summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/httpd/config.c16
-rw-r--r--usr.sbin/httpd/httpd.h4
-rw-r--r--usr.sbin/httpd/parse.y20
-rw-r--r--usr.sbin/httpd/server.c15
-rw-r--r--usr.sbin/httpd/server_http.c26
5 files changed, 45 insertions, 36 deletions
diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c
index 9e9d2c3754d..44cd419565f 100644
--- a/usr.sbin/httpd/config.c
+++ b/usr.sbin/httpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.6 2014/07/30 10:05:14 reyk Exp $ */
+/* $OpenBSD: config.c,v 1.7 2014/07/30 13:49:48 reyk Exp $ */
/*
* Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -275,23 +275,19 @@ config_getserver(struct httpd *env, struct imsg *imsg)
memcpy(&srv_conf, p, sizeof(srv_conf));
s = sizeof(srv_conf);
- if (srv_conf.flags & SRVFLAG_LOCATION) {
- if ((srv = server_byname(srv_conf.name)) == NULL) {
- log_warnx("%s: invalid location", __func__);
- return (-1);
- }
- return (config_getserver_config(env, srv, imsg));
- }
-
/* Check if server with matching listening socket already exists */
if ((srv = server_byaddr((struct sockaddr *)
&srv_conf.ss, srv_conf.port)) != NULL) {
/* Add "host" to existing listening server */
- close(imsg->fd);
+ if (imsg->fd != -1)
+ close(imsg->fd);
return (config_getserver_config(env,
srv, imsg));
}
+ if (srv_conf.flags & SRVFLAG_LOCATION)
+ fatalx("invalid location");
+
/* Otherwise create a new server */
if ((srv = calloc(1, sizeof(*srv))) == NULL) {
close(imsg->fd);
diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h
index c15313243e4..7fa00efc9f4 100644
--- a/usr.sbin/httpd/httpd.h
+++ b/usr.sbin/httpd/httpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.h,v 1.18 2014/07/30 10:05:14 reyk Exp $ */
+/* $OpenBSD: httpd.h,v 1.19 2014/07/30 13:49:48 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -402,8 +402,6 @@ int server_bufferevent_write(struct client *, void *, size_t);
void server_inflight_dec(struct client *, const char *);
struct server *
server_byaddr(struct sockaddr *, in_port_t);
-struct server *
- server_byname(const char *);
SPLAY_PROTOTYPE(client_tree, client, clt_nodes, server_client_cmp);
diff --git a/usr.sbin/httpd/parse.y b/usr.sbin/httpd/parse.y
index 4844272b86e..3947f710cd5 100644
--- a/usr.sbin/httpd/parse.y
+++ b/usr.sbin/httpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.9 2014/07/30 10:05:14 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.10 2014/07/30 13:49:48 reyk Exp $ */
/*
* Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -233,6 +233,11 @@ server : SERVER STRING {
SPLAY_INIT(&srv->srv_clients);
TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
} '{' optnl serveropts_l '}' {
+ if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
+ yyerror("listen address not specified");
+ free($2);
+ YYERROR;
+ }
srv = NULL;
}
;
@@ -294,6 +299,12 @@ serveroptsl : LISTEN ON STRING port {
| LOCATION STRING {
struct server *s;
+ if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
+ yyerror("listen address not specified");
+ free($2);
+ YYERROR;
+ }
+
if (parentsrv != NULL) {
yyerror("location %s inside location", $2);
free($2);
@@ -337,8 +348,13 @@ serveroptsl : LISTEN ON STRING port {
YYERROR;
}
- s->srv_conf.id = ++last_server_id;
+ /* A location entry uses the parent id */
+ s->srv_conf.id = srv->srv_conf.id;
s->srv_conf.flags = SRVFLAG_LOCATION;
+ memcpy(&s->srv_conf.ss, &srv->srv_conf.ss,
+ sizeof(s->srv_conf.ss));
+ s->srv_conf.port = srv->srv_conf.port;
+ s->srv_conf.prefixlen = srv->srv_conf.prefixlen;
if (last_server_id == INT_MAX) {
yyerror("too many servers/locations defined");
diff --git a/usr.sbin/httpd/server.c b/usr.sbin/httpd/server.c
index 2b230111cd7..4c2645d7833 100644
--- a/usr.sbin/httpd/server.c
+++ b/usr.sbin/httpd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.16 2014/07/30 10:05:14 reyk Exp $ */
+/* $OpenBSD: server.c,v 1.17 2014/07/30 13:49:48 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -199,19 +199,6 @@ server_byaddr(struct sockaddr *addr, in_port_t port)
return (NULL);
}
-struct server *
-server_byname(const char *name)
-{
- struct server *srv;
-
- TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
- if (strcmp(srv->srv_conf.name, name) == 0)
- return (srv);
- }
-
- return (NULL);
-}
-
int
server_socket_af(struct sockaddr_storage *ss, in_port_t port)
{
diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c
index 05e8bf5d755..8e4de311747 100644
--- a/usr.sbin/httpd/server_http.c
+++ b/usr.sbin/httpd/server_http.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_http.c,v 1.20 2014/07/30 10:05:14 reyk Exp $ */
+/* $OpenBSD: server_http.c,v 1.21 2014/07/30 13:49:48 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -671,7 +671,7 @@ server_response(struct httpd *httpd, struct client *clt)
char path[MAXPATHLEN];
struct http_descriptor *desc = clt->clt_desc;
struct server *srv = clt->clt_srv;
- struct server_config *srv_conf = &srv->srv_conf;
+ struct server_config *srv_conf = &srv->srv_conf, *location;
struct kv *kv, key, *host;
int ret;
@@ -717,11 +717,9 @@ server_response(struct httpd *httpd, struct client *clt)
if (host != NULL) {
/* XXX maybe better to turn srv_hosts into a tree */
TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) {
- if (((srv_conf->flags & SRVFLAG_LOCATION) &&
- fnmatch(srv_conf->location,
- desc->http_path, FNM_CASEFOLD) == 0) ||
- (fnmatch(srv_conf->name, host->kv_value,
- FNM_CASEFOLD) == 0)) {
+ if ((srv_conf->flags & SRVFLAG_LOCATION) == 0 &&
+ fnmatch(srv_conf->name, host->kv_value,
+ FNM_CASEFOLD) == 0) {
/* Replace host configuration */
clt->clt_srv_conf = srv_conf;
srv_conf = NULL;
@@ -740,6 +738,20 @@ server_response(struct httpd *httpd, struct client *clt)
if (strlcpy(desc->http_host, host->kv_value,
sizeof(desc->http_host)) >= sizeof(desc->http_host))
goto fail;
+ srv_conf = clt->clt_srv_conf;
+ }
+
+ /* Now search for the location */
+ TAILQ_FOREACH(location, &srv->srv_hosts, entry) {
+ if ((location->flags & SRVFLAG_LOCATION) &&
+ location->id == srv_conf->id &&
+ fnmatch(location->location, desc->http_path,
+ FNM_CASEFOLD) == 0) {
+ /* Replace host configuration */
+ clt->clt_srv_conf = location;
+ srv_conf = NULL;
+ break;
+ }
}
if ((ret = server_file(httpd, clt)) == -1)