Implement --forward-all to forward all requests to a given url.

Suggested and initially implemented by: Christian Hesse <mail@eworm.de>
This commit is contained in:
Emil Mikulic 2014-03-14 22:36:37 +11:00
parent d28bb0c9f7
commit f73bf69a1e
4 changed files with 62 additions and 7 deletions

6
README
View File

@ -49,9 +49,15 @@ Web forward (301) requests for some hosts:
$ ./darkhttpd /var/www/htdocs --forward example.com http://www.example.com \ $ ./darkhttpd /var/www/htdocs --forward example.com http://www.example.com \
--forward secure.example.com https://www.example.com/secure --forward secure.example.com https://www.example.com/secure
Web forward (301) requests for all hosts:
$ ./darkhttpd /var/www/htdocs --forward example.com http://www.example.com \
--forward-all http://catchall.example.com
Commandline options can be combined: Commandline options can be combined:
$ ./darkhttpd ~/public_html --port 8080 --addr 127.0.0.1 $ ./darkhttpd ~/public_html --port 8080 --addr 127.0.0.1
To see a full list of commandline options, To see a full list of commandline options,
run darkhttpd without any arguments: run darkhttpd without any arguments:
$ ./darkhttpd $ ./darkhttpd
vim:set ts=2 sw=2 et tw=80:

View File

@ -233,6 +233,7 @@ struct forward_mapping {
static struct forward_mapping *forward_map = NULL; static struct forward_mapping *forward_map = NULL;
static size_t forward_map_size = 0; static size_t forward_map_size = 0;
static const char *forward_all_url = NULL;
struct mime_mapping { struct mime_mapping {
char *extension, *mimetype; char *extension, *mimetype;
@ -1019,6 +1020,11 @@ static void parse_commandline(const int argc, char *argv[]) {
url = argv[i]; url = argv[i];
add_forward_mapping(host, url); add_forward_mapping(host, url);
} }
else if (strcmp(argv[i], "--forward-all") == 0) {
if (++i >= argc)
errx(1, "missing url after --forward-all");
forward_all_url = argv[i];
}
else if (strcmp(argv[i], "--no-server-id") == 0) { else if (strcmp(argv[i], "--no-server-id") == 0) {
want_server_id = 0; want_server_id = 0;
} }
@ -1752,6 +1758,7 @@ static void process_get(struct connection *conn) {
char *decoded_url, *target, *if_mod_since; char *decoded_url, *target, *if_mod_since;
char date[DATE_LEN], lastmod[DATE_LEN]; char date[DATE_LEN], lastmod[DATE_LEN];
const char *mimetype = NULL; const char *mimetype = NULL;
const char *forward_to = NULL;
struct stat filestat; struct stat filestat;
/* work out path of file being requested */ /* work out path of file being requested */
@ -1774,16 +1781,21 @@ static void process_get(struct connection *conn) {
printf("host=\"%s\"\n", host); printf("host=\"%s\"\n", host);
for (i = 0; i < forward_map_size; i++) { for (i = 0; i < forward_map_size; i++) {
if (strcasecmp(forward_map[i].host, host) == 0) { if (strcasecmp(forward_map[i].host, host) == 0) {
redirect(conn, "%s%s", forward_to = forward_map[i].target_url;
forward_map[i].target_url, decoded_url); break;
}
}
free(host); free(host);
}
}
if (!forward_to) {
forward_to = forward_all_url;
}
if (forward_to) {
redirect(conn, "%s%s", forward_to, decoded_url);
free(decoded_url); free(decoded_url);
return; return;
} }
}
free(host);
}
}
/* does it end in a slash? serve up url/index_name */ /* does it end in a slash? serve up url/index_name */
if (decoded_url[strlen(decoded_url)-1] == '/') { if (decoded_url[strlen(decoded_url)-1] == '/') {

View File

@ -31,7 +31,7 @@ python test.py
kill $PID kill $PID
wait $PID wait $PID
echo "===> run forwarding tests" echo "===> run --forward tests"
./a.out $DIR --port $PORT \ ./a.out $DIR --port $PORT \
--forward example.com http://www.example.com \ --forward example.com http://www.example.com \
--forward secure.example.com https://www.example.com/secure >/dev/null & --forward secure.example.com https://www.example.com/secure >/dev/null &
@ -41,7 +41,17 @@ python test_forward.py
kill $PID kill $PID
wait $PID wait $PID
echo "===> run no-server-id tests" echo "===> run --forward-all tests"
./a.out $DIR --port $PORT \
--forward example.com http://www.example.com \
--forward-all http://catchall.example.com >/dev/null &
PID=$!
kill -0 $PID || exit 1
python test_forward_all.py
kill $PID
wait $PID
echo "===> run --no-server-id tests"
./a.out $DIR --port $PORT --no-server-id >/dev/null & ./a.out $DIR --port $PORT --no-server-id >/dev/null &
PID=$! PID=$!
kill -0 $PID || exit 1 kill -0 $PID || exit 1

27
devel/test_forward_all.py Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
# This is run by the "cover" script.
import unittest
from test import TestHelper, Conn, parse
class TestForwardAll(TestHelper):
def test_forward_root(self):
resp = Conn().get("/", req_hdrs = { "Host": "not-example.com" })
status, hdrs, body = parse(resp)
self.assertContains(status, "301 Moved Permanently")
expect = "http://catchall.example.com/"
self.assertEquals(hdrs["Location"], expect)
self.assertContains(body, expect)
def test_forward_relative(self):
resp = Conn().get("/foo/bar",
req_hdrs = { "Host": "still-not.example.com" })
status, hdrs, body = parse(resp)
self.assertContains(status, "301 Moved Permanently")
expect = "http://catchall.example.com/foo/bar"
self.assertEquals(hdrs["Location"], expect)
self.assertContains(body, expect)
if __name__ == '__main__':
unittest.main()
# vim:set ts=4 sw=4 et: