Commit Diff


commit - 9adde3d8b2936f53d7b658c91f627336f563ab23
commit + e7a2a99b5acfd15f0a0bba63344ec028a36700b3
blob - 35b9e148c54ada15e846adf58d4809fc37dc01f1
blob + 453c18817b1115d3378b081fbdae799e9a1a1c21
--- gmid.1
+++ gmid.1
@@ -177,6 +177,10 @@ Specify the language tag for the text/gemini content s
 If not specified, no
 .Dq lang
 parameter will be added in the response.
+.It Ic index Ar string
+Set the directory index file.
+If not specified, it defaults to
+.Pa index.gmi
 .El
 .Sh CGI
 When CGI scripts are enabled for a directory, a request for an
blob - 4a2c2c33e4efe3604fb6da45e59bae65bcc575e4
blob + 5388023427098827fecf83c357f898d76678514e
--- gmid.h
+++ gmid.h
@@ -65,6 +65,7 @@ struct vhost {
 	char		*lang;
 	int		 dirfd;
 	char		*default_mime;
+	char		*index;
 };
 
 extern struct vhost hosts[HOSTSLEN];
blob - 154fa6932bf4775cedc6379b545c2cd4bcae89d3
blob + 0932bc3ba0af1fe2db1b68a5721a3e72b1f918a1
--- lex.l
+++ lex.l
@@ -58,13 +58,14 @@ protocols	return TPROTOCOLS;
 mime		return TMIME;
 default		return TDEFAULT;
 type		return TTYPE;
-lang		return TLANG;
 server		return TSERVER;
 
 cert		return TCERT;
 key		return TKEY;
 root		return TROOT;
 cgi		return TCGI;
+lang		return TLANG;
+index		return TINDEX;
 
 [{}]		return *yytext;
 
blob - e72f2f0478ec188fa0edaac1daa2f66e2741d552
blob + 2d8f0b855acc9ea0c12421c60a7ab408b4e6b807
--- parse.y
+++ parse.y
@@ -106,4 +106,8 @@ servopt		: TCERT TSTRING		{ host->cert = $2; }
 			free(host->lang);
 			host->lang = $2;
 		}
+		| TINDEX TSTRING {
+			free(host->index);
+			host->index = $2;
+		}
 		;
blob - fdccdb7bba1efd0215abb4731fc87217f6ec11b0
blob + 6e62029b119ed834817fb59d9e2decd7f6bbf754
--- regress/runtime
+++ regress/runtime
@@ -173,3 +173,14 @@ echo OK GET /invalid with cgi
 
 check "should be running"
 quit
+
+config '' 'index "foo.gmi"'
+checkconf
+run
+
+eq "$(head /dir/)"	"20 text/gemini"	"Unexpected head for /"
+eq "$(get  /dir/)"	"# hello world$ln"	"Unexpected body for error"
+echo OK GET /dir/ with custom index
+
+check "should be running"
+quit
blob - 69d79c1b24fdac7dd0a4aa5e0a40c086b9579665
blob + 62fef97850b53b67c06472051910e83c05ff751d
--- server.c
+++ server.c
@@ -371,19 +371,14 @@ void
 send_dir(struct pollfd *fds, struct client *c)
 {
 	size_t len;
+	const char *index = "index.gmi";
 
-	/* guard against a re-entrant call:
-	 *
-	 *	open_file -> send_dir -> open_file -> send_dir
-	 *
-	 * this can happen only if:
+	/* guard against a re-entrant call: open_file -> send_dir ->
+	 * open_file -> send_dir.  This can happen only if:
 	 *
 	 *  - user requested a dir, say foo/
-	 *  - we try to serve foo/index.gmi
-	 *  - foo/index.gmi is a directory.
-	 *
-	 * It's an unlikely case, but can happen.  We then redirect
-	 * to foo/index.gmi
+	 *  - we try to serve foo/$INDEX
+	 *  - foo/$INDEX is a directory.
 	 */
 	if (c->iri.path == c->sbuf) {
 		goodbye(fds, c, TEMP_REDIRECT, c->sbuf);
@@ -406,7 +401,9 @@ send_dir(struct pollfd *fds, struct client *c)
 	if (!ends_with(c->sbuf, "/"))
 		strlcat(c->sbuf, "/", sizeof(c->sbuf));
 
-	len = strlcat(c->sbuf, "index.gmi", sizeof(c->sbuf));
+	if (c->host->index != NULL)
+		index = c->host->index;
+	len = strlcat(c->sbuf, index, sizeof(c->sbuf));
 
 	if (len >= sizeof(c->sbuf)) {
 		goodbye(fds, c, TEMP_FAILURE, "internal server error");