commit 6016a593a32c4f3f27ed3e7892a1595d631fcbef from: Omar Polo date: Sat Jan 30 12:04:20 2021 UTC invert the location precedence: first match wins It's how httpd(8) does it, and it allows us to call fnmatch less time commit - 601bc1cc3797c8afc6610478cab9004be7a2c7b0 commit + 6016a593a32c4f3f27ed3e7892a1595d631fcbef blob - 781bf41f36d70a4b0ca14a4fb036bc0a3fb72c75 blob + 34a05915d99a94249514b5f9d47a6d51f6edf7e9 --- gmid.1 +++ gmid.1 @@ -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 blob - 2b6a1c86c9ed55ad4c9710bbe351fcecffb2bd66 blob + fc9ec53396cd01bcffd98b0364cc20e7e526f28c --- gmid.h +++ gmid.h @@ -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]; }; blob - 4ee62bc35cd2c1aa99f19bd1b33d2f0738e16965 blob + 2be6e68ac5cefd775d0459d0993162fda6981f50 --- server.c +++ server.c @@ -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