From 579697f138e3bdf94c40f48a90b55dfc3d12bdd3 Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Sun, 20 Apr 2025 21:21:54 +0200 Subject: [PATCH] Remove router code --- tinyhttp.c | 342 +---------------------------------------------------- tinyhttp.h | 15 --- 2 files changed, 1 insertion(+), 356 deletions(-) diff --git a/tinyhttp.c b/tinyhttp.c index 4a4117c..698b858 100644 --- a/tinyhttp.c +++ b/tinyhttp.c @@ -2603,344 +2603,4 @@ void tinyhttp_response_undo(TinyHTTPResponse res) return; // Invalid handle tinyhttp_stream_response_undo(stream); -} - -//////////////////////////////////////////////////////////////////////////////////// -// HTTP ROUTER // -//////////////////////////////////////////////////////////////////////////////////// -#if TINYHTTP_ROUTER_ENABLE - -#include -#include -#include -#include - -typedef struct { - char *ptr; - int len; -} string; - -#define S(X) ((string) {(X), sizeof(X)-1}) - -typedef enum { - ROUTE_STATIC_DIR, -} RouteType; - -typedef struct { - RouteType type; - string endpoint; - string path; - int dir_listing; -} Route; - -struct TinyHTTPRouter { - int num_routes; - int max_routes; - Route routes[]; -}; - -TinyHTTPRouter *tinyhttp_router_init(void) -{ - int max_routes = 32; - TinyHTTPRouter *router = malloc(max_routes * sizeof(TinyHTTPRouter)); - if (router == NULL) - return NULL; - router->max_routes = max_routes; - router->num_routes = 0; - return router; -} - -void tinyhttp_router_free(TinyHTTPRouter *router) -{ - free(router); -} - -void tinyhttp_router_dir(TinyHTTPRouter *router, string endpoint, string path, int dir_listing) -{ - if (router->num_routes == router->max_routes) - abort(); - Route *route = &router->routes[router->num_routes++]; - route->type = ROUTE_STATIC_DIR; - route->endpoint = endpoint; - route->path = path; - route->dir_listing = dir_listing; -} - -static int -valid_component_char(char c) -{ - return is_alpha(c) || is_digit(c) || c == '-' || c == '_' || c == '.'; // TODO -} - -static int -parse_path(string path, string *comps, int max_comps) -{ - // We treat relative and absolute paths the same - if (path.len > 0 && path.ptr[0] == '/') { - path.ptr++; - path.len--; - if (path.len == 0) - return 0; - } - - int num = 0; - int cur = 0; - for (;;) { - if (cur == path.len || !valid_component_char(path.ptr[cur])) - return -1; // Empty component - int start = cur; - do - cur++; - while (cur < path.len && valid_component_char(path.ptr[cur])); - string comp = { path.ptr + start, cur - start }; - - if (eqstr(comp, S(".."))) { - if (num == 0) - return -1; - num--; - } else if (!eqstr(comp, S("."))) { - if (num == max_comps) - return -1; - comps[num++] = comp; - } - - if (cur < path.len) { - if (path.ptr[cur] != '/') - return -1; - cur++; - } - - if (cur == path.len) - break; - } - - return num; -} - -static int swap_parents(string original_parent_path, string new_parent_path, string path, char *mem, int max) -{ - int num_original_parent_path_comps; - string original_parent_path_comps[TINYHTTP_ROUTER_MAX_PATH_COMPONENTS]; - - int num_new_parent_path_comps; - string new_parent_path_comps[TINYHTTP_ROUTER_MAX_PATH_COMPONENTS]; - - int num_path_comps; - string path_comps[TINYHTTP_ROUTER_MAX_PATH_COMPONENTS]; - - num_original_parent_path_comps = parse_path(original_parent_path, original_parent_path_comps, TINYHTTP_ROUTER_MAX_PATH_COMPONENTS); - num_new_parent_path_comps = parse_path(new_parent_path, new_parent_path_comps, TINYHTTP_ROUTER_MAX_PATH_COMPONENTS); - num_path_comps = parse_path(path, path_comps, TINYHTTP_ROUTER_MAX_PATH_COMPONENTS); - if (num_original_parent_path_comps < 0 || num_new_parent_path_comps < 0 || num_path_comps < 0) - return -1; - - int match = 1; - if (num_path_comps < num_original_parent_path_comps) - match = 0; - else { - for (int i = 0; i < num_original_parent_path_comps; i++) - if (!eqstr(original_parent_path_comps[i], path_comps[i])) { - match = 0; - break; - } - } - if (!match) - return 0; - - int num_result_comps = num_new_parent_path_comps + num_path_comps - num_original_parent_path_comps; - if (num_result_comps < 0 || num_result_comps > TINYHTTP_ROUTER_MAX_PATH_COMPONENTS) - return -1; - - string result_comps[TINYHTTP_ROUTER_MAX_PATH_COMPONENTS]; - for (int i = 0; i < num_new_parent_path_comps; i++) - result_comps[i] = new_parent_path_comps[i]; - - for (int i = 0; i < num_path_comps; i++) - result_comps[num_new_parent_path_comps + i] = path_comps[num_original_parent_path_comps + i]; - - int result_flat_len = 0; - for (int i = 0; i < num_result_comps; i++) - result_flat_len += result_comps[i].len + 1; - - if (result_flat_len >= max) - return -1; - int copied = 0; - for (int i = 0; i < num_result_comps; i++) { - if (i > 0) - mem[copied++] = '/'; - memcpy(mem + copied, result_comps[i].ptr, result_comps[i].len); - copied += result_comps[i].len; - } - - mem[copied] = '\0'; - return result_flat_len; -} - -static void -respond_with_regular_file(TinyHTTPServer *server, TinyHTTPResponse response, int fd, int file_size) -{ - http_response_write_status(server, response, 200); - - int cap; - void *dst = http_response_write_body_ptr(server, response, file_size, &cap); - if (dst) { - int copied = 0; - while (copied < file_size) { - int ret = read(fd, dst + copied, file_size - copied); - if (ret < 0) { - if (errno == EINTR) - continue; - http_response_undo(server, response); - http_response_write_status(server, response, 500); - http_response_send(server, response); - return; - } - if (ret == 0) - break; - copied += ret; - } - if (copied < file_size) { - http_response_undo(server, response); - http_response_write_status(server, response, 500); - http_response_send(server, response); - return; - } - } - http_response_write_body_ack(server, response, file_size); - http_response_send(server, response); -} - -static void -respond_with_dir_listing(TinyHTTPServer *server, TinyHTTPResponse response, DIR *dir) -{ - http_response_write_status(server, response, 200); - http_response_write_header(server, response, "Content-Type: text/html"); - http_response_write_body(server, response, S("
    ")); - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - string name = { entry->d_name, strlen(entry->d_name) }; // TODO: Check that d_name is always zero terminated - if (eqstr(name, S(".")) || eqstr(name, S(".."))) - continue; - int cap; - char *ptr = http_response_write_body_ptr(server, response, 128, &cap); - int len = snprintf(ptr, cap, "
  • %s
  • ", entry->d_name); // TODO: add link - if (len < 0 || len > cap) { - // TODO - } - http_response_write_body_ack(server, response, len); - } - http_response_write_body(server, response, S("
")); - http_response_send(server, response); -} - -static int -serve_static_dir(TinyHTTPServer *server, TinyHTTPResponse response, string base_endpoint, string base_path, string endpoint, int dir_listing) -{ - char mem[1<<12]; - int res = swap_parents(base_endpoint, base_path, endpoint, mem, sizeof(mem)); - if (res <= 0) - return res; - string path = {mem, res}; // Note that this is zero terminated - - int fd = open(path.ptr, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) - return 0; - http_response_write_status(server, response, 500); - http_response_send(server, response); - return 1; - } - - struct stat info; - if (fstat(fd, &info) < 0) { - http_response_write_status(server, response, 500); - http_response_send(server, response); - close(fd); - return 1; - } - - if (S_ISDIR(info.st_mode)) { - - int fd2 = openat(fd, "index.html", O_RDONLY); - if (fd2 < 0) { - if (errno != ENOENT) { - http_response_write_status(server, response, 500); - http_response_send(server, response); - close(fd); - return 1; - } - // Allow falling through - } else { - - struct stat info2; - if (fstat(fd2, &info2) < 0) { - http_response_write_status(server, response, 500); - http_response_send(server, response); - close(fd2); - close(fd); - return 1; - } - - respond_with_regular_file(server, response, fd2, info2.st_size); - - close(fd2); - close(fd); - return 1; - } - // Allow falling through - } - - if (S_ISDIR(info.st_mode)) { - - if (!dir_listing) { - close(fd); - return 0; - } - - DIR *dir = fdopendir(fd); - if (dir == NULL) { - http_response_write_status(server, response, 500); - http_response_send(server, response); - close(fd); - return 1; - } - - respond_with_dir_listing(server, response, dir); - closedir(dir); // This also closes fd - return 1; - } - - if (!S_ISREG(info.st_mode)) { - http_response_write_status(server, response, 500); - http_response_send(server, response); - close(fd); - return 1; - } - int file_size = info.st_size; - - respond_with_regular_file(server, response, fd, file_size); - close(fd); - return 1; -} - -void http_router_resolve(TinyHTTPRouter *router, TinyHTTPServer *server, TinyHTTPRequest *request, TinyHTTPResponse response) -{ - for (int i = 0; i < router->num_routes; i++) { - Route *route = &router->routes[i]; - switch (route->type) { - case ROUTE_STATIC_DIR: - if (1 == serve_static_dir(server, response, route->endpoint, route->path, request->path, route->dir_listing)) - return; - break; - - default: - http_response_write_status(server, response, 500); - http_response_send(server, response); - return; - } - } - http_response_write_status(server, response, 404); - http_response_send(server, response); -} - -#endif // TINYHTTP_ROUTER_ENABLE \ No newline at end of file +} \ No newline at end of file diff --git a/tinyhttp.h b/tinyhttp.h index 00637d1..8529510 100644 --- a/tinyhttp.h +++ b/tinyhttp.h @@ -31,9 +31,7 @@ #include "tinyhttp_config.h" #else #define TINYHTTP_SERVER_ENABLE 1 -#define TINYHTTP_ROUTER_ENABLE 0 #define TINYHTTP_HTTPS_ENABLE 0 -#define TINYHTTP_ROUTER_MAX_PATH_COMPONENTS 32 #define TINYHTTP_HEADER_LIMIT 32 #define TINYHTTP_SERVER_CONN_LIMIT (1<<10) #define TINYHTTP_SERVER_EPOLL_BATCH_SIZE (1<<10) @@ -46,7 +44,6 @@ // Opaque types typedef struct TinyHTTPServer TinyHTTPServer; -typedef struct TinyHTTPRouter TinyHTTPRouter; typedef struct { const char *ptr; @@ -346,15 +343,3 @@ void tinyhttp_response_send(TinyHTTPResponse res); // TODO: Comment void tinyhttp_response_undo(TinyHTTPResponse res); - -// TODO: Comment -TinyHTTPRouter *tinyhttp_router_init(void); - -// TODO: Comment -void tinyhttp_router_free(TinyHTTPRouter *router); - -// TODO: Comment -void tinyhttp_router_resolve(TinyHTTPRouter *router, TinyHTTPServer *server, TinyHTTPRequest *request, TinyHTTPResponse response); - -// TODO: Comment -void tinyhttp_router_dir(TinyHTTPRouter *router, const char *endpoint, const char *path, int dir_listing);