From 7da8be98eddd52dfda56a23cd08e15a250df14c4 Mon Sep 17 00:00:00 2001 From: "me@ow.nekobit.net" Date: Mon, 21 Feb 2022 01:44:59 +0000 Subject: [PATCH] Move POST requests to global FossilOrigin-Name: 26191fc8d8f5fb4085e55549a64521082ac3a6f3d5032d15661c088a7d294a57 --- src/cookie.c | 11 ++--- src/key.h | 28 +++++++++++ src/main.c | 25 +--------- src/page_config.c | 16 ++++--- src/query.c | 51 +++++++++++++++++++- src/query.h | 12 ++++- src/status.c | 115 ++++++++++++++++------------------------------ 7 files changed, 141 insertions(+), 117 deletions(-) create mode 100644 src/key.h diff --git a/src/cookie.c b/src/cookie.c index 64a9a00..b2ca288 100644 --- a/src/cookie.c +++ b/src/cookie.c @@ -18,8 +18,9 @@ #include #include -#include "cookie.h" #include +#include "cookie.h" +#include "key.h" enum cookie_state { @@ -29,12 +30,6 @@ enum cookie_state STATE_V_START, }; -struct cookie_value_refs -{ - char* key; - char** val; -}; - struct cookie_values cookies = { 0 }; char* read_cookies_env() @@ -56,7 +51,7 @@ char* read_cookies_env() char* cookies_read = cookies_str; // Will loop through these - struct cookie_value_refs refs[] = { + struct key_value_refs refs[] = { { "access_token", &(cookies.access_token) }, { "logged_in", &(cookies.logged_in) }, { "theme", &(cookies.theme) } diff --git a/src/key.h b/src/key.h new file mode 100644 index 0000000..356f682 --- /dev/null +++ b/src/key.h @@ -0,0 +1,28 @@ +/* + * 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 KEY_H +#define KEY_H + +struct key_value_refs +{ + char* key; + char** val; +}; + +#endif // KEY_H diff --git a/src/main.c b/src/main.c index e726275..8a2d1f6 100644 --- a/src/main.c +++ b/src/main.c @@ -29,29 +29,6 @@ #include "local_config.h" #include "cookie.h" -void load_auth_token(mastodont_t* api) -{ - struct http_cookie_info ck; - char* http_cookie = getenv("HTTP_COOKIE"); - - if (http_cookie) - { - char* cookie = malloc(strlen(http_cookie)); - if (!cookie) - { - perror("malloc"); - exit(1); - } - strcpy(cookie, http_cookie); - char* cookie_read = cookie; - if (cookie_get_val(cookie_read, "access_token", &ck) == 0) - { - mastodont_set_token(api, ck.val); - } - free(cookie); - } -} - int main(void) { // Content type is always HTML @@ -68,6 +45,7 @@ int main(void) // Load cookies char* cookies_str = read_cookies_env(); api.token = cookies.access_token; // Load token now + char* post_str = read_post_data(); // Config defaults g_config.theme = "ratfe20"; @@ -85,6 +63,7 @@ int main(void) // Cleanup if (cookies_str) free(cookies_str); + if (post_str) free(post_str); mastodont_free(&api); mastodont_global_curl_cleanup(); } diff --git a/src/page_config.c b/src/page_config.c index 3a74f6f..fea5cf3 100644 --- a/src/page_config.c +++ b/src/page_config.c @@ -37,8 +37,7 @@ static void config_post(struct http_query_info* info, void* args) if (strcmp(info->key, "theme") == 0) { g_config.theme = info->val; - printf("Set-Cookie: %s=%s; HttpOnly; SameSite=Strict;", - "theme", info->val); + g_config.changed = 1; } } @@ -47,8 +46,14 @@ void content_config(mastodont_t* api, char** data, size_t size) { char* post_query; (void)api; // No need to use this - - post_query = try_handle_post(config_post, NULL); + + if (post.theme) + { + g_config.theme = post.theme; + printf("Set-Cookie: %s=%s; HttpOnly; SameSite=Strict;", + "theme", post.theme); + g_config.changed = 1; + } struct base_page b = { .locale = L10N_EN_US, @@ -57,7 +62,4 @@ void content_config(mastodont_t* api, char** data, size_t size) }; render_base_page(&b); - - // Cleanup - if (post_query) free(post_query); } diff --git a/src/query.c b/src/query.c index d7aa022..5f2be61 100644 --- a/src/query.c +++ b/src/query.c @@ -21,6 +21,55 @@ #include #include #include "query.h" +#include "key.h" + +struct query_values post = { 0 }; + +char* read_post_data() +{ + struct http_query_info info; + char* request_method = getenv("REQUEST_METHOD"); + char* post_query = NULL, *p_query_read; + + // BEGIN Query references + struct key_value_refs refs[] = { + { "content", &(post.content) }, + { "itype", &(post.itype) }, + { "id", &(post.id) }, + { "theme", &(post.theme) } + }; + // END Query references + + if (request_method && (strcmp("POST", request_method) == 0)) + { + int content_length = atoi(getenv("CONTENT_LENGTH")); + post_query = malloc(content_length + 1); + if (!post_query) + { + perror("malloc"); + return NULL; + } + // Read in data + read(STDIN_FILENO, post_query, content_length); + post_query[content_length] = '\0'; + + // For shifting through + p_query_read = post_query; + + do + { + p_query_read = parse_query(p_query_read, &info); + if (!(info.key && info.val)) break; + for (size_t i = 0; i < (sizeof(refs)/sizeof(refs[0])); ++i) + if (strcmp(info.key, refs[i].key) == 0) + *(refs[i].val) = info.val; + } + while (p_query_read); + } + + // Free me afterwards! + return post_query; +} char* parse_query(char* begin, struct http_query_info* info) { @@ -39,8 +88,6 @@ char* parse_query(char* begin, struct http_query_info* info) if (*begin == '\0') end = 1; if (*begin == '&') *begin = '\0'; info->val = val_begin; - // The val length may be large, so strlen can waste time - info->val_len = (size_t)(begin - val_begin); return end ? NULL : begin+1; } diff --git a/src/query.h b/src/query.h index 68ca8df..a4e4ec1 100644 --- a/src/query.h +++ b/src/query.h @@ -24,9 +24,19 @@ struct http_query_info { char* key; char* val; - size_t val_len; // Val may be large, like CSS property }; +struct query_values +{ + char* theme; + char* content; + char* itype; + char* id; +}; + +extern struct query_values post; + +char* read_post_data(); /* A stupidly quick query parser */ char* parse_query(char* begin, struct http_query_info* info); char* try_handle_post(void (*call)(struct http_query_info*, void*), void* arg); diff --git a/src/status.c b/src/status.c index ea3b3ac..cdbc932 100644 --- a/src/status.c +++ b/src/status.c @@ -24,89 +24,52 @@ #include "cookie.h" #include "../static/status.chtml" -enum post_interact_type -{ - POST_INTERACT_NONE, - POST_INTERACT_LIKE, - POST_INTERACT_REBLOG -}; - -struct interact_args -{ - mastodont_t* api; - enum post_interact_type type; -}; - -static void status_interact(struct http_query_info* info, void* _arg) -{ - struct interact_args* arg = _arg; - - if (strcmp(info->key, "itype") == 0) - { - if (strcmp(info->val, "like") == 0) - { - arg->type = POST_INTERACT_LIKE; - } - } - else if (strcmp(info->key, "id") == 0) - { - struct mstdnt_storage storage; - switch (arg->type) - { - case POST_INTERACT_LIKE: - mastodont_favourite_status(arg->api, - info->val, - &storage); -// mastodont_storage_cleanup(&storage); - return; - default: - return; - } - } -} - -static void status_post(struct http_query_info* info, void* arg) -{ - mastodont_t* api = arg; - - if (strcmp(info->key, "content") == 0) - { - struct mstdnt_storage storage; - - // Cookie copy and read - struct mstdnt_create_status_args args = { - .content_type = "text/plain", - .expires_in = 0, - .in_reply_to_conversation_id = NULL, - .in_reply_to_id = NULL, - .language = NULL, - .media_ids = NULL, - .poll = NULL, - .preview = 0, - .scheduled_at = NULL, - .sensitive = 0, - .spoiler_text = NULL, - .status = info->val, - .visibility = "public", - }; - mastodont_create_status(api, &args, &storage); -// mastodont_storage_cleanup(&storage); - - } -} - int try_post_status(mastodont_t* api) { - char* post_query = try_handle_post(status_post, api); + if (!post.content) return 1; + + struct mstdnt_storage storage; + + // Cookie copy and read + struct mstdnt_create_status_args args = { + .content_type = "text/plain", + .expires_in = 0, + .in_reply_to_conversation_id = NULL, + .in_reply_to_id = NULL, + .language = NULL, + .media_ids = NULL, + .poll = NULL, + .preview = 0, + .scheduled_at = NULL, + .sensitive = 0, + .spoiler_text = NULL, + .status = post.content, + .visibility = "public", + }; + + mastodont_create_status(api, &args, &storage); + + // TODO cleanup when errors are properly implemented + // mastodont_storage_cleanup(&storage); + return 0; } int try_interact_status(mastodont_t* api) { - struct interact_args args; - args.api = api; - - char* post_query = try_handle_post(status_interact, &args); + struct mstdnt_storage storage; + if (!(post.itype && post.id)) return 1; + + // Pretty up the type + if (strcmp(post.itype, "like") == 0) + { + mastodont_favourite_status(api, + post.id, + &storage); + // TODO Cleanup when errors handled + // mastodont_storage_cleanup(&storage); + } + return 0; }