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:
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? */