diff options
author | Reyk Floeter <reyk@esdenera.com> | 2015-06-23 17:25:57 +0200 |
---|---|---|
committer | Reyk Floeter <reyk@esdenera.com> | 2015-06-23 17:25:57 +0200 |
commit | 81406d22e54b5d3ad4799d92125dd1c4a4bc0a28 (patch) | |
tree | f06195078745a28c9e9ba9d66ac5a80032735ae0 /httpd/parse.y | |
parent | ada83f819308cab0c92bcba37a152a655782157b (diff) | |
parent | f9ef46fb267f6cf5ec187b068c993615040b7a7b (diff) | |
download | httpd-81406d22e54b5d3ad4799d92125dd1c4a4bc0a28.tar.gz httpd-81406d22e54b5d3ad4799d92125dd1c4a4bc0a28.zip |
Merge branch 'patterns'
Diffstat (limited to 'httpd/parse.y')
-rw-r--r-- | httpd/parse.y | 71 |
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; |