summaryrefslogtreecommitdiff
path: root/cfws.c
diff options
context:
space:
mode:
authorcflip <cflip@cflip.net>2023-05-27 11:50:37 -0600
committercflip <cflip@cflip.net>2023-05-27 11:50:37 -0600
commit30458088f0f6acbb9581fecd2aa39d97c13d7373 (patch)
tree71ee8fc561a3ee3be1e674cdb9db1c3a600080f6 /cfws.c
parent7f1d6bbc335288df1e24e7c8f305c32afe6b050a (diff)
Load and serve files from the filesystem
Diffstat (limited to 'cfws.c')
-rw-r--r--cfws.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/cfws.c b/cfws.c
index bc9d0fa..63a6b19 100644
--- a/cfws.c
+++ b/cfws.c
@@ -1,4 +1,6 @@
#include <arpa/inet.h>
+#include <errno.h>
+#include <linux/limits.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
@@ -6,6 +8,7 @@
#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>
@@ -17,6 +20,8 @@
#define CFWS_DEFAULT_PORT 8080
+size_t file_read(const char *, char **);
+
int initialize_server(int);
void handle_connection();
@@ -41,6 +46,44 @@ int main(int argc, char *argv[])
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;
@@ -81,8 +124,10 @@ int initialize_server(int port)
void handle_connection(int connfd)
{
- char msgbuf[128];
- char *resbuf;
+ char *content_buf;
+ size_t content_len, response_len;
+
+ char resbuf[CFWS_MAX_RESPONSE];
char readbuf[CFWS_MAXREAD];
struct http_request req;
@@ -91,12 +136,17 @@ void handle_connection(int connfd)
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));
+ 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);
+ }
- free(resbuf);
+ write(connfd, resbuf, response_len);
http_free_request(&req);
}
-