From 16e55c62623ef33db5e143126582d93c44ea950e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 1 Nov 2020 10:30:35 -0500 Subject: [PATCH] Change meaning of root (backwards incompatible!) This takes the nginx approach to the "root" directive, which is simpler to implement and more consistent with more complex routing behaviors like regexp. The path component of the URL is now simply appended to the root to form the path to the file which should be served to the client. --- doc/gmnisrvini.scd | 9 ++++++--- src/serve.c | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/doc/gmnisrvini.scd b/doc/gmnisrvini.scd index 554458a..00fbce3 100644 --- a/doc/gmnisrvini.scd +++ b/doc/gmnisrvini.scd @@ -84,9 +84,12 @@ Within each routing section, the following keys are used to configure how *root* Configures the path on disk from which files shall be served for this - host. If using path prefix matching, the prefix is trimmed, so if - example.org/foo/bar.txt is requested and matches *[example.org:/foo]*, - "bar.txt" will be appended to the root to form the file path. + host. The path component of the URL will be appended to this value to + form the path to files on disk to serve. + + If example.org/foo/bar.txt is requested, and a route is configured for + *[example.org:/foo]* with the root set to /srv/gemini, + /srv/gemini/foo/bar.txt will be served. *index* Configures the name of the index file which shall be served in the event diff --git a/src/serve.c b/src/serve.c index 9d0bcf3..6d9d87d 100644 --- a/src/serve.c +++ b/src/serve.c @@ -198,8 +198,9 @@ serve_cgi(struct gmnisrv_client *client, const char *path, } static bool -route_match(struct gmnisrv_route *route, const char *path, const char **revised) +route_match(struct gmnisrv_route *route, const char *path, char **revised) { + free(*revised); switch (route->routing) { case ROUTE_PATH:; size_t l = strlen(route->path); @@ -211,11 +212,7 @@ route_match(struct gmnisrv_route *route, const char *path, const char **revised) // route == "/foo": return false; } - if (route->path[l-1] == '/') { - *revised = &path[l-1]; - } else { - *revised = &path[l]; - } + *revised = strdup(path); return true; case ROUTE_REGEX:; int ncapture = lre_get_capture_count(route->regex); @@ -230,8 +227,7 @@ route_match(struct gmnisrv_route *route, const char *path, const char **revised) free(capture); return false; } - // TODO: Process captures and rewrites - *revised = path; + *revised = strdup(path); return true; } @@ -246,7 +242,7 @@ serve_request(struct gmnisrv_client *client) struct gmnisrv_route *route = host->routes; assert(route); - const char *url_path; + char *url_path = NULL; while (route) { if (route_match(route, client->path, &url_path)) { break; @@ -315,6 +311,7 @@ serve_request(struct gmnisrv_client *client) if (S_ISDIR(st.st_mode)) { if (route->autoindex) { serve_autoindex(client, real_path); + free(url_path); return; } else { strncat(real_path, @@ -329,6 +326,7 @@ serve_request(struct gmnisrv_client *client) client_submit_response(client, GEMINI_STATUS_NOT_FOUND, "Not found", NULL); + free(url_path); return; } ssize_t s = readlink(real_path, temp_path, sizeof(temp_path)); @@ -340,10 +338,13 @@ serve_request(struct gmnisrv_client *client) // Don't serve special files client_submit_response(client, GEMINI_STATUS_NOT_FOUND, "Not found", NULL); + free(url_path); return; } } + free(url_path); + if (route->cgi) { serve_cgi(client, real_path, (const char *)client_path,