Commit Diff


commit - 5b4a641893cfc1db2af0c612566083f58b10903b
commit + 87f2b68b58fc46ff12a592474e65280ef8455aff
blob - c8149d526f57bcc39d29238aa9193c1734aafb79
blob + 56a44faac59787607f05fa21207844decf2c387d
--- ChangeLog
+++ ChangeLog
@@ -1,6 +1,7 @@
 2021-02-02  Omar Polo  <op@omarpolo.com>
 
 	* server.c (handle_dirlist_head): print the header in the directory listing
+	(open_file): cgi follows globbing rules, just like location and hostname matching
 
 2021-02-01  Omar Polo  <op@omarpolo.com>
 
blob - f74e287e159d569d8a3244d269eb5d0c1d18b367
blob + 27068958239d78fb8a6b8ab5f1eddcf055cee976
--- gmid.1
+++ gmid.1
@@ -193,11 +193,9 @@ Specify the root directory for this server.
 This option is mandatory.
 It's relative to the chroot, if enabled.
 .It Ic cgi Pa path
-Enable the execution of CGI scripts if
+Execute CGI scripts that matches
 .Pa path
-is a prefix of the user request string.
-An empty path "" will effectively enable the execution of any file
-with the executable bit set inside the root directory.
+using shell globbing rules.
 .It Ic default type Ar string
 Set the default media type that is used if the media type for a
 specified extension is not found.
@@ -234,8 +232,9 @@ except
 .Ic cert , Ic key , Ic root , Ic location No and Ic cgi .
 .El
 .Sh CGI
-When CGI scripts are enabled, a matching request for an executable
-file will execute it and fed its output to the client.
+When a request for an executable file matches the
+.Ic cgi
+rule, that file will be execute and its output fed to the client.
 .Pp
 The CGI scripts are executed in the directory they reside and inherit
 the environment from
@@ -360,14 +359,6 @@ $ chmod +x docs/cgi/hello
 $ gmid -x cgi docs
 .Ed
 .Pp
-Note that the argument to the
-.Fl x
-option is
-.Pa cgi
-and not
-.Pa docs/cgi ,
-since it's relative to the document root.
-.Pp
 The following is an example of a possible configuration for a site
 that enables only TLSv1.3, adds a mime type for the file extension
 "rtf" and defines two virtual host:
@@ -388,7 +379,7 @@ server "it.example.com" {
 	cert "/path/to/cert.pem"
 	key  "/path/to/key.pem"
 	root "/var/gemini/it.example.com"
-	cgi  "/cgi-bin"
+	cgi  "/cgi-bin/*"
 	lang "it"
 }
 .Ed
blob - 6de3e30c26b75b35788d4f649a6a93d7b63ac3ea
blob + b114bebd4202f3f980cce8bc36c3499f5db783d9
--- regress/runtime
+++ regress/runtime
@@ -151,7 +151,7 @@ check "should be running"
 quit
 
 # finally try with CGI scripts
-config '' 'cgi ""'
+config '' 'cgi "*"'
 checkconf
 run
 
blob - 0c3b649b1ae4609c0e5a554aa5fec914b7d94c8d
blob + 281b46d333e904bb9a1abf6e61cff11289718891
--- sample.conf
+++ sample.conf
@@ -19,7 +19,7 @@ server "it.example.com" {
 	root "/var/gemini/example.com"
 
 	# enable CGI scripts in /cgi-bin/
-	cgi  "/cgi-bin/"
+	cgi  "/cgi-bin/*"
 
 	# optional
 	lang "it"
blob - d1b3a1079a053524226aee0e0a8b96638bcb13bf
blob + 7ac341221941da24e088620f3a1a63224f0dcce0
--- server.c
+++ server.c
@@ -150,7 +150,7 @@ open_file(struct pollfd *fds, struct client *c)
 {
 	switch (check_path(c, c->iri.path, &c->fd)) {
 	case FILE_EXECUTABLE:
-		if (starts_with(c->iri.path, c->host->cgi)) {
+		if (c->host->cgi != NULL && !fnmatch(c->host->cgi, c->iri.path, 0)) {
 			start_cgi(c->iri.path, "", fds, c);
 			return;
 		}
@@ -166,7 +166,7 @@ open_file(struct pollfd *fds, struct client *c)
 		return;
 
 	case FILE_MISSING:
-		if (c->host->cgi != NULL && starts_with(c->iri.path, c->host->cgi)) {
+		if (c->host->cgi != NULL && !fnmatch(c->host->cgi, c->iri.path, 0)) {
 			check_for_cgi(fds, c);
 			return;
 		}
@@ -183,7 +183,8 @@ void
 load_file(struct pollfd *fds, struct client *c)
 {
 	if ((c->len = filesize(c->fd)) == -1) {
-		LOGE(c, "failed to get file size for %s", c->iri.path);
+		LOGE(c, "failed to get file size for %s: %s",
+		    c->iri.path, strerror(errno));
 		start_reply(fds, c, TEMP_FAILURE, "internal server error");
 		return;
 	}
@@ -519,7 +520,7 @@ open_dir(struct pollfd *fds, struct client *c)
 
 	switch (check_path(c, c->iri.path, &c->fd)) {
 	case FILE_EXECUTABLE:
-		if (starts_with(c->iri.path, c->host->cgi)) {
+		if (c->host->cgi != NULL && !fnmatch(c->host->cgi, c->iri.path, 0)) {
 			start_cgi(c->iri.path, "", fds, c);
 			break;
 		}