aboutsummaryrefslogtreecommitdiff
path: root/httpd/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'httpd/parse.y')
-rw-r--r--httpd/parse.y71
1 files changed, 45 insertions, 26 deletions
diff --git a/httpd/parse.y b/httpd/parse.y
index 0aae421..f556bf0 100644
--- a/httpd/parse.y
+++ b/httpd/parse.y
@@ -107,7 +107,7 @@ int host_if(const char *, struct addresslist *,
int host(const char *, struct addresslist *,
int, struct portrange *, const char *, int);
void host_free(struct addresslist *);
-struct server *server_inherit(struct server *, const char *,
+struct server *server_inherit(struct server *, struct server_config *,
struct server_config *);
int getservice(char *);
int is_if_in_group(const char *, const char *);
@@ -131,14 +131,14 @@ typedef struct {
%token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
%token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LISTEN
-%token LOCATION LOG LOGDIR MAXIMUM NO NODELAY ON PORT PREFORK PROTOCOLS
+%token LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY ON PORT PREFORK PROTOCOLS
%token REQUEST REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TIMEOUT
%token TLS TYPES
%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.port> port
-%type <v.number> opttls
+%type <v.number> opttls optmatch
%type <v.tv> timeout
%type <v.string> numberstring optstring
%type <v.auth> authopts
@@ -200,26 +200,26 @@ main : PREFORK NUMBER {
}
;
-server : SERVER STRING {
+server : SERVER optmatch STRING {
struct server *s;
if (!loadcfg) {
- free($2);
+ free($3);
YYACCEPT;
}
if ((s = calloc(1, sizeof (*s))) == NULL)
fatal("out of memory");
- if (strlcpy(s->srv_conf.name, $2,
+ if (strlcpy(s->srv_conf.name, $3,
sizeof(s->srv_conf.name)) >=
sizeof(s->srv_conf.name)) {
yyerror("server name truncated");
- free($2);
+ free($3);
free(s);
YYERROR;
}
- free($2);
+ free($3);
strlcpy(s->srv_conf.root, HTTPD_DOCROOT,
sizeof(s->srv_conf.root));
@@ -235,7 +235,9 @@ server : SERVER STRING {
s->srv_conf.timeout.tv_sec = SERVER_TIMEOUT;
s->srv_conf.maxrequests = SERVER_MAXREQUESTS;
s->srv_conf.maxrequestbody = SERVER_MAXREQUESTBODY;
- s->srv_conf.flags |= SRVFLAG_LOG;
+ s->srv_conf.flags = SRVFLAG_LOG;
+ if ($2)
+ s->srv_conf.flags |= SRVFLAG_SERVER_MATCH;
s->srv_conf.logformat = LOG_FORMAT_COMMON;
s->srv_conf.tls_protocols = TLS_PROTOCOLS_DEFAULT;
if ((s->srv_conf.tls_cert_file =
@@ -334,7 +336,7 @@ server : SERVER STRING {
continue;
if ((sn = server_inherit(srv,
- b->name, a)) == NULL) {
+ b, a)) == NULL) {
serverconfig_free(srv_conf);
free(srv);
YYABORT;
@@ -405,30 +407,35 @@ serveroptsl : LISTEN ON STRING opttls port {
}
if (alias != NULL) {
+ /* IP-based; use name match flags from parent */
+ alias->flags = srv->srv_conf.flags;
TAILQ_INSERT_TAIL(&srv->srv_hosts,
alias, entry);
}
}
- | ALIAS STRING {
+ | ALIAS optmatch STRING {
struct server_config *alias;
if (parentsrv != NULL) {
yyerror("alias inside location");
- free($2);
+ free($3);
YYERROR;
}
if ((alias = calloc(1, sizeof(*alias))) == NULL)
fatal("out of memory");
- if (strlcpy(alias->name, $2, sizeof(alias->name)) >=
+ if (strlcpy(alias->name, $3, sizeof(alias->name)) >=
sizeof(alias->name)) {
yyerror("server alias truncated");
- free($2);
+ free($3);
free(alias);
YYERROR;
}
- free($2);
+ free($3);
+
+ if ($2)
+ alias->flags |= SRVFLAG_SERVER_MATCH;
TAILQ_INSERT_TAIL(&srv->srv_hosts, alias, entry);
}
@@ -456,38 +463,38 @@ serveroptsl : LISTEN ON STRING opttls port {
| fastcgi
| authenticate
| filter
- | LOCATION STRING {
+ | LOCATION optmatch STRING {
struct server *s;
if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
yyerror("listen address not specified");
- free($2);
+ free($3);
YYERROR;
}
if (parentsrv != NULL) {
- yyerror("location %s inside location", $2);
- free($2);
+ yyerror("location %s inside location", $3);
+ free($3);
YYERROR;
}
if (!loadcfg) {
- free($2);
+ free($3);
YYACCEPT;
}
if ((s = calloc(1, sizeof (*s))) == NULL)
fatal("out of memory");
- if (strlcpy(s->srv_conf.location, $2,
+ if (strlcpy(s->srv_conf.location, $3,
sizeof(s->srv_conf.location)) >=
sizeof(s->srv_conf.location)) {
yyerror("server location truncated");
- free($2);
+ free($3);
free(s);
YYERROR;
}
- free($2);
+ free($3);
if (strlcpy(s->srv_conf.name, srv->srv_conf.name,
sizeof(s->srv_conf.name)) >=
@@ -501,6 +508,8 @@ serveroptsl : LISTEN ON STRING opttls port {
/* A location entry uses the parent id */
s->srv_conf.parent_id = srv->srv_conf.id;
s->srv_conf.flags = SRVFLAG_LOCATION;
+ if ($2)
+ s->srv_conf.flags |= SRVFLAG_LOCATION_MATCH;
s->srv_s = -1;
memcpy(&s->srv_conf.ss, &srv->srv_conf.ss,
sizeof(s->srv_conf.ss));
@@ -884,6 +893,10 @@ block : BLOCK {
}
;
+optmatch : /* empty */ { $$ = 0; }
+ | MATCH { $$ = 1; }
+ ;
+
optstring : /* empty */ { $$ = NULL; }
| STRING { $$ = $1; }
;
@@ -1108,6 +1121,7 @@ lookup(char *s)
{ "location", LOCATION },
{ "log", LOG },
{ "logdir", LOGDIR },
+ { "match", MATCH },
{ "max", MAXIMUM },
{ "no", NO },
{ "nodelay", NODELAY },
@@ -1889,7 +1903,7 @@ host_free(struct addresslist *al)
}
struct server *
-server_inherit(struct server *src, const char *name,
+server_inherit(struct server *src, struct server_config *alias,
struct server_config *addr)
{
struct server *dst, *s, *dstl;
@@ -1927,7 +1941,7 @@ server_inherit(struct server *src, const char *name,
}
/* Now set alias and listen address */
- strlcpy(dst->srv_conf.name, name, sizeof(dst->srv_conf.name));
+ strlcpy(dst->srv_conf.name, alias->name, sizeof(dst->srv_conf.name));
memcpy(&dst->srv_conf.ss, &addr->ss, sizeof(dst->srv_conf.ss));
dst->srv_conf.port = addr->port;
dst->srv_conf.prefixlen = addr->prefixlen;
@@ -1936,6 +1950,10 @@ server_inherit(struct server *src, const char *name,
else
dst->srv_conf.flags &= ~SRVFLAG_TLS;
+ /* Don't inherit the "match" option, use it from the alias */
+ dst->srv_conf.flags &= ~SRVFLAG_SERVER_MATCH;
+ dst->srv_conf.flags |= (alias->flags & SRVFLAG_SERVER_MATCH);
+
if (server_tls_load_keypair(dst) == -1) {
yyerror("failed to load public/private keys "
"for server %s", dst->srv_conf.name);
@@ -1975,7 +1993,8 @@ server_inherit(struct server *src, const char *name,
fatal("out of memory");
memcpy(&dstl->srv_conf, &s->srv_conf, sizeof(dstl->srv_conf));
- strlcpy(dstl->srv_conf.name, name, sizeof(dstl->srv_conf.name));
+ strlcpy(dstl->srv_conf.name, alias->name,
+ sizeof(dstl->srv_conf.name));
/* Copy the new Id and listen address */
dstl->srv_conf.id = ++last_server_id;