diff options
author | Omar Polo <op@omarpolo.com> | 2021-01-30 12:04:20 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2021-01-30 12:04:20 +0000 |
commit | 6016a593a32c4f3f27ed3e7892a1595d631fcbef (patch) | |
tree | efbf517aa47a564c87138c55e09404bc17d909d8 | |
parent | 601bc1cc3797c8afc6610478cab9004be7a2c7b0 (diff) |
invert the location precedence: first match wins
It's how httpd(8) does it, and it allows us to call fnmatch less time
-rw-r--r-- | gmid.1 | 10 | ||||
-rw-r--r-- | gmid.h | 4 | ||||
-rw-r--r-- | server.c | 31 |
3 files changed, 27 insertions, 18 deletions
@@ -223,15 +223,15 @@ The .Pa path argument will be matched against the request path with shell globbing rules. -In case of multiple location statements in the same context, the last -matching location will be put into effect. -Therefore is advisable to match for a generic paths first and for more -specific ones later on. +In case of multiple location statements in the same context, the first +matching location will be put into effect and the later ones ignored. +Therefore is advisable to match for more specific paths first and for +generic ones later on. A .Ic location section may include most of the server configuration rules except -.Ic cert , Ic key , Ic root , Ic location No and Ic CGI . +.Ic cert , Ic key , Ic root , Ic location No and Ic cgi . .El .Sh CGI When CGI scripts are enabled for a directory, a request for an @@ -76,6 +76,10 @@ struct vhost { const char *dir; const char *cgi; int dirfd; + + /* the first location rule is always '*' and holds the default + * settings for the vhost, from locations[1] onwards there are + * the "real" location rules specified in the configuration. */ struct location locations[LOCLEN]; }; @@ -33,19 +33,18 @@ const char * vhost_lang(struct vhost *v, const char *path) { struct location *loc; - const char *lang = NULL; if (v == NULL || path == NULL) - return lang; + return NULL; - for (loc = v->locations; loc->match != NULL; ++loc) { + for (loc = &v->locations[1]; loc->match != NULL; ++loc) { if (!fnmatch(loc->match, path, 0)) { if (loc->lang != NULL) - lang = loc->lang; + return loc->lang; } } - return lang; + return v->locations[0].lang; } const char * @@ -57,13 +56,15 @@ vhost_default_mime(struct vhost *v, const char *path) if (v == NULL || path == NULL) return default_mime; - for (loc = v->locations; loc->match != NULL; ++loc) { + for (loc = &v->locations[1]; loc->match != NULL; ++loc) { if (!fnmatch(loc->match, path, 0)) { if (loc->default_mime != NULL) - default_mime = loc->default_mime; + return loc->default_mime; } } + if (v->locations[0].default_mime != NULL) + return v->locations[0].default_mime; return default_mime; } @@ -76,13 +77,15 @@ vhost_index(struct vhost *v, const char *path) if (v == NULL || path == NULL) return index; - for (loc = v->locations; loc->match != NULL; ++loc) { + for (loc = &v->locations[1]; loc->match != NULL; ++loc) { if (!fnmatch(loc->match, path, 0)) { if (loc->index != NULL) - index = loc->index; + return loc->index; } } + if (v->locations[0].default_mime != NULL) + return v->locations[0].default_mime; return index; } @@ -90,16 +93,18 @@ int vhost_auto_index(struct vhost *v, const char *path) { struct location *loc; - int auto_index = 0; + + if (v == NULL || path == NULL) + return 0; for (loc = v->locations; loc->match != NULL; ++loc) { if (!fnmatch(loc->match, path, 0)) { - if (loc->auto_index) - auto_index = loc->auto_index; + if (loc->auto_index != 0) + return loc->auto_index == 1; } } - return auto_index == 1; + return v->locations[0].auto_index == 1; } int |