summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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)
CGI_INTERPRETER,
} cgi_type = CGI_NONE;
#endif
+#if ENABLE_FEATURE_HTTPD_PROXY
+ Htaccess_Proxy *proxy_entry;
+#endif
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
smallint authorized = -1;
#endif
@@ -2231,13 +2234,57 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
if (!get_line()) /* EOF or error or empty line */
send_headers_and_exit(HTTP_BAD_REQUEST);
- /* Determine type of request (GET/POST/...) */
+ /* Find URL */
// rfc2616: method and URI is separated by exactly one space
//urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed
urlp = strchr(iobuf, ' ');
if (urlp == NULL)
send_headers_and_exit(HTTP_BAD_REQUEST);
*urlp++ = '\0';
+ //urlp = skip_whitespace(urlp); - should not be necessary
+ if (urlp[0] != '/')
+ send_headers_and_exit(HTTP_BAD_REQUEST);
+ /* Find end of URL */
+ HTTP_slash = strchr(urlp, ' ');
+ /* Is it " HTTP/"? */
+ if (!HTTP_slash || strncmp(HTTP_slash + 1, HTTP_200, 5) != 0)
+ send_headers_and_exit(HTTP_BAD_REQUEST);
+ *HTTP_slash++ = '\0';
+
+#if ENABLE_FEATURE_HTTPD_PROXY
+ proxy_entry = find_proxy_entry(urlp);
+ if (proxy_entry) {
+ int proxy_fd;
+ len_and_sockaddr *lsa;
+
+ if (verbose > 1)
+ bb_error_msg("proxy:%s", urlp);
+ lsa = host2sockaddr(proxy_entry->host_port, 80);
+ if (!lsa)
+ send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
+ proxy_fd = socket(lsa->u.sa.sa_family, SOCK_STREAM, 0);
+ if (proxy_fd < 0)
+ send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
+ if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0)
+ send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
+ /* Disable peer header reading timeout */
+ alarm(0);
+ /* Config directive was of the form:
+ * P:/url:[http://]hostname[:port]/new/path
+ * When /urlSFX is requested, reverse proxy it
+ * to http://hostname[:port]/new/pathSFX
+ */
+ fdprintf(proxy_fd, "%s %s%s %s\r\n",
+ iobuf, /* "GET" / "POST" / etc */
+ proxy_entry->url_to, /* "/new/path" */
+ urlp + strlen(proxy_entry->url_from), /* "SFX" */
+ HTTP_slash /* "HTTP/xyz" */
+ );
+ cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX);
+ }
+#endif
+
+ /* Determine type of request (GET/POST/...) */
#if ENABLE_FEATURE_HTTPD_CGI
prequest = request_GET;
if (strcasecmp(iobuf, prequest) == 0)
@@ -2248,7 +2295,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
prequest = request_POST;
if (strcasecmp(iobuf, prequest) == 0)
goto found;
- /* For CGI, allow other requests too (DELETE, PUT, OPTIONS, etc) */
+ /* For CGI, allow DELETE, PUT, OPTIONS, etc too */
prequest = alloca(16);
safe_strncpy((char*)prequest, iobuf, 16);
found:
@@ -2256,60 +2303,11 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
if (strcasecmp(iobuf, "GET") != 0)
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
#endif
- // rfc2616: method and URI is separated by exactly one space
- //urlp = skip_whitespace(urlp); - should not be necessary
- if (urlp[0] != '/')
- send_headers_and_exit(HTTP_BAD_REQUEST);
-
- /* Find end of URL */
- HTTP_slash = strchr(urlp, ' ');
- /* Is it " HTTP/"? */
- if (!HTTP_slash || strncmp(HTTP_slash + 1, HTTP_200, 5) != 0)
- send_headers_and_exit(HTTP_BAD_REQUEST);
- *HTTP_slash++ = '\0';
-
- /* Copy URL from after "GET "/"POST " to stack-allocated char[] */
+ /* Copy URL to stack-allocated char[] */
urlcopy = alloca((HTTP_slash - urlp) + 2 + strlen(index_page));
- /*if (urlcopy == NULL)
- * send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);*/
strcpy(urlcopy, urlp);
/* NB: urlcopy ptr is never changed after this */
-#if ENABLE_FEATURE_HTTPD_PROXY
- {
- int proxy_fd;
- len_and_sockaddr *lsa;
- Htaccess_Proxy *proxy_entry = find_proxy_entry(urlcopy);
-
- if (proxy_entry) {
- if (verbose > 1)
- bb_error_msg("proxy:%s", urlcopy);
- lsa = host2sockaddr(proxy_entry->host_port, 80);
- if (!lsa)
- send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
- proxy_fd = socket(lsa->u.sa.sa_family, SOCK_STREAM, 0);
- if (proxy_fd < 0)
- send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
- if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0)
- send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
- /* Disable peer header reading timeout */
- alarm(0);
- /* Config directive was of the form:
- * P:/url:[http://]hostname[:port]/new/path
- * When /urlSFX is requested, reverse proxy it
- * to http://hostname[:port]/new/pathSFX
- */
- fdprintf(proxy_fd, "%s %s%s %s\r\n",
- iobuf, /* "GET" / "POST" / etc */
- proxy_entry->url_to, /* "/new/path" */
- urlcopy + strlen(proxy_entry->url_from), /* "SFX" */
- HTTP_slash /* "HTTP/xyz" */
- );
- cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX);
- }
- }
-#endif
-
/* Extract url args if present */
g_query = strchr(urlcopy, '?');
if (g_query)
@@ -2571,9 +2569,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
send_headers_and_exit(HTTP_UNAUTHORIZED);
#endif
- if (found_moved_temporarily) {
+ if (found_moved_temporarily)
send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
- }
tptr = urlcopy + 1; /* skip first '/' */
@@ -2587,9 +2584,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
}
#endif
- if (urlp[-1] == '/') {
+ if (urlp[-1] == '/')
strcpy(urlp, index_page);
- }
#if ENABLE_FEATURE_HTTPD_CGI
if (prequest != request_GET && prequest != request_HEAD) {