invert the location precedence: first match wins

It's how httpd(8) does it, and it allows us to call fnmatch less time
This commit is contained in:
Omar Polo 2021-01-30 12:04:20 +00:00
parent 601bc1cc37
commit 6016a593a3
3 changed files with 27 additions and 18 deletions

10
gmid.1
View File

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

4
gmid.h
View File

@ -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];
};

View File

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