Commit Diff


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