quark

quark web server
git clone git://git.suckless.org/quark
Log | Files | Refs | LICENSE

commit 02d6ae5a5714ad24ea0d56a1d575c3dc72bb6949
parent 4948053bee6d4883d988d104316d11ad9a0ca092
Author: Laslo Hunhold <dev@frign.de>
Date:   Tue, 27 Feb 2018 11:36:24 +0100

Add support for adding a prefix to a target when matching vhosts

This makes quark's vhost-handling very powerful while still being
simple.

Imagine you have a website with a subdomain you really want
to move back to your main domain.
Say the subdomain is called "old.example.org" and you want to serve it
under "example.org" but in the subdirectory "old/", i.e. you want to
redirect a request "old.example.org/subdir/" to "example.org/old/subdir".

For a vhost-handler that only takes 4 arguments for each vhost this is
actually pretty powerful.

Diffstat:
config.def.h | 6++++--
http.c | 14++++++++++++--
2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -17,10 +17,12 @@ static struct { const char *name; const char *regex; const char *dir; + const char *prefix; regex_t re; } vhost[] = { - /* canonical host host regex directory */ - { "example.org", "^(www\\.)?example\\.org$", "/example.org" }, + /* canonical host host regex directory prefix */ + { "example.org", "^(www\\.)?example\\.org$", "/example.org", NULL }, + { "example.org", "old\\.example\\.org", "/", "/old" }, }; /* mime-types */ diff --git a/http.c b/http.c @@ -320,6 +320,9 @@ http_send_response(int fd, struct request *r) char *p, *q, *mime; const char *vhostmatch, *err; + /* make a working copy of the target */ + memcpy(realtarget, r->target, sizeof(realtarget)); + /* match vhost */ vhostmatch = NULL; if (vhosts) { @@ -338,10 +341,17 @@ http_send_response(int fd, struct request *r) if (i == LEN(vhost)) { return http_send_status(fd, S_NOT_FOUND); } + + /* if we have a vhost prefix, prepend it to the target */ + if (vhost[i].prefix) { + if (snprintf(realtarget, sizeof(realtarget), "%s%s", + vhost[i].prefix, realtarget) >= sizeof(realtarget)) { + return http_send_status(fd, S_REQUEST_TOO_LARGE); + } + } } /* normalize target */ - memcpy(realtarget, r->target, sizeof(realtarget)); if (normabspath(realtarget)) { return http_send_status(fd, S_BAD_REQUEST); } @@ -369,7 +379,7 @@ http_send_response(int fd, struct request *r) } } - /* redirect if targets differ or host is non-canonical */ + /* redirect if targets differ, host is non-canonical or we prefixed */ if (strcmp(r->target, realtarget) || (vhosts && vhostmatch && strcmp(r->field[REQ_HOST], vhostmatch))) { /* do we need to add a port to the Location? */