Move POST requests to global

FossilOrigin-Name: 26191fc8d8f5fb4085e55549a64521082ac3a6f3d5032d15661c088a7d294a57
This commit is contained in:
me@ow.nekobit.net 2022-02-21 01:44:59 +00:00
parent 4877ef15ae
commit 7da8be98ed
7 changed files with 141 additions and 117 deletions

View file

@ -18,8 +18,9 @@
#include <string.h>
#include <stdio.h>
#include "cookie.h"
#include <stdlib.h>
#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) }

28
src/key.h Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
*/
#ifndef KEY_H
#define KEY_H
struct key_value_refs
{
char* key;
char** val;
};
#endif // KEY_H

View file

@ -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();
}

View file

@ -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);
}

View file

@ -21,6 +21,55 @@
#include <stdio.h>
#include <unistd.h>
#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;
}

View file

@ -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);

View file

@ -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;
}