$ ./darkhttpd /var/www/htdocs --forward example.com http://www.example.com \
--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:
$ ./darkhttpd ~/public_html --port 8080 --addr 127.0.0.1
To see a full list of commandline options,
run darkhttpd without any arguments:
$ ./darkhttpd
+
+vim:set ts=2 sw=2 et tw=80:
static struct forward_mapping *forward_map = NULL;
static size_t forward_map_size = 0;
+static const char *forward_all_url = NULL;
struct mime_mapping {
char *extension, *mimetype;
url = argv[i];
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) {
want_server_id = 0;
}
char *decoded_url, *target, *if_mod_since;
char date[DATE_LEN], lastmod[DATE_LEN];
const char *mimetype = NULL;
+ const char *forward_to = NULL;
struct stat filestat;
/* work out path of file being requested */
printf("host=\"%s\"\n", host);
for (i = 0; i < forward_map_size; i++) {
if (strcasecmp(forward_map[i].host, host) == 0) {
- redirect(conn, "%s%s",
- forward_map[i].target_url, decoded_url);
- free(host);
- free(decoded_url);
- return;
+ forward_to = forward_map[i].target_url;
+ break;
}
}
free(host);
}
}
+ if (!forward_to) {
+ forward_to = forward_all_url;
+ }
+ if (forward_to) {
+ redirect(conn, "%s%s", forward_to, decoded_url);
+ free(decoded_url);
+ return;
+ }
/* does it end in a slash? serve up url/index_name */
if (decoded_url[strlen(decoded_url)-1] == '/') {
kill $PID
wait $PID
-echo "===> run forwarding tests"
+echo "===> run --forward tests"
./a.out $DIR --port $PORT \
--forward example.com http://www.example.com \
--forward secure.example.com https://www.example.com/secure >/dev/null &
kill $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 &
PID=$!
kill -0 $PID || exit 1
--- /dev/null
+#!/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: