aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-04-16 12:45:26 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-04-16 12:45:26 +0200
commitc69f648457a552518f92c5a70689bd106f03ec13 (patch)
tree3ce1ee3bcfb0198fbd1bc442ea0c2b90656e37c9
parentcf695976c7cf169495e749c8a907e47c269e0068 (diff)
downloadbusybox-w32-c69f648457a552518f92c5a70689bd106f03ec13.tar.gz
busybox-w32-c69f648457a552518f92c5a70689bd106f03ec13.tar.bz2
busybox-w32-c69f648457a552518f92c5a70689bd106f03ec13.zip
httpd: do not decode URL and headers if proxying - send all verbatim
function old new delta handle_incoming_and_exit 2566 2385 -181 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/httpd.c114
1 files changed, 46 insertions, 68 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index 8921c02a3..205c434bf 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -2085,12 +2085,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2085 smallint authorized = -1; 2085 smallint authorized = -1;
2086#endif 2086#endif
2087 char http_major_version; 2087 char http_major_version;
2088#if ENABLE_FEATURE_HTTPD_PROXY 2088 char *HTTP_slash;
2089 char http_minor_version;
2090 char *header_buf = header_buf; /* for gcc */
2091 char *header_ptr = header_ptr;
2092 Htaccess_Proxy *proxy_entry;
2093#endif
2094 2089
2095 /* Allocation of iobuf is postponed until now 2090 /* Allocation of iobuf is postponed until now
2096 * (IOW, server process doesn't need to waste 8k) */ 2091 * (IOW, server process doesn't need to waste 8k) */
@@ -2152,18 +2147,18 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2152 send_headers_and_exit(HTTP_BAD_REQUEST); 2147 send_headers_and_exit(HTTP_BAD_REQUEST);
2153 2148
2154 /* Find end of URL and parse HTTP version, if any */ 2149 /* Find end of URL and parse HTTP version, if any */
2155 http_major_version = '0'; 2150//TODO: mayybe just reject all queries which have no " HTTP/xyz" suffix?
2156 IF_FEATURE_HTTPD_PROXY(http_minor_version = '0';) 2151//Then 'http_major_version' can be deleted
2157 tptr = strchrnul(urlp, ' '); 2152 http_major_version = ('0' - 1); /* "less than 0th" version */
2153 HTTP_slash = strchrnul(urlp, ' ');
2158 /* Is it " HTTP/"? */ 2154 /* Is it " HTTP/"? */
2159 if (tptr[0] && strncmp(tptr + 1, HTTP_200, 5) == 0) { 2155 if (HTTP_slash[0] && strncmp(HTTP_slash + 1, HTTP_200, 5) == 0) {
2160 http_major_version = tptr[6]; 2156 http_major_version = HTTP_slash[6];
2161 IF_FEATURE_HTTPD_PROXY(http_minor_version = tptr[8];) 2157 *HTTP_slash++ = '\0';
2162 } 2158 }
2163 *tptr = '\0';
2164 2159
2165 /* Copy URL from after "GET "/"POST " to stack-allocated char[] */ 2160 /* Copy URL from after "GET "/"POST " to stack-allocated char[] */
2166 urlcopy = alloca((tptr - urlp) + 2 + strlen(index_page)); 2161 urlcopy = alloca((HTTP_slash - urlp) + 2 + strlen(index_page));
2167 /*if (urlcopy == NULL) 2162 /*if (urlcopy == NULL)
2168 * send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);*/ 2163 * send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);*/
2169 strcpy(urlcopy, urlp); 2164 strcpy(urlcopy, urlp);
@@ -2178,23 +2173,45 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2178 } 2173 }
2179 2174
2180#if ENABLE_FEATURE_HTTPD_PROXY 2175#if ENABLE_FEATURE_HTTPD_PROXY
2181 proxy_entry = find_proxy_entry(urlcopy);
2182 if (proxy_entry)
2183 header_buf = header_ptr = xmalloc(MAX_HTTP_HEADERS_SIZE + 2);
2184//TODO: why we don't just start pumping data to proxy here,
2185//without decoding URL, saving headers and such???
2186 else
2187#endif
2188 { 2176 {
2189 /* (If not proxying,) decode URL escape sequences */ 2177 int proxy_fd;
2190 tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1); 2178 len_and_sockaddr *lsa;
2191 if (tptr == NULL) 2179 Htaccess_Proxy *proxy_entry = find_proxy_entry(urlcopy);
2192 send_headers_and_exit(HTTP_BAD_REQUEST); 2180
2193 if (tptr == urlcopy + 1) { 2181 if (proxy_entry) {
2194 /* '/' or NUL is encoded */ 2182 lsa = host2sockaddr(proxy_entry->host_port, 80);
2195 send_headers_and_exit(HTTP_NOT_FOUND); 2183 if (!lsa)
2184 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2185 proxy_fd = socket(lsa->u.sa.sa_family, SOCK_STREAM, 0);
2186 if (proxy_fd < 0)
2187 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2188 if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0)
2189 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2190 /* Config directive was of the form:
2191 * P:/url:[http://]hostname[:port]/new/path
2192 * When /urlSFX is requested, reverse proxy it
2193 * to http://hostname[:port]/new/pathSFX
2194 */
2195 fdprintf(proxy_fd, "%s %s%s%s%s %s\r\n",
2196 prequest, /* "GET" or "POST" */
2197 proxy_entry->url_to, /* "/new/path" */
2198 urlcopy + strlen(proxy_entry->url_from), /* "SFX" */
2199 (g_query ? "?" : ""), /* "?" (maybe) */
2200 (g_query ? g_query : ""), /* query string (maybe) */
2201 HTTP_slash /* HTTP/xyz" or "" */
2202 );
2203 cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX);
2196 } 2204 }
2197//should path canonicalization also be conditional on not proxying? 2205 }
2206#endif
2207
2208 /* Decode URL escape sequences */
2209 tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1);
2210 if (tptr == NULL)
2211 send_headers_and_exit(HTTP_BAD_REQUEST);
2212 if (tptr == urlcopy + 1) {
2213 /* '/' or NUL is encoded */
2214 send_headers_and_exit(HTTP_NOT_FOUND);
2198 } 2215 }
2199 2216
2200 /* Canonicalize path */ 2217 /* Canonicalize path */
@@ -2321,16 +2338,6 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2321 send_headers_and_exit(HTTP_ENTITY_TOO_LARGE); 2338 send_headers_and_exit(HTTP_ENTITY_TOO_LARGE);
2322 if (DEBUG) 2339 if (DEBUG)
2323 bb_error_msg("header: '%s'", iobuf); 2340 bb_error_msg("header: '%s'", iobuf);
2324#if ENABLE_FEATURE_HTTPD_PROXY
2325 if (proxy_entry) {
2326 /* protected from overflow by header_len check above */
2327 memcpy(header_ptr, iobuf, iobuf_len);
2328 header_ptr += iobuf_len;
2329 header_ptr[0] = '\r';
2330 header_ptr[1] = '\n';
2331 header_ptr += 2;
2332 }
2333#endif
2334 2341
2335#if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY 2342#if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY
2336 /* Try and do our best to parse more lines */ 2343 /* Try and do our best to parse more lines */
@@ -2457,35 +2464,6 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2457 send_headers_and_exit(HTTP_MOVED_TEMPORARILY); 2464 send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
2458 } 2465 }
2459 2466
2460#if ENABLE_FEATURE_HTTPD_PROXY
2461 if (proxy_entry) {
2462 int proxy_fd;
2463 len_and_sockaddr *lsa;
2464
2465 lsa = host2sockaddr(proxy_entry->host_port, 80);
2466 if (lsa == NULL)
2467 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2468 proxy_fd = socket(lsa->u.sa.sa_family, SOCK_STREAM, 0);
2469 if (proxy_fd < 0)
2470 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2471 if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0)
2472 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2473 fdprintf(proxy_fd, "%s %s%s%s%s HTTP/%c.%c\r\n",
2474 prequest, /* GET or POST */
2475 proxy_entry->url_to, /* url part 1 */
2476 urlcopy + strlen(proxy_entry->url_from), /* url part 2 */
2477 (g_query ? "?" : ""), /* "?" (maybe) */
2478 (g_query ? g_query : ""), /* query string (maybe) */
2479 http_major_version, http_minor_version);
2480 header_ptr[0] = '\r';
2481 header_ptr[1] = '\n';
2482 header_ptr += 2;
2483 full_write(proxy_fd, header_buf, header_ptr - header_buf);
2484 free(header_buf); /* on the order of 8k, free it */
2485 cgi_io_loop_and_exit(proxy_fd, proxy_fd, length);
2486 }
2487#endif
2488
2489 tptr = urlcopy + 1; /* skip first '/' */ 2467 tptr = urlcopy + 1; /* skip first '/' */
2490 2468
2491#if ENABLE_FEATURE_HTTPD_CGI 2469#if ENABLE_FEATURE_HTTPD_CGI