forked from aniani/gmnisrv
1
0
Fork 0

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*
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

View File

@ -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,