From 47c98cbbe3587d1553afaa3f4cd772ff6da0bae4 Mon Sep 17 00:00:00 2001 From: LDA Date: Wed, 12 Jun 2024 23:27:36 +0200 Subject: [PATCH] [ADD/WIP] Routerwerk! --- Makefile | 2 +- src/HttParsee.c | 52 +++++++++++++++++++++++++++++++++ src/Main.c | 28 ++++++++++++++++++ src/ParseeConfig.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ src/ParseeData.c | 35 ++++++++++++++++++++++ src/Routes/Root.c | 30 +++++++++++++++++++ src/include/Parsee.h | 45 +++++++++++++++++++++++++++++ src/include/Routes.h | 20 +++++++++++++ 8 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 src/HttParsee.c create mode 100644 src/ParseeConfig.c create mode 100644 src/ParseeData.c create mode 100644 src/Routes/Root.c create mode 100644 src/include/Parsee.h create mode 100644 src/include/Routes.h diff --git a/Makefile b/Makefile index 716491b..0a324b2 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ CYTO_LIB=/usr/local/lib # Where's Cytoplasm's library is SOURCE=src OBJECT=build -INCLUDES=include +INCLUDES=src/include CC=cc CFLAGS=-I$(INCLUDES) -I$(CYTO_INC) -DNAME="\"$(NAME)\"" -DVERSION="\"$(VERSION)\"" -g -ggdb LDFLAGS=-L $(CYTO_LIB) -lCytoplasm -Wl,--export-dynamic diff --git a/src/HttParsee.c b/src/HttParsee.c new file mode 100644 index 0000000..f3dc3d7 --- /dev/null +++ b/src/HttParsee.c @@ -0,0 +1,52 @@ +#include + +#include +#include +#include +#include + +#include + +void +ParseeRequest(HttpServerContext *ctx, void *argp) +{ + ParseeData *data = argp; + char *path = HttpRequestPath(ctx); + HashMap *response = NULL; + Stream *stream = HttpServerStream(ctx); + int encodedSize; + char *encodedStr; + ParseeHttpArg arg; + + /* Basic headers */ + HttpResponseStatus(ctx, HTTP_OK); + HttpResponseHeader(ctx, "Server", NAME "/v" VERSION); + HttpResponseHeader(ctx, "Connection", "close"); + + arg.data = data; + arg.ctx = ctx ; + + arg.stream = stream; + + if (!HttpRouterRoute(data->router, path, &arg, (void **) &response)) + { + HttpResponseStatus(ctx, HTTP_NOT_FOUND); + JsonFree(response); + response = NULL; + /* TODO: Set a thing */ + } + + /* Whatever, we routed a thing. */ + if (response) + { + encodedSize = JsonEncode(response, NULL, JSON_DEFAULT); + encodedStr = StrInt(encodedSize); + HttpResponseHeader(ctx, "Content-Length", encodedStr); + HttpResponseHeader(ctx, "Content-Type", "application/json"); + Free(encodedStr); + + HttpSendHeaders(ctx); + JsonEncode(response, stream, JSON_DEFAULT); + return; + } +} diff --git a/src/Main.c b/src/Main.c index 5c4a6ae..f2c7e8b 100644 --- a/src/Main.c +++ b/src/Main.c @@ -1,9 +1,37 @@ +#include #include +#include + +#include + int Main(void) { + HttpServer *server = NULL; + HttpServerConfig conf; + ParseeData *data; + const ParseeConfig *parseeConf; + Log(LOG_INFO, "%s - v%s", NAME, VERSION); + ParseeConfigInit(); + ParseeExportConfigYAML(StreamStdout()); + + parseeConf = ParseeConfigGet(); + + memset(&conf, 0, sizeof(conf)); + conf.port = parseeConf->port; + conf.threads = 4; + conf.maxConnections = 32; + conf.handlerArgs = ParseeInitData(); + conf.handler = ParseeRequest; + /* TODO: The rest of Parsee. */ + server = HttpServerCreate(&conf); + HttpServerStart(server); + HttpServerJoin(server); + + HttpServerFree(server); + ParseeConfigFree(); return 0; } diff --git a/src/ParseeConfig.c b/src/ParseeConfig.c new file mode 100644 index 0000000..78cedd3 --- /dev/null +++ b/src/ParseeConfig.c @@ -0,0 +1,69 @@ +#include + +#include +#include + +static ParseeConfig *config = NULL; + +void +ParseeConfigInit(void) +{ + if (config) + { + return; + } + config = Malloc(sizeof(*config)); + config->as_token = StrRandom(32); + config->hs_token = StrRandom(32); + config->sender_localpart = StrDuplicate("_parsee_bridge"); + config->namespace_base = StrDuplicate("_parsee_j"); + config->listen_as = StrDuplicate("localhost"); + config->port = 7642; /* proposed by Saint */ +} + +void +ParseeExportConfigYAML(Stream *stream) +{ + if (!stream || !config) + { + return; + } + StreamPrintf(stream, "# Autogenerated YAML AS entry for %s\n", NAME); + StreamPrintf(stream, "# This file should be *moved* to your\n"); + StreamPrintf(stream, "# Matrix homeserver's config directory\n"); + StreamPrintf(stream, "# (as for Conduit, y'all really need a better system)\n"); + StreamPrintf(stream, "\n"); + StreamPrintf(stream, "id: \"Parsee XMPP\"\n"); + StreamPrintf(stream, "url: \"http://%s:%d/\"\n", config->listen_as, config->port); + StreamPrintf(stream, "as_token: \"%s\"\n", config->as_token); + StreamPrintf(stream, "hs_token: \"%s\"\n", config->hs_token); + StreamPrintf(stream, "sender_localpart: \"%s\"\n", config->sender_localpart); + StreamPrintf(stream, "\n"); + StreamPrintf(stream, "namespaces: \n"); + StreamPrintf(stream, " users:\n"); + StreamPrintf(stream, " - exclusive: true\n"); + StreamPrintf(stream, " regex: \"@%s_.*\n", config->namespace_base); + StreamPrintf(stream, " aliases:\n"); + StreamPrintf(stream, " - exclusive: true\n"); + StreamPrintf(stream, " regex: \"#%s_.*\n", config->namespace_base); +} + +void +ParseeConfigFree(void) +{ + if (!config) + { + return; + } + Free(config->as_token); + Free(config->hs_token); + Free(config->sender_localpart); + Free(config->namespace_base); + Free(config->listen_as); + Free(config); +} +const ParseeConfig * +ParseeConfigGet(void) +{ + return (const ParseeConfig *) config; +} diff --git a/src/ParseeData.c b/src/ParseeData.c new file mode 100644 index 0000000..34b73f9 --- /dev/null +++ b/src/ParseeData.c @@ -0,0 +1,35 @@ +#include + +#include + +#include + +ParseeData * +ParseeInitData(void) +{ + ParseeData *data; + if (!ParseeConfigGet()) + { + return NULL; + } + + data = Malloc(sizeof(*data)); + data->config = ParseeConfigGet(); + data->router = HttpRouterCreate(); + +#define X_ROUTE(path, func) HttpRouterAdd(data->router, path, func); + ROUTES +#undef X_ROUTE + return data; +} +void +ParseeFreeData(ParseeData *data) +{ + if (!data) + { + return; + } + + HttpRouterFree(data->router); + Free(data); +} diff --git a/src/Routes/Root.c b/src/Routes/Root.c new file mode 100644 index 0000000..1d47bdf --- /dev/null +++ b/src/Routes/Root.c @@ -0,0 +1,30 @@ +#include + +RouteHead(RouteRoot, arr, argp) +{ + ParseeHttpArg *args = argp; + + HttpResponseHeader(args->ctx, "Content-Type", "text/html"); + HttpSendHeaders(args->ctx); + StreamPrintf(args->stream, ""); + StreamPrintf(args->stream, " "); + StreamPrintf(args->stream, " Parsee Lander"); + StreamPrintf(args->stream, " "); + StreamPrintf(args->stream, " "); + StreamPrintf(args->stream, "

"); + StreamPrintf(args->stream, " Your Parsee is running!"); + StreamPrintf(args->stream, "

"); + StreamPrintf(args->stream, "
"); + StreamPrintf(args->stream, "

"); + StreamPrintf(args->stream, " Kinda jealous of that, to be "); + StreamPrintf(args->stream, " fair."); + StreamPrintf(args->stream, "

"); + StreamPrintf(args->stream, "

"); + StreamPrintf(args->stream, " Your homeserver now can interact"); + StreamPrintf(args->stream, " with the bridge, with the "); + StreamPrintf(args->stream, " generated YAML file."); + StreamPrintf(args->stream, "

"); + StreamPrintf(args->stream, " "); + StreamPrintf(args->stream, ""); + return NULL; +} diff --git a/src/include/Parsee.h b/src/include/Parsee.h new file mode 100644 index 0000000..e6bbce9 --- /dev/null +++ b/src/include/Parsee.h @@ -0,0 +1,45 @@ +#ifndef PARSEE_PARSEE_H +#define PARSEE_PARSEE_H + +#include +#include +#include + +typedef struct ParseeConfig { + char *as_token, *hs_token; + /* id here is "Parsee XMPP". */ + char *sender_localpart; + char *namespace_base; + + char *listen_as; + int port; +} ParseeConfig; + +typedef struct ParseeData { + const ParseeConfig *config; + HttpRouter *router; +} ParseeData; + +/* Initialises a Parsee config from scratch, and writes to it + * as JSON in the CWD. */ +extern void ParseeConfigInit(void); + +/* Loads a Parsee config from a JSON filepath. */ +extern void ParseeConfigLoad(char *); + +/* Retrieves the Parsee config if loaded. */ +extern const ParseeConfig * ParseeConfigGet(void); + +/* Exports the Parsee config as a YAML document. */ +extern void ParseeExportConfigYAML(Stream *); + +/* Destroys the Parsee configuration */ +extern void ParseeConfigFree(void); + +/* Creates and destroys a data structure, stored on the heap. */ +extern ParseeData * ParseeInitData(void); +extern void ParseeFreeData(ParseeData *); + +/* HTTP server handler for Parsee, takes in a config. */ +extern void ParseeRequest(HttpServerContext *, void *); +#endif diff --git a/src/include/Routes.h b/src/include/Routes.h new file mode 100644 index 0000000..b325db4 --- /dev/null +++ b/src/include/Routes.h @@ -0,0 +1,20 @@ +#ifndef PARSEE_ROUTES_H +#define PARSEE_ROUTES_H + +#include +typedef struct ParseeHttpArg { + ParseeData *data; + HttpServerContext *ctx; + Stream *stream; +} ParseeHttpArg; + +/* A list of all routes. */ +#define ROUTES X_ROUTE("/", RouteRoot) + +#define X_ROUTE(path, name) extern void * name(Array *, void *); + ROUTES +#undef X_ROUTE + +#define RouteHead(name, pathargs, argp) void * \ + name(Array * pathargs, void *argp) +#endif