1 | --- a/include/usage.h |
2 | +++ b/include/usage.h |
3 | @@ -1693,6 +1693,7 @@ |
4 | IF_FEATURE_HTTPD_BASIC_AUTH(" [-r REALM]") \ |
5 | " [-h HOME]\n" \ |
6 | "or httpd -d/-e" IF_FEATURE_HTTPD_AUTH_MD5("/-m") " STRING" |
7 | + " [-R <path> [-H <host>]]" |
8 | #define httpd_full_usage "\n\n" \ |
9 | "Listen for incoming HTTP requests\n" \ |
10 | "\nOptions:" \ |
11 | @@ -1710,6 +1711,8 @@ |
12 | "\n -m STRING MD5 crypt STRING") \ |
13 | "\n -e STRING HTML encode STRING" \ |
14 | "\n -d STRING URL decode STRING" \ |
15 | + "\n -R PATH Redirect target path" \ |
16 | + "\n -H HOST Redirect target host" \ |
17 | |
18 | #define hwclock_trivial_usage \ |
19 | IF_FEATURE_HWCLOCK_LONG_OPTIONS( \ |
20 | --- a/networking/httpd.c |
21 | +++ b/networking/httpd.c |
22 | @@ -248,6 +248,8 @@ struct globals { |
23 | |
24 | const char *found_mime_type; |
25 | const char *found_moved_temporarily; |
26 | + const char *redirect_path; |
27 | + const char *redirect_host; |
28 | Htaccess_IP *ip_a_d; /* config allow/deny lines */ |
29 | |
30 | IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;) |
31 | @@ -294,6 +296,8 @@ struct globals { |
32 | #define index_page (G.index_page ) |
33 | #define found_mime_type (G.found_mime_type ) |
34 | #define found_moved_temporarily (G.found_moved_temporarily) |
35 | +#define redirect_path (G.redirect_path ) |
36 | +#define redirect_host (G.redirect_host ) |
37 | #define last_mod (G.last_mod ) |
38 | #define ip_a_d (G.ip_a_d ) |
39 | #define g_realm (G.g_realm ) |
40 | @@ -993,8 +997,11 @@ static void send_headers(int responseNum |
41 | } |
42 | #endif |
43 | if (responseNum == HTTP_MOVED_TEMPORARILY) { |
44 | - len += sprintf(iobuf + len, "Location: %s/%s%s\r\n", |
45 | + len += sprintf(iobuf + len, "Location: %s%s%s%s%s%s\r\n", |
46 | + (redirect_host ? "http://" : ""), |
47 | + (redirect_host ? redirect_host : ""), |
48 | found_moved_temporarily, |
49 | + (redirect_host ? "" : "/"), |
50 | (g_query ? "?" : ""), |
51 | (g_query ? g_query : "")); |
52 | } |
53 | @@ -1924,8 +1931,12 @@ static void handle_incoming_and_exit(con |
54 | } while (*++tptr); |
55 | *++urlp = '\0'; /* terminate after last character */ |
56 | |
57 | + /* redirect active */ |
58 | + if (redirect_path && (strncmp(urlcopy, redirect_path, strlen(redirect_path)) != 0)) |
59 | + found_moved_temporarily = redirect_path; |
60 | + |
61 | /* If URL is a directory, add '/' */ |
62 | - if (urlp[-1] != '/') { |
63 | + if (!redirect_path && (urlp[-1] != '/')) { |
64 | if (is_directory(urlcopy + 1, 1, &sb)) { |
65 | found_moved_temporarily = urlcopy; |
66 | } |
67 | @@ -2266,7 +2277,9 @@ static void sighup_handler(int sig UNUSE |
68 | } |
69 | |
70 | enum { |
71 | - c_opt_config_file = 0, |
72 | + R_opt_redirect_path = 0, |
73 | + H_opt_redirect_host, |
74 | + c_opt_config_file, |
75 | d_opt_decode_url, |
76 | h_opt_home_httpd, |
77 | IF_FEATURE_HTTPD_ENCODE_URL_STR(e_opt_encode_url,) |
78 | @@ -2315,12 +2328,13 @@ int httpd_main(int argc UNUSED_PARAM, ch |
79 | /* We do not "absolutize" path given by -h (home) opt. |
80 | * If user gives relative path in -h, |
81 | * $SCRIPT_FILENAME will not be set. */ |
82 | - opt = getopt32(argv, "c:d:h:" |
83 | + opt = getopt32(argv, "R:H:c:d:h:" |
84 | IF_FEATURE_HTTPD_ENCODE_URL_STR("e:") |
85 | IF_FEATURE_HTTPD_BASIC_AUTH("r:") |
86 | IF_FEATURE_HTTPD_AUTH_MD5("m:") |
87 | IF_FEATURE_HTTPD_SETUID("u:") |
88 | "p:ifv", |
89 | + &redirect_path, &redirect_host, |
90 | &opt_c_configFile, &url_for_decode, &home_httpd |
91 | IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) |
92 | IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) |
93 | |