From 8dbeb095f12c8a4c3b5d7ebf8162cfda844552a8 Mon Sep 17 00:00:00 2001 From: "me@ow.nekobit.net" Date: Thu, 10 Feb 2022 20:32:18 +0000 Subject: [PATCH] Pretty path parsing Introduces a new path parser that uses the : token to represent a variable. It isn't fully featured but is just capable enough to work for ratFE FossilOrigin-Name: f7646dd5278f3c509d96307e45dc216522f81d9b93eb6b17125dc1b1892b1eee --- Makefile | 2 +- src/account.c | 23 +++++------ src/account.h | 3 +- src/index.c | 21 ++++++---- src/main.c | 4 +- src/page_config.c | 15 +++++--- src/page_config.h | 3 +- src/path.c | 95 ++++++++++++++++++++++++++++++++++++++++++---- src/path.h | 3 +- src/uri.c | 17 --------- src/uri.h | 25 ------------ static/config.html | 2 +- 12 files changed, 132 insertions(+), 81 deletions(-) delete mode 100644 src/uri.c delete mode 100644 src/uri.h diff --git a/Makefile b/Makefile index 9844c06..8c8f950 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC ?= cc GIT ?= git MASTODONT_DIR = mastodont-c/ MASTODONT = $(MASTODONT_DIR)libmastodont.a -CFLAGS = -Wall -I $(MASTODONT_DIR)include/ +CFLAGS += -Wall -I $(MASTODONT_DIR)include/ LDFLAGS = -L$(MASTODONT_DIR) -lcurl -lmastodont -lcjson SRC = $(wildcard src/*.c) OBJ = $(patsubst %.c,%.o,$(SRC)) diff --git a/src/account.c b/src/account.c index fe9246e..a72a0ad 100644 --- a/src/account.c +++ b/src/account.c @@ -22,7 +22,6 @@ #include "../config.h" #include "account.h" #include "easprintf.h" -#include "uri.h" // Files #include "../static/index.chtml" @@ -51,25 +50,23 @@ char* construct_account_page(struct mstdnt_account* acct, size_t* res_size) return result; } -void content_account(mastodont_t* api) +void content_account(mastodont_t* api, char** data, size_t size) { + int cleanup = 0; char* account_page; struct mstdnt_account acct; struct mstdnt_storage storage; - char uri[MSTDNT_URISIZE]; - if (parse_uri(uri, MSTDNT_URISIZE, getenv("PATH_INFO")+2)) - { - return; - } - if (mastodont_account(api, MSTDNT_LOOKUP_ACCT, uri, + if (mastodont_account(api, MSTDNT_LOOKUP_ACCT, data[0], &acct, &storage, NULL)) - account_page = "An error occured"; + account_page = "Couldn't load account info"; else + { + cleanup = 1; account_page = construct_account_page(&acct, NULL); - - if (!account_page) - account_page = "Malloc error"; + if (!account_page) + account_page = "Malloc error"; + } struct base_page b = { .locale = L10N_EN_US, @@ -82,5 +79,5 @@ void content_account(mastodont_t* api) /* Cleanup */ mastodont_storage_cleanup(&storage); - free(account_page); + if (cleanup) free(account_page); } diff --git a/src/account.h b/src/account.h index e9c2972..a477f55 100644 --- a/src/account.h +++ b/src/account.h @@ -18,9 +18,10 @@ #ifndef ACCOUNT_H #define ACCOUNT_H +#include #include char* construct_account_page(struct mstdnt_account* acct, size_t* res_size); -void content_account(mastodont_t* api); +void content_account(mastodont_t* api, char** data, size_t data_size); #endif // ACCOUNT_H diff --git a/src/index.c b/src/index.c index 33675d4..64f7729 100644 --- a/src/index.c +++ b/src/index.c @@ -28,16 +28,23 @@ void content_index(mastodont_t* api) { + int cleanup = 0; size_t status_count, statuses_html_count; struct mstdnt_status* statuses; struct mstdnt_storage storage; char* status_format; - mastodont_timeline_public(api, NULL, &storage, &statuses, &status_count); - - /* Construct statuses into HTML */ - status_format = construct_statuses(statuses, status_count, &statuses_html_count); - if (status_format == NULL) - status_format = "Error in malloc!"; + if (mastodont_timeline_public(api, NULL, &storage, &statuses, &status_count)) + { + status_format = "An error occured loading the timeline"; + } + else + { + /* Construct statuses into HTML */ + status_format = construct_statuses(statuses, status_count, &statuses_html_count); + if (status_format == NULL) + status_format = "Error in malloc!"; + cleanup = 1; + } struct base_page b = { .locale = L10N_EN_US, @@ -50,5 +57,5 @@ void content_index(mastodont_t* api) /* Cleanup */ mastodont_storage_cleanup(&storage); - free(status_format); + if (cleanup) free(status_format); } diff --git a/src/main.c b/src/main.c index 5ad6cc5..0059101 100644 --- a/src/main.c +++ b/src/main.c @@ -23,6 +23,7 @@ #include "index.h" #include "page_config.h" #include "path.h" +#include "account.h" int main(void) { @@ -41,7 +42,8 @@ int main(void) * Path handling * ******************/ struct path_info paths[] = { - { "/config", content_config } + { "/config", content_config }, + { "/@:", content_account }, }; handle_paths(&api, paths, sizeof(paths)/sizeof(paths[0])); diff --git a/src/page_config.c b/src/page_config.c index dc25aa9..d120098 100644 --- a/src/page_config.c +++ b/src/page_config.c @@ -20,6 +20,7 @@ #include #include #include +#include "base_page.h" #include "../config.h" #include "page_config.h" #include "query.h" @@ -28,17 +29,13 @@ #include "../static/index.chtml" #include "../static/config.chtml" -void content_config(mastodont_t* api) +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; struct http_query_info info; - // Output - printf("Content-Length: %ld\r\n\r\n", - data_index_html_size + data_config_html_size); - // Handle POST if (request_method && (strcmp("POST", request_method) == 0)) @@ -71,5 +68,13 @@ void content_config(mastodont_t* api) free(post_query); } + struct base_page b = { + .locale = L10N_EN_US, + .content = data_config_html, + .sidebar_right = NULL + }; + + render_base_page(&b); + printf(data_index_html, config_canonical_name, data_config_html); } diff --git a/src/page_config.h b/src/page_config.h index e6fd70f..684b746 100644 --- a/src/page_config.h +++ b/src/page_config.h @@ -18,8 +18,9 @@ #ifndef PAGE_CONFIG_H #define PAGE_CONFIG_H +#include #include -void content_config(mastodont_t* api); +void content_config(mastodont_t* api, char** data, size_t data_size); #endif // PAGE_CONFIG_H diff --git a/src/path.c b/src/path.c index dceaf2b..69b8f9f 100644 --- a/src/path.c +++ b/src/path.c @@ -22,6 +22,91 @@ #include "index.h" #include "account.h" +enum path_state +{ + PARSE_NEUTRAL, + PARSE_READ, +}; + +void parse_path(mastodont_t* api, struct path_info* path_info) +{ + int fail = 0, fin = 0; + enum path_state state = PARSE_NEUTRAL; + char* p = path_info->path + 1; + char* p2 = getenv("PATH_INFO") + 1; + + // Stored into data + int str_size = 0; + char* tmp = NULL; + char** data = NULL; + size_t size = 0; + + for (int i = 0, j = 0;;) + { + switch (p[j]) + { + case '\0': + fin = 1; + // fall + case '/': + if (state == PARSE_READ) + { + state = PARSE_NEUTRAL; + + // Set value and move on + data = realloc(data, ++size * sizeof(tmp)); + data[size-1] = tmp; + tmp = NULL; + str_size = 0; + } + + if (fin) goto breakpt; + break; + case ':': + state = PARSE_READ; + // fall + default: + if (state == PARSE_NEUTRAL) + { + if (p[j] == p2[i]) + break; + else { + fail = 1; + goto breakpt; + } + } + else { + // Don't realloc, we already have a space for our final character + if (p2[i] == '\0') + { + tmp[str_size] = '\0'; + ++j; + } + tmp = realloc(tmp, ++str_size + 1); + tmp[str_size-1] = p2[i]; + } + + + break; + } + + if (state == PARSE_NEUTRAL) ++j; // Used for p + ++i; // Used for p2 + } +breakpt: + if (fail) + return; + + path_info->callback(api, data, size); + + // Cleanup + for (size_t i = 0; i < size; ++i) + { + free(data[i]); + } + if (data) free(data); +} + void handle_paths(mastodont_t* api, struct path_info* paths, size_t paths_len) { char* path = getenv("PATH_INFO"); @@ -30,16 +115,10 @@ void handle_paths(mastodont_t* api, struct path_info* paths, size_t paths_len) { content_index(api); } - else if (path[1] == '@') - { // Account path - content_account(api); - } - else - { // Generic path + else { // Generic path for (size_t i = 0; i < paths_len; ++i) { - if (strcmp(path, paths[i].path) == 0) - paths[i].callback(api); + parse_path(api, paths + i); } } } diff --git a/src/path.h b/src/path.h index 5d35fea..2fdd0ff 100644 --- a/src/path.h +++ b/src/path.h @@ -24,9 +24,10 @@ struct path_info { char* path; - void (*callback)(mastodont_t*); + void (*callback)(mastodont_t*, char**, size_t); }; void handle_paths(mastodont_t* api, struct path_info* paths, size_t paths_len); +void parse_path(mastodont_t* api, struct path_info* path_info); #endif // PATH_H diff --git a/src/uri.c b/src/uri.c deleted file mode 100644 index 3487660..0000000 --- a/src/uri.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include "uri.h" - -int parse_uri(char* dest, size_t dest_max_n, char* src) -{ - strncpy(dest, src, dest_max_n); - char* delim = strchr(dest, '/'); - int xp = delim != NULL; /* Expression */ - if (xp || dest[strlen(dest)] == '\0') - { - /* Incase the second expression didn't match, check xp again */ - if (xp) *delim = '\0'; - return 0; - } - - return 1; -} diff --git a/src/uri.h b/src/uri.h deleted file mode 100644 index 63847f2..0000000 --- a/src/uri.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 URI_H -#define URI_H -#include - -int parse_uri(char* dest, size_t dest_max_n, char* src); - -#endif // URI_H diff --git a/static/config.html b/static/config.html index 9ba836b..f746c5f 100644 --- a/static/config.html +++ b/static/config.html @@ -1,5 +1,5 @@
-
+

General

JavaScript