Start building support for running multiple HTTP servers.

The standard use case for this is going to be running a TLS and a non-TLS
HTTP server. I can't see a need for *more* than two, but it is theoretically
possible.

We shouldn't have to change anything with the database or anything; it
should suffice to simply spin up more HTTP servers, and they should
interact with each other the same way a single HTTP server with multiple
threads will.
This commit is contained in:
Jordan Bancino 2023-03-22 17:00:48 +00:00
parent e30fa3ee33
commit 413c7ad803

View file

@ -44,13 +44,25 @@
#include <Cron.h> #include <Cron.h>
#include <Uia.h> #include <Uia.h>
static HttpServer *httpServer = NULL; static Array *httpServers = NULL;
static void static void
TelodendriaSignalHandler(int signalNo) TelodendriaSignalHandler(int signalNo)
{ {
size_t i;
(void) signalNo; (void) signalNo;
HttpServerStop(httpServer);
if (!httpServers)
{
return;
}
for (i = 0; i < ArraySize(httpServers); i++)
{
HttpServer *server = ArrayGet(httpServers, i);
HttpServerStop(server);
}
} }
typedef enum ArgFlag typedef enum ArgFlag
@ -81,6 +93,10 @@ main(int argc, char **argv)
struct passwd *userInfo = NULL; struct passwd *userInfo = NULL;
struct group *groupInfo = NULL; struct group *groupInfo = NULL;
/* HTTP server management */
size_t i;
HttpServer *server;
/* Signal handling */ /* Signal handling */
struct sigaction sigAction; struct sigaction sigAction;
@ -269,10 +285,18 @@ main(int argc, char **argv)
/* Arguments to pass into the HTTP handler */ /* Arguments to pass into the HTTP handler */
matrixArgs.config = tConfig; matrixArgs.config = tConfig;
httpServers = ArrayCreate();
if (!httpServers)
{
Log(LOG_ERR, "Error setting up HTTP server.");
exit = EXIT_FAILURE;
goto finish;
}
/* Bind the socket before possibly dropping permissions */ /* Bind the socket before possibly dropping permissions */
httpServer = HttpServerCreate(HTTP_FLAG_NONE, tConfig->listenPort, tConfig->threads, server = HttpServerCreate(HTTP_FLAG_NONE, tConfig->listenPort, tConfig->threads,
tConfig->maxConnections, MatrixHttpHandler, &matrixArgs); tConfig->maxConnections, MatrixHttpHandler, &matrixArgs);
if (!httpServer) if (!server)
{ {
Log(LOG_ERR, "Unable to create HTTP server on port %d: %s", Log(LOG_ERR, "Unable to create HTTP server on port %d: %s",
tConfig->listenPort, strerror(errno)); tConfig->listenPort, strerror(errno));
@ -280,6 +304,8 @@ main(int argc, char **argv)
goto finish; goto finish;
} }
ArrayAdd(httpServers, server);
Log(LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid()); Log(LOG_DEBUG, "Running as uid:gid: %d:%d.", getuid(), getgid());
if (tConfig->uid && tConfig->gid) if (tConfig->uid && tConfig->gid)
@ -386,11 +412,20 @@ main(int argc, char **argv)
Log(LOG_NOTICE, "Starting server..."); Log(LOG_NOTICE, "Starting server...");
if (!HttpServerStart(httpServer)) for (i = 0; i < ArraySize(httpServers); i++)
{ {
Log(LOG_ERR, "Unable to start HTTP server."); server = ArrayGet(httpServers, i);
exit = EXIT_FAILURE;
goto finish; if (!HttpServerStart(server))
{
Log(LOG_ERR, "Unable to start HTTP server %lu.", i);
exit = EXIT_FAILURE;
goto finish;
}
else
{
Log(LOG_DEBUG, "Started HTTP server %lu.", i);
}
} }
Log(LOG_INFO, "Listening on port: %d", tConfig->listenPort); Log(LOG_INFO, "Listening on port: %d", tConfig->listenPort);
@ -406,16 +441,25 @@ main(int argc, char **argv)
goto finish; goto finish;
} }
/* Block this thread until the server is terminated by a signal /* Block this thread until the servers are terminated by a signal
* handler */ * handler */
HttpServerJoin(httpServer); for (i = 0; i < ArraySize(httpServers); i++)
{
server = ArrayGet(httpServers, i);
HttpServerJoin(server);
}
finish: finish:
Log(LOG_NOTICE, "Shutting down..."); Log(LOG_NOTICE, "Shutting down...");
if (httpServer) if (httpServers)
{ {
HttpServerFree(httpServer); for (i = 0; i < ArraySize(httpServers); i++)
Log(LOG_DEBUG, "Freed HTTP Server."); {
server = ArrayGet(httpServers, i);
HttpServerStop(server);
HttpServerFree(server);
}
ArrayFree(httpServers);
} }
if (cron) if (cron)