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>
This commit is contained in:
parent
36e932abdf
commit
ff4d898fe6
@ -2190,6 +2190,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
|||||||
CGI_INTERPRETER,
|
CGI_INTERPRETER,
|
||||||
} cgi_type = CGI_NONE;
|
} cgi_type = CGI_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_FEATURE_HTTPD_PROXY
|
||||||
|
Htaccess_Proxy *proxy_entry;
|
||||||
|
#endif
|
||||||
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
|
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
|
||||||
smallint authorized = -1;
|
smallint authorized = -1;
|
||||||
#endif
|
#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 */
|
if (!get_line()) /* EOF or error or empty line */
|
||||||
send_headers_and_exit(HTTP_BAD_REQUEST);
|
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
|
// rfc2616: method and URI is separated by exactly one space
|
||||||
//urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed
|
//urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed
|
||||||
urlp = strchr(iobuf, ' ');
|
urlp = strchr(iobuf, ' ');
|
||||||
if (urlp == NULL)
|
if (urlp == NULL)
|
||||||
send_headers_and_exit(HTTP_BAD_REQUEST);
|
send_headers_and_exit(HTTP_BAD_REQUEST);
|
||||||
*urlp++ = '\0';
|
*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
|
#if ENABLE_FEATURE_HTTPD_CGI
|
||||||
prequest = request_GET;
|
prequest = request_GET;
|
||||||
if (strcasecmp(iobuf, prequest) == 0)
|
if (strcasecmp(iobuf, prequest) == 0)
|
||||||
@ -2248,7 +2295,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
|||||||
prequest = request_POST;
|
prequest = request_POST;
|
||||||
if (strcasecmp(iobuf, prequest) == 0)
|
if (strcasecmp(iobuf, prequest) == 0)
|
||||||
goto found;
|
goto found;
|
||||||
/* For CGI, allow other requests too (DELETE, PUT, OPTIONS, etc) */
|
/* For CGI, allow DELETE, PUT, OPTIONS, etc too */
|
||||||
prequest = alloca(16);
|
prequest = alloca(16);
|
||||||
safe_strncpy((char*)prequest, iobuf, 16);
|
safe_strncpy((char*)prequest, iobuf, 16);
|
||||||
found:
|
found:
|
||||||
@ -2256,60 +2303,11 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
|||||||
if (strcasecmp(iobuf, "GET") != 0)
|
if (strcasecmp(iobuf, "GET") != 0)
|
||||||
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
|
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
|
||||||
#endif
|
#endif
|
||||||
// rfc2616: method and URI is separated by exactly one space
|
/* Copy URL to stack-allocated char[] */
|
||||||
//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[] */
|
|
||||||
urlcopy = alloca((HTTP_slash - urlp) + 2 + strlen(index_page));
|
urlcopy = alloca((HTTP_slash - urlp) + 2 + strlen(index_page));
|
||||||
/*if (urlcopy == NULL)
|
|
||||||
* send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);*/
|
|
||||||
strcpy(urlcopy, urlp);
|
strcpy(urlcopy, urlp);
|
||||||
/* NB: urlcopy ptr is never changed after this */
|
/* 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 */
|
/* Extract url args if present */
|
||||||
g_query = strchr(urlcopy, '?');
|
g_query = strchr(urlcopy, '?');
|
||||||
if (g_query)
|
if (g_query)
|
||||||
@ -2571,9 +2569,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
|||||||
send_headers_and_exit(HTTP_UNAUTHORIZED);
|
send_headers_and_exit(HTTP_UNAUTHORIZED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (found_moved_temporarily) {
|
if (found_moved_temporarily)
|
||||||
send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
|
send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
|
||||||
}
|
|
||||||
|
|
||||||
tptr = urlcopy + 1; /* skip first '/' */
|
tptr = urlcopy + 1; /* skip first '/' */
|
||||||
|
|
||||||
@ -2587,9 +2584,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (urlp[-1] == '/') {
|
if (urlp[-1] == '/')
|
||||||
strcpy(urlp, index_page);
|
strcpy(urlp, index_page);
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI
|
#if ENABLE_FEATURE_HTTPD_CGI
|
||||||
if (prequest != request_GET && prequest != request_HEAD) {
|
if (prequest != request_GET && prequest != request_HEAD) {
|
||||||
|
Loading…
Reference in New Issue
Block a user