summaryrefslogtreecommitdiff
path: root/cfws.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfws.c')
-rw-r--r--cfws.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/cfws.c b/cfws.c
new file mode 100644
index 0000000..bc9d0fa
--- /dev/null
+++ b/cfws.c
@@ -0,0 +1,102 @@
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "http.h"
+
+#define CFWS_MAXCONN 10 /* Max connections allowed by listen(). */
+#define CFWS_MAXREAD 1024 /* Size of buffer used for reading from client. */
+
+#define CFWS_DEFAULT_PORT 8080
+
+int initialize_server(int);
+void handle_connection();
+
+int main(int argc, char *argv[])
+{
+ int port = CFWS_DEFAULT_PORT;
+ int serverfd, clientfd;
+
+ serverfd = initialize_server(port);
+ if (serverfd == -1)
+ return 1;
+
+ printf("Serving a directory at localhost:%d\n", port);
+
+ while (1) {
+ clientfd = accept(serverfd, NULL, NULL);
+ handle_connection(clientfd);
+ close(clientfd);
+ }
+
+ close(serverfd);
+ return 0;
+}
+
+int initialize_server(int port)
+{
+ struct sockaddr_in addr;
+ int rc;
+ int sockopts = 1;
+ int sockfd;
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd == -1) {
+ perror("Failed to create server socket");
+ return -1;
+ }
+
+ /* Allow the port to be reused, prevents errors when quickly starting
+ * and restarting the server. */
+ /* TODO: Also use SO_REUSEPORT? */
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopts, sizeof(int));
+
+ memset(&addr, 0, sizeof(struct sockaddr_in));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+
+ rc = bind(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr));
+ if (rc == -1) {
+ perror("Failed to bind server socket");
+ return -1;
+ }
+
+ rc = listen(sockfd, CFWS_MAXCONN);
+ if (rc == -1) {
+ perror("Failed to listen on server socket");
+ return -1;
+ }
+
+ return sockfd;
+}
+
+void handle_connection(int connfd)
+{
+ char msgbuf[128];
+ char *resbuf;
+ char readbuf[CFWS_MAXREAD];
+ struct http_request req;
+
+ memset(readbuf, 0, CFWS_MAXREAD);
+ read(connfd, readbuf, CFWS_MAXREAD - 1);
+
+ req = http_parse_request(readbuf);
+
+ snprintf(msgbuf, 128, "Welcome to %s", req.uri);
+
+ http_build_response(&resbuf, HTTP_RESPONSE_OK, msgbuf);
+ write(connfd, resbuf, strlen(resbuf));
+
+ free(resbuf);
+ http_free_request(&req);
+}
+