From e0f7c133d1cc2ae6e55c3bcd8adb95d75c9ad2cd Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Tue, 17 Jan 2023 20:29:16 +0000 Subject: [PATCH] Add a non-JSON landing page. This is the basis for other HTML pages. --- TODO.txt | 4 +- src/Matrix.c | 37 +++++++++----- src/Routes/RouteMainPage.c | 91 +++++++++++++++++++++++++++++++++ src/Telodendria.c | 101 +++++++++++++++++-------------------- src/include/Routes.h | 1 + src/include/Telodendria.h | 39 ++++++++++++++ 6 files changed, 203 insertions(+), 70 deletions(-) create mode 100644 src/Routes/RouteMainPage.c create mode 100644 src/include/Telodendria.h diff --git a/TODO.txt b/TODO.txt index bd008c1..27bfe59 100644 --- a/TODO.txt +++ b/TODO.txt @@ -18,8 +18,8 @@ Milestone: v0.2.0 [ ] Logout [ ] Logout all [ ] Login fallback (static HTML page) -[ ] Non-JSON endpoints - [ ] Home page (like Synapse's "it works!") +[x] Non-JSON endpoints + [x] Home page (like Synapse's "it works!") [ ] Content repository [x] Document MemoryHexDump() diff --git a/src/Matrix.c b/src/Matrix.c index 701e8a1..46e2fd9 100644 --- a/src/Matrix.c +++ b/src/Matrix.c @@ -40,7 +40,7 @@ MatrixHttpHandler(HttpServerContext * context, void *argp) MatrixHttpHandlerArgs *args = (MatrixHttpHandlerArgs *) argp; LogConfig *lc = args->lc; FILE *stream; - HashMap *response; + HashMap *response = NULL; char *key; @@ -60,7 +60,6 @@ MatrixHttpHandler(HttpServerContext * context, void *argp) HttpResponseStatus(context, HTTP_OK); HttpResponseHeader(context, "Server", "Telodendria/" TELODENDRIA_VERSION); - HttpResponseHeader(context, "Content-Type", "application/json"); /* CORS */ HttpResponseHeader(context, "Access-Control-Allow-Origin", "*"); @@ -101,7 +100,11 @@ MatrixHttpHandler(HttpServerContext * context, void *argp) pathPart = MATRIX_PATH_POP(pathParts); - if (MATRIX_PATH_EQUALS(pathPart, ".well-known")) + if (!pathPart) + { + response = RouteMainPage(&routeArgs); + } + else if (MATRIX_PATH_EQUALS(pathPart, ".well-known")) { response = RouteWellKnown(&routeArgs); } @@ -117,19 +120,26 @@ MatrixHttpHandler(HttpServerContext * context, void *argp) Free(pathPart); - if (!response) + /* + * If the route handler returned a JSON object, take care + * of sending it here. + * + * Otherwise, if the route handler returned NULL, so assume + * that it sent its own headers and and body. + */ + if (response) { - Log(lc, LOG_ERR, "The route handler returned NULL: %s", requestPath); - HttpResponseStatus(context, HTTP_INTERNAL_SERVER_ERROR); - response = MatrixErrorCreate(M_UNKNOWN); + HttpResponseHeader(context, "Content-Type", "application/json"); + HttpSendHeaders(context); + + stream = HttpStream(context); + + JsonEncode(response, stream); + JsonFree(response); + + fprintf(stream, "\n"); } - HttpSendHeaders(context); - - stream = HttpStream(context); - JsonEncode(response, stream); - fprintf(stream, "\n"); - /* * By this point, there should be no path parts remaining, but if * there are, free them up now. @@ -140,7 +150,6 @@ MatrixHttpHandler(HttpServerContext * context, void *argp) } MATRIX_PATH_FREE(pathParts); - JsonFree(response); finish: LogConfigUnindent(lc); diff --git a/src/Routes/RouteMainPage.c b/src/Routes/RouteMainPage.c new file mode 100644 index 0000000..df14443 --- /dev/null +++ b/src/Routes/RouteMainPage.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include + +#include + +ROUTE_IMPL(RouteMainPage, args) +{ + FILE *stream = HttpStream(args->context); + size_t i; + + HttpResponseHeader(args->context, "Content-Type", "text/html"); + HttpSendHeaders(args->context); + + fprintf(stream, + "" + "" + "" + "" + "" + "It Works! | Telodendria" + "" + "" + "" + "
"
+            );
+
+    for (i = 0; i < TELODENDRIA_LOGO_HEIGHT; i++)
+    {
+        fprintf(stream, "%s\n", TelodendriaLogo[i]);
+    }
+
+    fprintf(stream,
+            "
" + "

It works! Telodendria is running

" + "

" + "Your Telodendria server is listening on this port and is ready " + "for messages." + "

" + "

" + "To use this server, you'll need " + "a Matrix client." + "

" + "

" + "Welcome to the Matrix universe :)" + "

" + ); + + fprintf(stream, + "" + "" + ); + + return NULL; +} diff --git a/src/Telodendria.c b/src/Telodendria.c index 53d96a0..a6fb660 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,42 @@ #include #include +const char + TelodendriaLogo[TELODENDRIA_LOGO_HEIGHT][TELODENDRIA_LOGO_WIDTH] = { + " .= -=- ", + " :.:+ .=:. ", + " .=+-==. :. ", + " .+- =. ", + " .+ :+. ", + " ==. -+: ", + " =++==--:: =+. ", + " .:::--=+=: :+= ", + " :==. -=: ", + " ===----=-. ... :+. ", + " :==+=======: .-+-::-+-=+=", + " .==*%#======= :+- .. ", + " .:--=-===+=========-. :+: ", + " .=++=::..:============-+=-=- ", + ":+=: :=+-: .-=========-. . ", + " =+++: .:=+-: .:--. .--:==: ", + " ::---:.. :=+: == ", + " ++. .+- ", + " =+ .+- ...: ", + " +- -+-:-+=::+: ", + " :=-....:-=: .--: =- ", + " -++=:.:::.. " +}; + +const char + TelodendriaHeader[TELODENDRIA_HEADER_HEIGHT][TELODENDRIA_HEADER_WIDTH] = { + "=======================================================", + "|_ _|__| | ___ __| | ___ _ __ __| |_ __(_) __ _ ", + " | |/ _ \\ |/ _ \\ / _` |/ _ \\ '_ \\ / _` | '__| |/ _` | ", + " | | __/ | (_) | (_| | __/ | | | (_| | | | | (_| | ", + " |_|\\___|_|\\___/ \\__,_|\\___|_| |_|\\__,_|_| |_|\\__,_| ", + "=======================================================" +}; + static void TelodendriaMemoryHook(MemoryAction a, MemoryInfo * i, void *args) { @@ -125,62 +162,18 @@ typedef enum ArgFlag static void TelodendriaPrintHeader(LogConfig * lc) { - Log(lc, LOG_INFO, - " .= -=-"); - Log(lc, LOG_INFO, - " :.:+ .=:."); - Log(lc, LOG_INFO, - " .=+-==. :."); - Log(lc, LOG_INFO, - " .+- =."); - Log(lc, LOG_INFO, - " .+ :+."); - Log(lc, LOG_INFO, - " ==. -+:"); - Log(lc, LOG_INFO, - " =++==--:: =+."); - Log(lc, LOG_INFO, - " .:::--=+=: :+="); - Log(lc, LOG_INFO, - " :==. -=:"); - Log(lc, LOG_INFO, - " ===----=-. ... :+."); - Log(lc, LOG_INFO, - " :==+=======: .-+-::-+-=+="); - Log(lc, LOG_INFO, - " .==*%#======= :+- .."); - Log(lc, LOG_INFO, - " .:--=-===+=========-. :+:"); - Log(lc, LOG_INFO, - " .=++=::..:============-+=-=-"); - Log(lc, LOG_INFO, - ":+=: :=+-: .-=========-. ."); - Log(lc, LOG_INFO, - " =+++: .:=+-: .:--. .--:==:"); - Log(lc, LOG_INFO, - " ::---:.. :=+: =="); - Log(lc, LOG_INFO, - " ++. .+-"); - Log(lc, LOG_INFO, - " =+ .+- ...:"); - Log(lc, LOG_INFO, - " +- -+-:-+=::+:"); - Log(lc, LOG_INFO, - " :=-....:-=: .--: =-"); - Log(lc, LOG_INFO, - " -++=:.:::.."); + size_t i; + for (i = 0; i < TELODENDRIA_LOGO_HEIGHT; i++) + { + Log(lc, LOG_INFO, "%s", TelodendriaLogo[i]); + } + + for (i = 0; i < TELODENDRIA_HEADER_HEIGHT; i++) + { + Log(lc, LOG_INFO, "%s", TelodendriaHeader[i]); + } - Log(lc, LOG_INFO, - " _____ _ _ _ _"); - Log(lc, LOG_INFO, - "|_ _|__| | ___ __| | ___ _ __ __| |_ __(_) __ _"); - Log(lc, LOG_INFO, - " | |/ _ \\ |/ _ \\ / _` |/ _ \\ '_ \\ / _` | '__| |/ _` |"); - Log(lc, LOG_INFO, - " | | __/ | (_) | (_| | __/ | | | (_| | | | | (_| |"); - Log(lc, LOG_INFO, - " |_|\\___|_|\\___/ \\__,_|\\___|_| |_|\\__,_|_| |_|\\__,_|"); Log(lc, LOG_INFO, "Telodendria v" TELODENDRIA_VERSION); Log(lc, LOG_INFO, ""); Log(lc, LOG_INFO, diff --git a/src/include/Routes.h b/src/include/Routes.h index 6131564..05ecbcc 100644 --- a/src/include/Routes.h +++ b/src/include/Routes.h @@ -57,6 +57,7 @@ typedef struct RouteArgs HashMap * \ name(RouteArgs * argsName) +ROUTE(RouteMainPage); /* / */ ROUTE(RouteWellKnown); /* /.well-known */ ROUTE(RouteMatrix); /* /_matrix */ ROUTE(RouteLogin); /* /_matrix/client/(r0|v3)/login */ diff --git a/src/include/Telodendria.h b/src/include/Telodendria.h new file mode 100644 index 0000000..84cd0aa --- /dev/null +++ b/src/include/Telodendria.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef TELODENDRIA_H +#define TELODENDRIA_H + +#define TELODENDRIA_LOGO_WIDTH 56 +#define TELODENDRIA_LOGO_HEIGHT 22 + +extern const char + TelodendriaLogo[TELODENDRIA_LOGO_HEIGHT][TELODENDRIA_LOGO_WIDTH]; + +#define TELODENDRIA_HEADER_WIDTH 56 +#define TELODENDRIA_HEADER_HEIGHT 6 + +extern const char + TelodendriaHeader[TELODENDRIA_HEADER_HEIGHT][TELODENDRIA_HEADER_WIDTH]; + +#endif