From 90e5ac72595eaafb57941410319f9c7961dee6ce Mon Sep 17 00:00:00 2001 From: "me@ow.nekobit.net" Date: Sat, 12 Feb 2022 02:20:29 +0000 Subject: [PATCH] Parse cookies FossilOrigin-Name: a70c1b3c96720d7db399598e81e2cb87d1baae3f676926c511fa5b4f714c3555 --- dist/{ratfe.css => ratfe20.css} | 0 src/base_page.c | 20 +++++++++ src/base_page.h | 1 + src/cookie.c | 74 +++++++++++++++++++++++++++++++++ src/cookie.h | 11 +++++ src/local_config.h | 29 +++++++++++++ src/main.c | 4 ++ src/page_config.c | 25 ++++++----- static/index.html | 3 +- 9 files changed, 155 insertions(+), 12 deletions(-) rename dist/{ratfe.css => ratfe20.css} (100%) create mode 100644 src/cookie.c create mode 100644 src/local_config.h diff --git a/dist/ratfe.css b/dist/ratfe20.css similarity index 100% rename from dist/ratfe.css rename to dist/ratfe20.css diff --git a/src/base_page.c b/src/base_page.c index 372f793..1009958 100644 --- a/src/base_page.c +++ b/src/base_page.c @@ -20,17 +20,37 @@ #include #include "base_page.h" #include "easprintf.h" +#include "cookie.h" + // Files #include "../static/index.chtml" void render_base_page(struct base_page* page) { + char* cookie = getenv("HTTP_COOKIE"); enum l10n_locale locale = page->locale; + char* cookie_read = cookie; + struct http_cookie_info info = { 0 }; + + /*while (1) + { + cookie_read = parse_cookies(cookie_read, &info); + + if (!(info.key && info.val)) break; + if (strcmp(info.key, "theme") == 0) + { + g_config.theme = info.val; + } + + if (!cookie_read) break; + }*/ char* data; int len = easprintf(&data, data_index_html, L10N[locale][L10N_APP_NAME], + g_config.theme, + g_config.theme, L10N[locale][L10N_APP_NAME], L10N[locale][L10N_SEARCH_PLACEHOLDER], L10N[locale][L10N_SEARCH_BUTTON], diff --git a/src/base_page.h b/src/base_page.h index 7b1a2d8..7520dc9 100644 --- a/src/base_page.h +++ b/src/base_page.h @@ -19,6 +19,7 @@ #ifndef BASE_PAGE_H #define BASE_PAGE_H #include "l10n.h" +#include "local_config.h" struct base_page { diff --git a/src/cookie.c b/src/cookie.c new file mode 100644 index 0000000..1eff638 --- /dev/null +++ b/src/cookie.c @@ -0,0 +1,74 @@ +/* + * RatFE - Lightweight frontend for Pleroma + * Copyright (C) 2022 Nekobit + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include "cookie.h" + +enum cookie_state +{ + STATE_C_NEUTRAL, + STATE_C_STARTSP, + STATE_K_START, + STATE_V_START, +}; + +char* parse_cookies(char* begin, struct http_cookie_info* info) +{ + int keydone = 0; + enum cookie_state state = STATE_C_STARTSP; + int end = 0; + size_t val_s = 0; + + for (; *begin != ';' && *begin != '\0'; ++begin) + { + switch (*begin) + { + case '=': + if (state == STATE_K_START) keydone = 1; + state = STATE_C_STARTSP; + *begin = '\0'; // Null ptr + break; + case ' ': + // longkeyval = res; + // ^ ^ + if (state == STATE_C_STARTSP || + state == STATE_K_START) + break; + // fall + default: + if (state == STATE_C_STARTSP) + { + if (keydone) info->val = begin; + else info->key = begin; + state = keydone ? STATE_V_START : STATE_K_START; + } + if (keydone) ++val_s; + } + } + + // Which character did we stop at? + if (*begin == '\0') + end = 1; + else if (*begin == ';') + *begin = '\0'; + + // The val length may be large, so strlen can waste time + info->val_len = val_s; + + return end ? NULL : begin+1; +} diff --git a/src/cookie.h b/src/cookie.h index b4960a6..db651a6 100644 --- a/src/cookie.h +++ b/src/cookie.h @@ -18,5 +18,16 @@ #ifndef COOKIE_H #define COOKIE_H +#include + +struct http_cookie_info +{ + char* key; + char* val; + size_t val_len; // Val may be large, like CSS property +}; + +// Stupidly fast simple cookie parser +char* parse_cookies(char* begin, struct http_cookie_info* info); #endif // COOKIE_H diff --git a/src/local_config.h b/src/local_config.h new file mode 100644 index 0000000..860eae8 --- /dev/null +++ b/src/local_config.h @@ -0,0 +1,29 @@ +/* + * RatFE - Lightweight frontend for Pleroma + * Copyright (C) 2022 Nekobit + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef LOCAL_CONFIG_H +#define LOCAL_CONFIG_H + +struct local_config +{ + char* theme; +}; + +static struct local_config g_config; + +#endif // LOCAL_CONFIG_H diff --git a/src/main.c b/src/main.c index 0059101..3cd2b66 100644 --- a/src/main.c +++ b/src/main.c @@ -24,6 +24,7 @@ #include "page_config.h" #include "path.h" #include "account.h" +#include "local_config.h" int main(void) { @@ -38,6 +39,9 @@ int main(void) api.url = config_instance_url; mastodont_init(&api); + // Config defaults + g_config.theme = "ratfe20"; + /******************* * Path handling * ******************/ diff --git a/src/page_config.c b/src/page_config.c index d120098..1688464 100644 --- a/src/page_config.c +++ b/src/page_config.c @@ -24,6 +24,8 @@ #include "../config.h" #include "page_config.h" #include "query.h" +#include "cookie.h" +#include "local_config.h" // Pages #include "../static/index.chtml" @@ -33,9 +35,8 @@ void content_config(mastodont_t* api, char** data, size_t size) { (void)api; // No need to use this char* request_method = getenv("REQUEST_METHOD"); - char* post_query, * p_query_read; + char* post_query = NULL, * p_query_read; struct http_query_info info; - // Handle POST if (request_method && (strcmp("POST", request_method) == 0)) @@ -57,15 +58,16 @@ void content_config(mastodont_t* api, char** data, size_t size) while (1) { p_query_read = parse_query(p_query_read, &info); - - printf("%.*s,", (int)info.val_len, info.val); + if (!(info.key && info.val)) break; + if (strcmp(info.key, "theme") == 0) + { + g_config.theme = info.val; + printf("Set-Cookie: %s=%s; HttpOnly; SameSite=Strict;", + "theme", info.val); + } - if (p_query_read == NULL) - break; + if (!p_query_read) break; } - - // Cleanup - free(post_query); } struct base_page b = { @@ -75,6 +77,7 @@ void content_config(mastodont_t* api, char** data, size_t size) }; render_base_page(&b); - - printf(data_index_html, config_canonical_name, data_config_html); + + // Cleanup + if (post_query) free(post_query); } diff --git a/static/index.html b/static/index.html index 3ef22bc..a6600b8 100644 --- a/static/index.html +++ b/static/index.html @@ -4,10 +4,11 @@ %s - + + %s