Abstract socket creation and binding behind the HttpServer API.

This commit is contained in:
Jordan Bancino 2022-08-11 20:13:10 -04:00
parent e94212b080
commit d9c944871a
3 changed files with 46 additions and 53 deletions

View file

@ -26,6 +26,11 @@
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct HttpServer struct HttpServer
{ {
@ -41,16 +46,43 @@ struct HttpServer
}; };
HttpServer * HttpServer *
HttpServerCreate(int socketDesc, unsigned int nThreads, HttpHandler * requestHandler, void *handlerArgs) HttpServerCreate(unsigned short port, unsigned int nThreads, HttpHandler * requestHandler, void *handlerArgs)
{ {
HttpServer *server = malloc(sizeof(HttpServer)); HttpServer *server = malloc(sizeof(HttpServer));
struct sockaddr_in sa = {0};
if (!server) if (!server)
{ {
return NULL; return NULL;
} }
server->sd = socketDesc; server->sd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if (server->sd < 0)
{
free(server);
return NULL;
}
sa.sin_family = AF_INET;
sa.sin_port = port;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server->sd, (struct sockaddr *) & sa, sizeof(sa)) < 0)
{
close(server->sd);
free(server);
return NULL;
}
/* TODO: Make this a user-tunable parameter? */
if (listen(server->sd, 32) < 0)
{
close(server->sd);
free(server);
return NULL;
}
server->nThreads = nThreads; server->nThreads = nThreads;
server->requestHandler = requestHandler; server->requestHandler = requestHandler;
server->handlerArgs = handlerArgs; server->handlerArgs = handlerArgs;
@ -63,11 +95,15 @@ HttpServerCreate(int socketDesc, unsigned int nThreads, HttpHandler * requestHan
void void
HttpServerFree(HttpServer * server) HttpServerFree(HttpServer * server)
{ {
if (!server)
{
return;
}
close(server->sd);
free(server); free(server);
} }
#include <stdio.h>
static void * static void *
HttpServerEventThread(void *args) HttpServerEventThread(void *args)
{ {

View file

@ -31,10 +31,6 @@
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <TelodendriaConfig.h> #include <TelodendriaConfig.h>
#include <Log.h> #include <Log.h>
#include <HashMap.h> #include <HashMap.h>
@ -93,31 +89,6 @@ TelodendriaPrintUsage(LogConfig * lc)
Log(lc, LOG_MESSAGE, " -h Print this usage, then exit."); Log(lc, LOG_MESSAGE, " -h Print this usage, then exit.");
} }
static int
TelodendriaBindSocket(unsigned short port)
{
struct sockaddr_in remote = {0};
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
/* Unable to create the socket */
return -1;
}
remote.sin_family = AF_INET;
remote.sin_port = port;
remote.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *) & remote, sizeof(remote)) < 0)
{
/* Unable to bind the socket */
return -1;
}
return s;
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -141,9 +112,6 @@ main(int argc, char **argv)
struct passwd *userInfo; struct passwd *userInfo;
struct group *groupInfo; struct group *groupInfo;
/* Networking */
int httpSocket = -1;
/* Signal handling */ /* Signal handling */
struct sigaction sigAction; struct sigaction sigAction;
@ -327,10 +295,11 @@ main(int argc, char **argv)
} }
/* Bind the socket before possibly dropping permissions */ /* Bind the socket before possibly dropping permissions */
httpSocket = TelodendriaBindSocket(tConfig->listenPort); httpServer = HttpServerCreate(tConfig->listenPort, tConfig->threads, TelodendriaHttpHandler, NULL);
if (httpSocket < 0) if (!httpServer)
{ {
Log(lc, LOG_ERROR, "Unable to bind to port %d: %s", strerror(errno)); Log(lc, LOG_ERROR, "Unable to create HTTP server on port %d: %s",
tConfig->listenPort, strerror(errno));
exit = EXIT_FAILURE; exit = EXIT_FAILURE;
goto finish; goto finish;
} }
@ -385,14 +354,6 @@ main(int argc, char **argv)
Log(lc, LOG_TASK, "Starting server..."); Log(lc, LOG_TASK, "Starting server...");
httpServer = HttpServerCreate(httpSocket, tConfig->threads, TelodendriaHttpHandler, NULL);
if (!httpServer)
{
Log(lc, LOG_ERROR, "Unable to create HTTP server.");
exit = EXIT_FAILURE;
goto finish;
}
if (!HttpServerStart(httpServer)) if (!HttpServerStart(httpServer))
{ {
Log(lc, LOG_ERROR, "Unable to start HTTP server."); Log(lc, LOG_ERROR, "Unable to start HTTP server.");
@ -400,7 +361,7 @@ main(int argc, char **argv)
goto finish; goto finish;
} }
Log(lc, LOG_MESSAGE, "Ready."); Log(lc, LOG_MESSAGE, "Listening on port: %d", tConfig->listenPort);
sigAction.sa_handler = TelodendriaSignalHandler; sigAction.sa_handler = TelodendriaSignalHandler;
sigfillset(&sigAction.sa_mask); sigfillset(&sigAction.sa_mask);
@ -419,10 +380,6 @@ main(int argc, char **argv)
finish: finish:
Log(lc, LOG_TASK, "Shutting down..."); Log(lc, LOG_TASK, "Shutting down...");
if (httpSocket > 0)
{
close(httpSocket);
}
if (httpServer) if (httpServer)
{ {
HttpServerFree(httpServer); HttpServerFree(httpServer);

View file

@ -31,7 +31,7 @@ typedef struct HttpServer HttpServer;
typedef void (HttpHandler) (HttpRequest *, HttpResponse *, void *); typedef void (HttpHandler) (HttpRequest *, HttpResponse *, void *);
extern HttpServer * extern HttpServer *
HttpServerCreate(int, unsigned int, HttpHandler *, void *); HttpServerCreate(unsigned short, unsigned int, HttpHandler *, void *);
extern void extern void
HttpServerFree(HttpServer *); HttpServerFree(HttpServer *);