1
0
mirror of https://git.sr.ht/~sircmpwn/gmnisrv synced 2024-06-08 17:30:43 +00:00

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.
This commit is contained in:
Drew DeVault 2020-11-01 10:30:35 -05:00
parent 36e53f1f7f
commit 16e55c6262
2 changed files with 16 additions and 12 deletions

View File

@ -84,9 +84,12 @@ Within each routing section, the following keys are used to configure how
*root* *root*
Configures the path on disk from which files shall be served for this 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 host. The path component of the URL will be appended to this value to
example.org/foo/bar.txt is requested and matches *[example.org:/foo]*, form the path to files on disk to serve.
"bar.txt" will be appended to the root to form the file path.
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* *index*
Configures the name of the index file which shall be served in the event Configures the name of the index file which shall be served in the event

View File

@ -198,8 +198,9 @@ serve_cgi(struct gmnisrv_client *client, const char *path,
} }
static bool 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) { switch (route->routing) {
case ROUTE_PATH:; case ROUTE_PATH:;
size_t l = strlen(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": // route == "/foo":
return false; return false;
} }
if (route->path[l-1] == '/') { *revised = strdup(path);
*revised = &path[l-1];
} else {
*revised = &path[l];
}
return true; return true;
case ROUTE_REGEX:; case ROUTE_REGEX:;
int ncapture = lre_get_capture_count(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); free(capture);
return false; return false;
} }
// TODO: Process captures and rewrites *revised = strdup(path);
*revised = path;
return true; return true;
} }
@ -246,7 +242,7 @@ serve_request(struct gmnisrv_client *client)
struct gmnisrv_route *route = host->routes; struct gmnisrv_route *route = host->routes;
assert(route); assert(route);
const char *url_path; char *url_path = NULL;
while (route) { while (route) {
if (route_match(route, client->path, &url_path)) { if (route_match(route, client->path, &url_path)) {
break; break;
@ -315,6 +311,7 @@ serve_request(struct gmnisrv_client *client)
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
if (route->autoindex) { if (route->autoindex) {
serve_autoindex(client, real_path); serve_autoindex(client, real_path);
free(url_path);
return; return;
} else { } else {
strncat(real_path, strncat(real_path,
@ -329,6 +326,7 @@ serve_request(struct gmnisrv_client *client)
client_submit_response(client, client_submit_response(client,
GEMINI_STATUS_NOT_FOUND, GEMINI_STATUS_NOT_FOUND,
"Not found", NULL); "Not found", NULL);
free(url_path);
return; return;
} }
ssize_t s = readlink(real_path, temp_path, sizeof(temp_path)); 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 // Don't serve special files
client_submit_response(client, client_submit_response(client,
GEMINI_STATUS_NOT_FOUND, "Not found", NULL); GEMINI_STATUS_NOT_FOUND, "Not found", NULL);
free(url_path);
return; return;
} }
} }
free(url_path);
if (route->cgi) { if (route->cgi) {
serve_cgi(client, real_path, serve_cgi(client, real_path,
(const char *)client_path, (const char *)client_path,