/* * Treebird - 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 #include #include #include "query.h" #include "key.h" struct query_values post = { 0 }; char* read_post_data() { struct http_query_info info; char* post_env = getenv("POST"); 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) }, { "username", &(post.username) }, { "password", &(post.password) }, { "replyid", &(post.replyid) }, }; // END Query references if ((request_method && (strcmp("POST", request_method) == 0)) || post_env) { int content_length = post_env ? strlen(post_env) : atoi(getenv("CONTENT_LENGTH")); post_query = malloc(content_length + 1); if (!post_query) { perror("malloc"); return NULL; } if (post_env) strcpy(post_query, post_env); else { // 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) { int end = 0; char* val_begin; info->key = begin; for (; *begin != '&' && *begin != '\0'; ++begin) { if (*begin == '=') { val_begin = begin+1; *begin = '\0'; } } if (*begin == '\0') end = 1; if (*begin == '&') *begin = '\0'; info->val = val_begin; return end ? NULL : begin+1; } char* try_handle_post(void (*call)(struct http_query_info*, void*), void* arg) { char* request_method = getenv("REQUEST_METHOD"); char* post_query = NULL, * p_query_read; struct http_query_info info; // Handle POST if (request_method && (strcmp("POST", request_method) == 0)) { int content_length = atoi(getenv("CONTENT_LENGTH")); post_query = malloc(content_length + 1); if (!post_query) { puts("Malloc error!"); return NULL; } read(STDIN_FILENO, post_query, content_length); post_query[content_length] = '\0'; // For parse_query to shift through, so we can still free the original p_query_read = post_query; // Parse while (1) { p_query_read = parse_query(p_query_read, &info); if (!(info.key && info.val)) break; call(&info, arg); if (!p_query_read) break; } } return post_query; }