mirror of https://github.com/omar-polo/gmid.git
revamp fastcgi configuration: make it per-location
this revamps the syntax in the configuration to better match httpd(8) (and in general be less weird) and to allow per-location fastcgi configurations. the bare `param' is now deprecated, but for compatibility it acts like `fastcgi param' would do now. Same story for `fastcgi <path>'.
This commit is contained in:
parent
f36ba9be59
commit
a1ba9650a9
30
config.c
30
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:
|
||||
|
|
4
fcgi.c
4
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);
|
||||
}
|
||||
|
||||
|
|
127
gmid.conf.5
127
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.
|
||||
|
|
6
gmid.h
6
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 char*);
|
|||
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);
|
||||
|
|
59
parse.y
59
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 : -1; }
|
|||
sizeof(loc->default_mime));
|
||||
free($3);
|
||||
}
|
||||
| FASTCGI fastcgi
|
||||
| fastcgi
|
||||
| INDEX string {
|
||||
(void) strlcpy(loc->index, $2, sizeof(loc->index));
|
||||
free($2);
|
||||
|
@ -487,26 +489,44 @@ locopt : AUTO INDEX bool { loc->auto_index = $3 ? 1 : -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);
|
||||
}
|
||||
| error '}'
|
||||
;
|
||||
|
||||
fastcgiopts : /* empty */
|
||||
| fastcgiopts fastcgiopt optnl
|
||||
;
|
||||
|
||||
fastcgiopt : PARAM string '=' string {
|
||||
add_param($2, $4);
|
||||
}
|
||||
| SOCKET string {
|
||||
loc->fcgi = fastcgi_conf($2, NULL);
|
||||
free($2);
|
||||
}
|
||||
| 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);
|
||||
}
|
||||
| TCP string {
|
||||
loc->fcgi = fastcgi_conf($2, "9000");
|
||||
free($2);
|
||||
| SOCKET TCP string {
|
||||
loc->fcgi = fastcgi_conf($3, "9000");
|
||||
}
|
||||
| TCP string PORT string {
|
||||
loc->fcgi = fastcgi_conf($2, $4);
|
||||
free($2);
|
||||
free($4);
|
||||
| SOCKET TCP string PORT string {
|
||||
loc->fcgi = fastcgi_conf($3, $5);
|
||||
free($3);
|
||||
free($5);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -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));
|
||||
|
|
19
server.c
19
server.c
|
@ -243,23 +243,23 @@ vhost_block_return(struct vhost *v, const char *path, int *code, const char **fm
|
|||
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;
|
||||
}
|
||||
|
|
2
utils.c
2
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue