aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-05-04 19:51:39 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-05-04 19:52:41 +0200
commitff4d898fe6a0f082baff929087df7eb38d4e890c (patch)
tree760ced4e69b3a63dda413c7a66dbc6f0789213d9
parent36e932abdfd79f55fdded4142d10319ba843839e (diff)
downloadbusybox-w32-ff4d898fe6a0f082baff929087df7eb38d4e890c.tar.gz
busybox-w32-ff4d898fe6a0f082baff929087df7eb38d4e890c.tar.bz2
busybox-w32-ff4d898fe6a0f082baff929087df7eb38d4e890c.zip
httpd: move proxy check before URL duplication and request type check
This makes proxy work for any type of requests. function old new delta handle_incoming_and_exit 2240 2172 -68 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/httpd.c108
1 files changed, 52 insertions, 56 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index 09e19dc29..951213ec5 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -2190,6 +2190,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2190 CGI_INTERPRETER, 2190 CGI_INTERPRETER,
2191 } cgi_type = CGI_NONE; 2191 } cgi_type = CGI_NONE;
2192#endif 2192#endif
2193#if ENABLE_FEATURE_HTTPD_PROXY
2194 Htaccess_Proxy *proxy_entry;
2195#endif
2193#if ENABLE_FEATURE_HTTPD_BASIC_AUTH 2196#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
2194 smallint authorized = -1; 2197 smallint authorized = -1;
2195#endif 2198#endif
@@ -2231,13 +2234,57 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2231 if (!get_line()) /* EOF or error or empty line */ 2234 if (!get_line()) /* EOF or error or empty line */
2232 send_headers_and_exit(HTTP_BAD_REQUEST); 2235 send_headers_and_exit(HTTP_BAD_REQUEST);
2233 2236
2234 /* Determine type of request (GET/POST/...) */ 2237 /* Find URL */
2235 // rfc2616: method and URI is separated by exactly one space 2238 // rfc2616: method and URI is separated by exactly one space
2236 //urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed 2239 //urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed
2237 urlp = strchr(iobuf, ' '); 2240 urlp = strchr(iobuf, ' ');
2238 if (urlp == NULL) 2241 if (urlp == NULL)
2239 send_headers_and_exit(HTTP_BAD_REQUEST); 2242 send_headers_and_exit(HTTP_BAD_REQUEST);
2240 *urlp++ = '\0'; 2243 *urlp++ = '\0';
2244 //urlp = skip_whitespace(urlp); - should not be necessary
2245 if (urlp[0] != '/')
2246 send_headers_and_exit(HTTP_BAD_REQUEST);
2247 /* Find end of URL */
2248 HTTP_slash = strchr(urlp, ' ');
2249 /* Is it " HTTP/"? */
2250 if (!HTTP_slash || strncmp(HTTP_slash + 1, HTTP_200, 5) != 0)
2251 send_headers_and_exit(HTTP_BAD_REQUEST);
2252 *HTTP_slash++ = '\0';
2253
2254#if ENABLE_FEATURE_HTTPD_PROXY
2255 proxy_entry = find_proxy_entry(urlp);
2256 if (proxy_entry) {
2257 int proxy_fd;
2258 len_and_sockaddr *lsa;
2259
2260 if (verbose > 1)
2261 bb_error_msg("proxy:%s", urlp);
2262 lsa = host2sockaddr(proxy_entry->host_port, 80);
2263 if (!lsa)
2264 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2265 proxy_fd = socket(lsa->u.sa.sa_family, SOCK_STREAM, 0);
2266 if (proxy_fd < 0)
2267 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2268 if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0)
2269 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2270 /* Disable peer header reading timeout */
2271 alarm(0);
2272 /* Config directive was of the form:
2273 * P:/url:[http://]hostname[:port]/new/path
2274 * When /urlSFX is requested, reverse proxy it
2275 * to http://hostname[:port]/new/pathSFX
2276 */
2277 fdprintf(proxy_fd, "%s %s%s %s\r\n",
2278 iobuf, /* "GET" / "POST" / etc */
2279 proxy_entry->url_to, /* "/new/path" */
2280 urlp + strlen(proxy_entry->url_from), /* "SFX" */
2281 HTTP_slash /* "HTTP/xyz" */
2282 );
2283 cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX);
2284 }
2285#endif
2286
2287 /* Determine type of request (GET/POST/...) */
2241#if ENABLE_FEATURE_HTTPD_CGI 2288#if ENABLE_FEATURE_HTTPD_CGI
2242 prequest = request_GET; 2289 prequest = request_GET;
2243 if (strcasecmp(iobuf, prequest) == 0) 2290 if (strcasecmp(iobuf, prequest) == 0)
@@ -2248,7 +2295,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2248 prequest = request_POST; 2295 prequest = request_POST;
2249 if (strcasecmp(iobuf, prequest) == 0) 2296 if (strcasecmp(iobuf, prequest) == 0)
2250 goto found; 2297 goto found;
2251 /* For CGI, allow other requests too (DELETE, PUT, OPTIONS, etc) */ 2298 /* For CGI, allow DELETE, PUT, OPTIONS, etc too */
2252 prequest = alloca(16); 2299 prequest = alloca(16);
2253 safe_strncpy((char*)prequest, iobuf, 16); 2300 safe_strncpy((char*)prequest, iobuf, 16);
2254 found: 2301 found:
@@ -2256,60 +2303,11 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2256 if (strcasecmp(iobuf, "GET") != 0) 2303 if (strcasecmp(iobuf, "GET") != 0)
2257 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 2304 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
2258#endif 2305#endif
2259 // rfc2616: method and URI is separated by exactly one space 2306 /* Copy URL to stack-allocated char[] */
2260 //urlp = skip_whitespace(urlp); - should not be necessary
2261 if (urlp[0] != '/')
2262 send_headers_and_exit(HTTP_BAD_REQUEST);
2263
2264 /* Find end of URL */
2265 HTTP_slash = strchr(urlp, ' ');
2266 /* Is it " HTTP/"? */
2267 if (!HTTP_slash || strncmp(HTTP_slash + 1, HTTP_200, 5) != 0)
2268 send_headers_and_exit(HTTP_BAD_REQUEST);
2269 *HTTP_slash++ = '\0';
2270
2271 /* Copy URL from after "GET "/"POST " to stack-allocated char[] */
2272 urlcopy = alloca((HTTP_slash - urlp) + 2 + strlen(index_page)); 2307 urlcopy = alloca((HTTP_slash - urlp) + 2 + strlen(index_page));
2273 /*if (urlcopy == NULL)
2274 * send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);*/
2275 strcpy(urlcopy, urlp); 2308 strcpy(urlcopy, urlp);
2276 /* NB: urlcopy ptr is never changed after this */ 2309 /* NB: urlcopy ptr is never changed after this */
2277 2310
2278#if ENABLE_FEATURE_HTTPD_PROXY
2279 {
2280 int proxy_fd;
2281 len_and_sockaddr *lsa;
2282 Htaccess_Proxy *proxy_entry = find_proxy_entry(urlcopy);
2283
2284 if (proxy_entry) {
2285 if (verbose > 1)
2286 bb_error_msg("proxy:%s", urlcopy);
2287 lsa = host2sockaddr(proxy_entry->host_port, 80);
2288 if (!lsa)
2289 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2290 proxy_fd = socket(lsa->u.sa.sa_family, SOCK_STREAM, 0);
2291 if (proxy_fd < 0)
2292 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2293 if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0)
2294 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
2295 /* Disable peer header reading timeout */
2296 alarm(0);
2297 /* Config directive was of the form:
2298 * P:/url:[http://]hostname[:port]/new/path
2299 * When /urlSFX is requested, reverse proxy it
2300 * to http://hostname[:port]/new/pathSFX
2301 */
2302 fdprintf(proxy_fd, "%s %s%s %s\r\n",
2303 iobuf, /* "GET" / "POST" / etc */
2304 proxy_entry->url_to, /* "/new/path" */
2305 urlcopy + strlen(proxy_entry->url_from), /* "SFX" */
2306 HTTP_slash /* "HTTP/xyz" */
2307 );
2308 cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX);
2309 }
2310 }
2311#endif
2312
2313 /* Extract url args if present */ 2311 /* Extract url args if present */
2314 g_query = strchr(urlcopy, '?'); 2312 g_query = strchr(urlcopy, '?');
2315 if (g_query) 2313 if (g_query)
@@ -2571,9 +2569,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2571 send_headers_and_exit(HTTP_UNAUTHORIZED); 2569 send_headers_and_exit(HTTP_UNAUTHORIZED);
2572#endif 2570#endif
2573 2571
2574 if (found_moved_temporarily) { 2572 if (found_moved_temporarily)
2575 send_headers_and_exit(HTTP_MOVED_TEMPORARILY); 2573 send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
2576 }
2577 2574
2578 tptr = urlcopy + 1; /* skip first '/' */ 2575 tptr = urlcopy + 1; /* skip first '/' */
2579 2576
@@ -2587,9 +2584,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2587 } 2584 }
2588#endif 2585#endif
2589 2586
2590 if (urlp[-1] == '/') { 2587 if (urlp[-1] == '/')
2591 strcpy(urlp, index_page); 2588 strcpy(urlp, index_page);
2592 }
2593 2589
2594#if ENABLE_FEATURE_HTTPD_CGI 2590#if ENABLE_FEATURE_HTTPD_CGI
2595 if (prequest != request_GET && prequest != request_HEAD) { 2591 if (prequest != request_GET && prequest != request_HEAD) {