aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2021-01-30 12:04:20 +0000
committerOmar Polo <op@omarpolo.com>2021-01-30 12:04:20 +0000
commit6016a593a32c4f3f27ed3e7892a1595d631fcbef (patch)
treeefbf517aa47a564c87138c55e09404bc17d909d8
parent601bc1cc3797c8afc6610478cab9004be7a2c7b0 (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.110
-rw-r--r--gmid.h4
-rw-r--r--server.c31
3 files changed, 27 insertions, 18 deletions
diff --git a/gmid.1 b/gmid.1
index 781bf41..34a0591 100644
--- a/gmid.1
+++ b/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
diff --git a/gmid.h b/gmid.h
index 2b6a1c8..fc9ec53 100644
--- a/gmid.h
+++ b/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];
};
diff --git a/server.c b/server.c
index 4ee62bc..2be6e68 100644
--- a/server.c
+++ b/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