forked from Telodendria/Telodendria
Abstract socket creation and binding behind the HttpServer API.
This commit is contained in:
parent
e94212b080
commit
d9c944871a
3 changed files with 46 additions and 53 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
Loading…
Reference in a new issue