aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--beaker.h1
-rw-r--r--src/routing.c62
2 files changed, 35 insertions, 28 deletions
diff --git a/beaker.h b/beaker.h
index d19d4c6..634795f 100644
--- a/beaker.h
+++ b/beaker.h
@@ -95,6 +95,7 @@ void set_handler(const char *path, RequestHandler handler);
char *parse_request_url(const char *request_buffer, UrlParams *params);
const char *get_mime_type(const char *file_path);
bool serve_static_file(const char *request_path_relative_to_static);
+bool serve_static_file_with_mime(const char *request_path_relative_to_static, const char *mime_type);
int beaker_run(const char *ip, int port);
diff --git a/src/routing.c b/src/routing.c
index 89c6c2c..b411c0c 100644
--- a/src/routing.c
+++ b/src/routing.c
@@ -223,7 +223,7 @@ char *parse_request_url(const char *request_line, UrlParams *params) {
}
free(path_check);
}
-
+
if (query_start) {
char *query_string = query_start + 1;
@@ -253,17 +253,16 @@ char *parse_request_url(const char *request_line, UrlParams *params) {
return final_path;
}
-bool serve_static_file(const char *request_path_relative_to_static) {
- char full_static_path[MAX_PATH_LEN];
+bool serve_static_file_with_mime(const char *request_path_relative_to_static, const char *mime_type) {
+ char full_static_path[MAX_PATH_LEN];
if (strstr(request_path_relative_to_static, "..") != NULL) {
fprintf(stderr, "[SECURITY] Attempted directory traversal: %s\n",
request_path_relative_to_static);
-
const char *forbidden_response =
"HTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\n\r\n";
send(current_client_socket, forbidden_response, strlen(forbidden_response), 0);
- return true;
+ return true;
}
snprintf(full_static_path, sizeof(full_static_path), "%s%s", STATIC_DIR,
@@ -272,57 +271,64 @@ bool serve_static_file(const char *request_path_relative_to_static) {
FILE *fp = fopen(full_static_path, "rb");
if (fp == NULL) {
fprintf(stderr,
- "[ERROR] serve_static_file: File '%s' not found or could not be opened. %s\n",
- full_static_path, strerror(errno));
- return false;
+ "[ERROR] serve_static_file_with_mime: File '%s' not found or could not be opened. %s\n",
+ full_static_path, strerror(errno));
+ return false;
}
- struct stat st;
+ struct stat st;
if (fstat(fileno(fp), &st) < 0) {
perror("fstat error");
- fprintf(stderr, "[ERROR] serve_static_file: fstat failed for '%s'.\n",
+ fprintf(stderr, "[ERROR] serve_static_file_with_mime: fstat failed for '%s'.\n",
full_static_path);
- fclose(fp);
-
+ fclose(fp);
const char *server_error_response =
"HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n";
send(current_client_socket, server_error_response, strlen(server_error_response), 0);
- return true;
+ return true;
}
- long file_size = st.st_size;
- const char *mime_type = get_mime_type(full_static_path);
+ long file_size = st.st_size;
+
+ if (!mime_type || mime_type[0] == '\0') {
+ mime_type = get_mime_type(full_static_path);
+ }
- char http_header[BUFFER_SIZE];
+ char http_header[BUFFER_SIZE];
snprintf(http_header, sizeof(http_header),
"HTTP/1.1 200 OK\r\n"
- "Content-Type: %s\r\n"
- "Content-Length: %ld\r\n"
- "Connection: close\r\n"
- "\r\n",
+ "Content-Type: %s\r\n"
+ "Content-Length: %ld\r\n"
+ "Connection: close\r\n"
+ "\r\n",
mime_type, file_size);
if (send(current_client_socket, http_header, strlen(http_header), 0) < 0) {
perror("Error sending static file header");
- fprintf(stderr, "[ERROR] serve_static_file: Failed to send header for '%s'.\n", full_static_path);
+ fprintf(stderr, "[ERROR] serve_static_file_with_mime: Failed to send header for '%s'.\n",
+ full_static_path);
fclose(fp);
- return true;
+ return true;
}
- char file_buffer[BUFFER_SIZE];
- size_t bytes_read;
+ char file_buffer[BUFFER_SIZE];
+ size_t bytes_read;
while ((bytes_read = fread(file_buffer, 1, sizeof(file_buffer), fp)) > 0) {
if (send(current_client_socket, file_buffer, bytes_read, 0) < 0) {
perror("Error sending static file content");
- fprintf(stderr, "[ERROR] serve_static_file: Failed to send content for '%s'.\n", full_static_path);
- break;
+ fprintf(stderr, "[ERROR] serve_static_file_with_mime: Failed to send content for '%s'.\n",
+ full_static_path);
+ break;
}
}
- fclose(fp);
- return true;
+ fclose(fp);
+ return true;
}
+bool serve_static_file(const char *request_path_relative_to_static) {
+ return serve_static_file_with_mime(request_path_relative_to_static, NULL);
+} \ No newline at end of file