Commit Diff


commit - f36ba9be59c1b60aff4b9663f49d8656800afa00
commit + a1ba9650a9f0cc0d9e70800d71769d32f927b939
blob - 0eac060cab77e8d58cf641739431835a8beab823
blob + 3b84aa40f0805acd04d2af75d2f68d218db79a57
--- config.c
+++ config.c
@@ -97,11 +97,11 @@ config_purge(struct conf *conf)
 			free(l->reqca_path);
 			X509_STORE_free(l->reqca);
 			free(l);
-		}
 
-		TAILQ_FOREACH_SAFE(e, &h->params, envs, te) {
-			TAILQ_REMOVE(&h->params, e, envs);
-			free(e);
+			TAILQ_FOREACH_SAFE(e, &l->params, envs, te) {
+				TAILQ_REMOVE(&l->params, e, envs);
+				free(e);
+			}
 		}
 
 		TAILQ_FOREACH_SAFE(a, &h->aliases, aliases, ta) {
@@ -363,12 +363,12 @@ config_send(struct conf *conf)
 			if (config_send_file(ps, PROC_SERVER, IMSG_RECONF_LOC,
 			    fd, &lcopy, sizeof(lcopy)) == -1)
 				return -1;
-		}
 
-		TAILQ_FOREACH(e, &h->params, envs) {
-			if (proc_compose(ps, PROC_SERVER, IMSG_RECONF_ENV,
-			    e, sizeof(*e)) == -1)
-				return -1;
+			TAILQ_FOREACH(e, &l->params, envs) {
+				if (proc_compose(ps, PROC_SERVER,
+				    IMSG_RECONF_ENV, e, sizeof(*e)) == -1)
+					return -1;
+			}
 		}
 
 		if (proc_flush_imsg(ps, PROC_SERVER, -1) == -1)
@@ -501,6 +501,7 @@ int
 config_recv(struct conf *conf, struct imsg *imsg)
 {
 	static struct vhost *h;
+	static struct location *l;
 	static struct proxy *p;
 	struct privsep	*ps = conf->ps;
 	struct etm	 m;
@@ -570,7 +571,8 @@ config_recv(struct conf *conf, struct imsg *imsg)
 		h = vh;
 		TAILQ_INSERT_TAIL(&conf->hosts, h, vhosts);
 
-		/* reset proxy */
+		/* reset location and proxy */
+		l = NULL;
 		p = NULL;
 		break;
 
@@ -633,6 +635,7 @@ config_recv(struct conf *conf, struct imsg *imsg)
 		IMSG_SIZE_CHECK(imsg, loc);
 		loc = xcalloc(1, sizeof(*loc));
 		memcpy(loc, imsg->data, datalen);
+		TAILQ_INIT(&loc->params);
 
 		if (imsg->fd != -1) {
 			if (load_file(imsg->fd, &d, &len) == -1)
@@ -643,16 +646,17 @@ config_recv(struct conf *conf, struct imsg *imsg)
 			free(d);
 		}
 
+		l = loc;
 		TAILQ_INSERT_TAIL(&h->locations, loc, locations);
 		break;
 
 	case IMSG_RECONF_ENV:
-		if (h == NULL)
-			fatalx("recv'd env without host");
+		if (l == NULL)
+			fatalx("recv'd env without location");
 		IMSG_SIZE_CHECK(imsg, env);
 		env = xcalloc(1, sizeof(*env));
 		memcpy(env, imsg->data, datalen);
-		TAILQ_INSERT_TAIL(&h->params, env, envs);
+		TAILQ_INSERT_TAIL(&l->params, env, envs);
 		break;
 
 	case IMSG_RECONF_ALIAS:
blob - 7a141a58fe7808af08033bb33aa9643e5e19b143
blob + 281dfaa37bc6bbc0c3481155016e4d7e19493925
--- fcgi.c
+++ fcgi.c
@@ -371,7 +371,7 @@ fcgi_error(struct bufferevent *bev, short err, void *d
 }
 
 void
-fcgi_req(struct client *c)
+fcgi_req(struct client *c, struct location *loc)
 {
 	char		 buf[22];
 	char		*qs;
@@ -398,7 +398,7 @@ fcgi_req(struct client *c)
 		free(qs);
 	}
 
-	TAILQ_FOREACH(p, &c->host->params, envs) {
+	TAILQ_FOREACH(p, &loc->params, envs) {
 		fcgi_send_param(c->cgibev, p->name, p->value);
 	}
 
blob - 07e58e099c17b03f7fbada0f29b418c6a007a9b1
blob + 8e81498bc910d365ee024df56062c609efcbe103
--- gmid.conf.5
+++ gmid.conf.5
@@ -212,10 +212,17 @@ If not specified, the
 .Ic default type
 is set to
 .Dq application/octet-stream .
-.It Ic fastcgi Oo Ic tcp Oc Ar socket Oo Cm port Ar port Oc
-Enable
-.Sx FastCGI
-instead of serving files.
+.It Ic fastcgi Ar option
+Enable FastCGI instead of serving files.
+Multiple options may be specified within curly braces.
+Valid options are:
+.Bl -tag -width Ds
+.It Ic param Ar name Cm = Ar value
+Set the param
+.Ar name
+to
+.Ar value .
+.It Ic socket Oo Ic tcp Oc Ar socket Oo Cm port Ar port Oc
 The
 .Ar socket
 can either be a UNIX-domain socket or a TCP socket.
@@ -234,64 +241,9 @@ is interpreted as a hostname or an IP address.
 can be either a port number or the name of a service enclosed in
 double quotes.
 If not specified defaults to 9000.
-.It Ic index Ar string
-Set the directory index file.
-If not specified, it defaults to
-.Pa index.gmi .
-.It Ic key Ar file
-Specify the private key to use for this server.
-.Ar file
-should contain a PEM encoded private key.
-This option is mandatory.
-.It Ic lang Ar string
-Specify the language tag for the text/gemini content served.
-If not specified, no
-.Dq lang
-parameter will be added in the response.
-.It Ic listen on Ar address Op Ic port Ar number
-Set the listen
-.Ar address
-and
-.Ar port
-which defaults to
-.Sq 1965 .
-This statement can be specified multiple times.
-If
-.Ar address
-is
-.Sq *
-then
-.Xr gmid 8
-will listen on all IPv4 and IPv6 addresses.
-.Ar 0.0.0.0
-can be used to listen on all IPv4 addresses and
-.Ar ::
-on all IPv6 addresses.
-.It Ic location Ar path Brq ...
-Specify server configuration rules for a specific location.
-.Ar path
-argument will be matched against the request path with shell globbing
-rules.
-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 alias , Ic cert , Ic key , Ic listen , Ic location , Ic param
-and
-.Ic proxy .
-.It Ic log Ar bool
-Enable or disable the logging for the current server or location block.
-.It Ic param Ar name Cm = Ar value
-Set the param
-.Ar name
-to
-.Ar value
-for FastCGI.
-By default the following parameters are defined:
+.El
+.Pp
+The FastCGI handler will be given the following variables by default:
 .Bl -tag -width 24m
 .It Ev GATEWAY_INTERFACE
 .Dq CGI/1.1
@@ -368,6 +320,57 @@ certificate in the ISO 8601 format
 The time corresponding to the start of the validity period of the peer
 certificate in the ISO 8601 format.
 .El
+.It Ic index Ar string
+Set the directory index file.
+If not specified, it defaults to
+.Pa index.gmi .
+.It Ic key Ar file
+Specify the private key to use for this server.
+.Ar file
+should contain a PEM encoded private key.
+This option is mandatory.
+.It Ic lang Ar string
+Specify the language tag for the text/gemini content served.
+If not specified, no
+.Dq lang
+parameter will be added in the response.
+.It Ic listen on Ar address Op Ic port Ar number
+Set the listen
+.Ar address
+and
+.Ar port
+which defaults to
+.Sq 1965 .
+This statement can be specified multiple times.
+If
+.Ar address
+is
+.Sq *
+then
+.Xr gmid 8
+will listen on all IPv4 and IPv6 addresses.
+.Ar 0.0.0.0
+can be used to listen on all IPv4 addresses and
+.Ar ::
+on all IPv6 addresses.
+.It Ic location Ar path Brq ...
+Specify server configuration rules for a specific location.
+.Ar path
+argument will be matched against the request path with shell globbing
+rules.
+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 alias , Ic cert , Ic key , Ic listen , Ic location
+and
+.Ic proxy .
+.It Ic log Ar bool
+Enable or disable the logging for the current server or location block.
 .It Ic ocsp Ar file
 Specify an OCSP response to be stapled during TLS handshakes
 with this server.
blob - c1fd62c38256e0a3ec065c10c7a501326ce6bb70
blob + 337fb0cd3c19959e03906c2b31d8925b032114f7
--- gmid.h
+++ gmid.h
@@ -175,6 +175,7 @@ struct location {
 	X509_STORE	*reqca;
 	int		 disable_log;
 	int		 fcgi;
+	struct envhead	 params;
 
 	char		 dir[PATH_MAX];
 	int		 dirfd;
@@ -209,7 +210,6 @@ struct vhost {
 	 */
 	struct lochead	 locations;
 
-	struct envhead	 params;
 	struct aliashead aliases;
 	struct proxyhead proxies;
 };
@@ -389,7 +389,7 @@ const char	*vhost_default_mime(struct vhost*, const ch
 const char	*vhost_index(struct vhost*, const char*);
 int		 vhost_auto_index(struct vhost*, const char*);
 int		 vhost_block_return(struct vhost*, const char*, int*, const char**);
-int		 vhost_fastcgi(struct vhost*, const char*);
+struct location	*vhost_fastcgi(struct vhost*, const char*);
 int		 vhost_dirfd(struct vhost*, const char*, size_t*);
 int		 vhost_strip(struct vhost*, const char*);
 X509_STORE	*vhost_require_ca(struct vhost*, const char*);
@@ -418,7 +418,7 @@ int		 select_non_dotdot(const struct dirent*);
 void		 fcgi_read(struct bufferevent *, void *);
 void		 fcgi_write(struct bufferevent *, void *);
 void		 fcgi_error(struct bufferevent *, short, void *);
-void		 fcgi_req(struct client *);
+void		 fcgi_req(struct client *, struct location *);
 
 /* sandbox.c */
 void		 sandbox_main_process(void);
blob - 5a72bf41391cc76033b7e78a4b74989d3213a575
blob + 2dcb4bc5a1edbb6cb2bd722b275f7529256791f0
--- parse.y
+++ parse.y
@@ -133,7 +133,7 @@ typedef struct {
 %token	OCSP OFF ON
 %token	PARAM PORT PREFORK PROTO PROTOCOLS PROXY
 %token	RELAY_TO REQUIRE RETURN ROOT
-%token	SERVER SNI STRIP
+%token	SERVER SNI SOCKET STRIP
 %token	TCP TOEXT TYPE TYPES
 %token	USE_TLS USER
 %token	VERIFYNAME
@@ -326,6 +326,8 @@ servopt		: ALIAS string {
 			host->ocsp_path = $2;
 		}
 		| PARAM string '=' string {
+			yywarn("the top-level `param' directive is deprecated."
+			    "  Please use `fastcgi { param ... }`");
 			add_param($2, $4);
 		}
 		| LISTEN ON listen_addr {
@@ -465,7 +467,7 @@ locopt		: AUTO INDEX bool	{ loc->auto_index = $3 ? 1 :
 			    sizeof(loc->default_mime));
 			free($3);
 		}
-		| FASTCGI fastcgi
+		| fastcgi
 		| INDEX string {
 			(void) strlcpy(loc->index, $2, sizeof(loc->index));
 			free($2);
@@ -487,27 +489,45 @@ locopt		: AUTO INDEX bool	{ loc->auto_index = $3 ? 1 :
 		| STRIP NUM		{ loc->strip = check_strip_no($2); }
 		;
 
-fastcgi		: string {
-			loc->fcgi = fastcgi_conf($1, NULL);
-			free($1);
-		}
-		| TCP string PORT NUM {
-			char *c;
-			if (asprintf(&c, "%d", $4) == -1)
-				fatal("asprintf");
-			loc->fcgi = fastcgi_conf($2, c);
+fastcgi		: FASTCGI '{' optnl fastcgiopts '}'
+		| FASTCGI fastcgiopt
+		| FASTCGI string {
+			yywarn("`fastcgi path' is deprecated.  "
+			    "Please use `fastcgi socket path' instead.");
+			loc->fcgi = fastcgi_conf($2, NULL);
 			free($2);
-			free(c);
 		}
-		| TCP string {
-			loc->fcgi = fastcgi_conf($2, "9000");
-			free($2);
+		| error '}'
+		;
+
+fastcgiopts	: /* empty */
+		| fastcgiopts fastcgiopt optnl
+		;
+
+fastcgiopt	: PARAM string '=' string {
+			add_param($2, $4);
 		}
-		| TCP string PORT string {
-			loc->fcgi = fastcgi_conf($2, $4);
+		| SOCKET string {
+			loc->fcgi = fastcgi_conf($2, NULL);
 			free($2);
-			free($4);
 		}
+		| SOCKET TCP string PORT NUM {
+			char *c;
+
+			if (asprintf(&c, "%d", $5) == -1)
+				fatal("asprintf");
+			loc->fcgi = fastcgi_conf($3, c);
+			free($3);
+			free(c);
+		}
+		| SOCKET TCP string {
+			loc->fcgi = fastcgi_conf($3, "9000");
+		}
+		| SOCKET TCP string PORT string {
+			loc->fcgi = fastcgi_conf($3, $5);
+			free($3);
+			free($5);
+		}
 		;
 
 types		: TYPES '{' optnl mediaopts_l '}' ;
@@ -586,6 +606,7 @@ static const struct keyword {
 	{"root", ROOT},
 	{"server", SERVER},
 	{"sni", SNI},
+	{"socket", SOCKET},
 	{"strip", STRIP},
 	{"tcp", TCP},
 	{"to-ext", TOEXT},
@@ -1183,7 +1204,7 @@ void
 add_param(char *name, char *val)
 {
 	struct envlist *e;
-	struct envhead *h = &host->params;
+	struct envhead *h = &loc->params;
 
 	e = xcalloc(1, sizeof(*e));
 	(void) strlcpy(e->name, name, sizeof(e->name));
blob - 8559b99344adc7478d8e745af031c24b490e6d5e
blob + 88479f1e797759712b76b50494e83a023e2760d7
--- server.c
+++ server.c
@@ -243,23 +243,23 @@ vhost_block_return(struct vhost *v, const char *path, 
 	return loc->block_code != 0;
 }
 
-int
+struct location *
 vhost_fastcgi(struct vhost *v, const char *path)
 {
 	struct location *loc;
 
 	if (v == NULL || path == NULL)
-		return -1;
+		return NULL;
 
 	loc = TAILQ_FIRST(&v->locations);
 	while ((loc = TAILQ_NEXT(loc, locations)) != NULL) {
 		if (loc->fcgi != -1)
 			if (matches(loc->match, path))
-				return loc->fcgi;
+				return loc;
 	}
 
 	loc = TAILQ_FIRST(&v->locations);
-	return loc->fcgi;
+	return loc->fcgi == -1 ? NULL : loc;
 }
 
 int
@@ -705,20 +705,21 @@ fcgi_open_conn(struct fcgi *f)
 static int
 apply_fastcgi(struct client *c)
 {
-	int		 id, i = 0;
+	int		 i = 0;
 	struct fcgi	*f;
+	struct location	*loc;
 
-	if ((id = vhost_fastcgi(c->host, c->iri.path)) == -1)
+	if ((loc = vhost_fastcgi(c->host, c->iri.path)) == NULL)
 		return 0;
 
 	TAILQ_FOREACH(f, &c->conf->fcgi, fcgi) {
-		if (i == id)
+		if (i == loc->fcgi)
 			break;
 		++i;
 	}
 
 	if (f == NULL) {
-		log_warnx("can't find fcgi #%d", id);
+		log_warnx("can't find fcgi #%d", loc->fcgi);
 		return 0;
 	}
 
@@ -745,7 +746,7 @@ apply_fastcgi(struct client *c)
 	}
 
 	bufferevent_enable(c->cgibev, EV_READ|EV_WRITE);
-	fcgi_req(c);
+	fcgi_req(c, loc);
 
 	return 1;
 }
blob - a020b9f5324af7e99561557ca739df446276dca4
blob + 2a9d4a4cfc0e314f6aa3c51ce2ac5a02e706bab8
--- utils.c
+++ utils.c
@@ -348,7 +348,6 @@ new_vhost(void)
 	h = xcalloc(1, sizeof(*h));
 	TAILQ_INIT(&h->addrs);
 	TAILQ_INIT(&h->locations);
-	TAILQ_INIT(&h->params);
 	TAILQ_INIT(&h->aliases);
 	TAILQ_INIT(&h->proxies);
 	return h;
@@ -362,6 +361,7 @@ new_location(void)
 	l = xcalloc(1, sizeof(*l));
 	l->dirfd = -1;
 	l->fcgi = -1;
+	TAILQ_INIT(&l->params);
 	return l;
 }