summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--cfws.c124
-rw-r--r--file.c47
-rw-r--r--file.h8
-rw-r--r--net.c81
-rw-r--r--net.h10
6 files changed, 148 insertions, 124 deletions
diff --git a/Makefile b/Makefile
index 3d4e5d7..3830dcb 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ LD=gcc
CFLAGS=-Wall -Wextra -pedantic -std=c89 -g
LDFLAGS=
-OBJS=cfws.o http.o
+OBJS=cfws.o file.o http.o net.o
DESTDIR=/usr/local/bin/
diff --git a/cfws.c b/cfws.c
index 63a6b19..0c96b99 100644
--- a/cfws.c
+++ b/cfws.c
@@ -1,30 +1,13 @@
-#include <arpa/inet.h>
-#include <errno.h>
-#include <linux/limits.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/stat.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. */
+#include "net.h"
#define CFWS_DEFAULT_PORT 8080
-size_t file_read(const char *, char **);
-
-int initialize_server(int);
-void handle_connection();
-
int main(int argc, char *argv[])
{
int port = CFWS_DEFAULT_PORT;
@@ -45,108 +28,3 @@ int main(int argc, char *argv[])
close(serverfd);
return 0;
}
-
-size_t file_read(const char *uri_path, char **buffer)
-{
- FILE *fp;
- struct stat statbuf;
- char path[PATH_MAX];
- long len;
-
- /* Prepend the current working directory to the uri path */
- getcwd(path, PATH_MAX);
- strncat(path, uri_path, PATH_MAX - 1);
-
- /* Append 'index.html' to directory paths. */
- stat(path, &statbuf);
- if (S_ISDIR(statbuf.st_mode))
- strcat(path, "index.html");
-
- fp = fopen(path, "rb");
- if (fp == NULL) {
- /*
- * File not found is a very common and harmless error, so
- * there's no need to print it out every time.
- */
- if (errno != ENOENT)
- perror("Failed to open file");
- return 0;
- }
-
- fseek(fp, 0, SEEK_END);
- len = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- *buffer = malloc(len);
- fread(*buffer, 1, len, fp);
-
- fclose(fp);
- return len;
-}
-
-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 *content_buf;
- size_t content_len, response_len;
-
- char resbuf[CFWS_MAX_RESPONSE];
- char readbuf[CFWS_MAXREAD];
- struct http_request req;
-
- memset(readbuf, 0, CFWS_MAXREAD);
- read(connfd, readbuf, CFWS_MAXREAD - 1);
-
- req = http_parse_request(readbuf);
-
- content_len = file_read(req.uri, &content_buf);
- if (content_len == 0) {
- const char *msg = "Could not find the specified file.";
- response_len = http_build_response(resbuf,
- HTTP_RESPONSE_NOTFOUND, msg, strlen(msg));
- } else {
- response_len = http_build_response(resbuf, HTTP_RESPONSE_OK,
- content_buf, content_len);
- free(content_buf);
- }
-
- write(connfd, resbuf, response_len);
- http_free_request(&req);
-}
diff --git a/file.c b/file.c
new file mode 100644
index 0000000..a8fef33
--- /dev/null
+++ b/file.c
@@ -0,0 +1,47 @@
+#include "file.h"
+
+#include <errno.h>
+#include <linux/limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+size_t file_read(const char *uri_path, char **buffer)
+{
+ FILE *fp;
+ struct stat statbuf;
+ char path[PATH_MAX];
+ long len;
+
+ /* Prepend the current working directory to the uri path */
+ getcwd(path, PATH_MAX);
+ strncat(path, uri_path, PATH_MAX - 1);
+
+ /* Append 'index.html' to directory paths. */
+ stat(path, &statbuf);
+ if (S_ISDIR(statbuf.st_mode))
+ strcat(path, "index.html");
+
+ fp = fopen(path, "rb");
+ if (fp == NULL) {
+ /*
+ * File not found is a very common and harmless error, so
+ * there's no need to print it out every time.
+ */
+ if (errno != ENOENT)
+ perror("Failed to open file");
+ return 0;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ *buffer = malloc(len);
+ fread(*buffer, 1, len, fp);
+
+ fclose(fp);
+ return len;
+}
diff --git a/file.h b/file.h
new file mode 100644
index 0000000..304cc75
--- /dev/null
+++ b/file.h
@@ -0,0 +1,8 @@
+#ifndef _H_FILE
+#define _H_FILE
+
+#include <stddef.h>
+
+size_t file_read(const char *, char **);
+
+#endif
diff --git a/net.c b/net.c
new file mode 100644
index 0000000..e13d664
--- /dev/null
+++ b/net.c
@@ -0,0 +1,81 @@
+#include "net.h"
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "file.h"
+#include "http.h"
+
+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 *content_buf;
+ size_t content_len, response_len;
+
+ char resbuf[CFWS_MAX_RESPONSE];
+ char readbuf[CFWS_MAXREAD];
+ struct http_request req;
+
+ memset(readbuf, 0, CFWS_MAXREAD);
+ read(connfd, readbuf, CFWS_MAXREAD - 1);
+
+ req = http_parse_request(readbuf);
+
+ content_len = file_read(req.uri, &content_buf);
+ if (content_len == 0) {
+ const char *msg = "Could not find the specified file.";
+ response_len = http_build_response(resbuf,
+ HTTP_RESPONSE_NOTFOUND, msg, strlen(msg));
+ } else {
+ response_len = http_build_response(resbuf, HTTP_RESPONSE_OK,
+ content_buf, content_len);
+ free(content_buf);
+ }
+
+ write(connfd, resbuf, response_len);
+ http_free_request(&req);
+}
diff --git a/net.h b/net.h
new file mode 100644
index 0000000..8b9e72a
--- /dev/null
+++ b/net.h
@@ -0,0 +1,10 @@
+#ifndef _H_NET
+#define _H_NET
+
+#define CFWS_MAXCONN 10 /* Max connections allowed by listen(). */
+#define CFWS_MAXREAD 1024 /* Size of buffer used for reading from client. */
+
+int initialize_server(int);
+void handle_connection(int);
+
+#endif