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:
		| @@ -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,36 +2234,16 @@ 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'; | ||||||
| #if ENABLE_FEATURE_HTTPD_CGI |  | ||||||
| 	prequest = request_GET; |  | ||||||
| 	if (strcasecmp(iobuf, prequest) == 0) |  | ||||||
| 		goto found; |  | ||||||
| 	prequest = request_HEAD; |  | ||||||
| 	if (strcasecmp(iobuf, prequest) == 0) |  | ||||||
| 		goto found; |  | ||||||
| 	prequest = request_POST; |  | ||||||
| 	if (strcasecmp(iobuf, prequest) == 0) |  | ||||||
| 		goto found; |  | ||||||
| 	/* For CGI, allow other requests too (DELETE, PUT, OPTIONS, etc) */ |  | ||||||
| 	prequest = alloca(16); |  | ||||||
| 	safe_strncpy((char*)prequest, iobuf, 16); |  | ||||||
|  found: |  | ||||||
| #else |  | ||||||
| 	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 | 	//urlp = skip_whitespace(urlp); - should not be necessary | ||||||
| 	if (urlp[0] != '/') | 	if (urlp[0] != '/') | ||||||
| 		send_headers_and_exit(HTTP_BAD_REQUEST); | 		send_headers_and_exit(HTTP_BAD_REQUEST); | ||||||
|  |  | ||||||
| 	/* Find end of URL */ | 	/* Find end of URL */ | ||||||
| 	HTTP_slash = strchr(urlp, ' '); | 	HTTP_slash = strchr(urlp, ' '); | ||||||
| 	/* Is it " HTTP/"? */ | 	/* Is it " HTTP/"? */ | ||||||
| @@ -2268,22 +2251,14 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||||||
| 		send_headers_and_exit(HTTP_BAD_REQUEST); | 		send_headers_and_exit(HTTP_BAD_REQUEST); | ||||||
| 	*HTTP_slash++ = '\0'; | 	*HTTP_slash++ = '\0'; | ||||||
|  |  | ||||||
| 	/* Copy URL from after "GET "/"POST " 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 | #if ENABLE_FEATURE_HTTPD_PROXY | ||||||
| 	{ | 	proxy_entry = find_proxy_entry(urlp); | ||||||
|  | 	if (proxy_entry) { | ||||||
| 		int proxy_fd; | 		int proxy_fd; | ||||||
| 		len_and_sockaddr *lsa; | 		len_and_sockaddr *lsa; | ||||||
| 		Htaccess_Proxy *proxy_entry = find_proxy_entry(urlcopy); |  | ||||||
|  |  | ||||||
| 		if (proxy_entry) { |  | ||||||
| 		if (verbose > 1) | 		if (verbose > 1) | ||||||
| 				bb_error_msg("proxy:%s", urlcopy); | 			bb_error_msg("proxy:%s", urlp); | ||||||
| 		lsa = host2sockaddr(proxy_entry->host_port, 80); | 		lsa = host2sockaddr(proxy_entry->host_port, 80); | ||||||
| 		if (!lsa) | 		if (!lsa) | ||||||
| 			send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | 			send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | ||||||
| @@ -2302,14 +2277,37 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||||||
| 		fdprintf(proxy_fd, "%s %s%s %s\r\n", | 		fdprintf(proxy_fd, "%s %s%s %s\r\n", | ||||||
| 				iobuf, /* "GET" / "POST" / etc */ | 				iobuf, /* "GET" / "POST" / etc */ | ||||||
| 				proxy_entry->url_to, /* "/new/path" */ | 				proxy_entry->url_to, /* "/new/path" */ | ||||||
| 					urlcopy + strlen(proxy_entry->url_from), /* "SFX" */ | 				urlp + strlen(proxy_entry->url_from), /* "SFX" */ | ||||||
| 				HTTP_slash /* "HTTP/xyz" */ | 				HTTP_slash /* "HTTP/xyz" */ | ||||||
| 		); | 		); | ||||||
| 		cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX); | 		cgi_io_loop_and_exit(proxy_fd, proxy_fd, /*max POST length:*/ INT_MAX); | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | 	/* Determine type of request (GET/POST/...) */ | ||||||
|  | #if ENABLE_FEATURE_HTTPD_CGI | ||||||
|  | 	prequest = request_GET; | ||||||
|  | 	if (strcasecmp(iobuf, prequest) == 0) | ||||||
|  | 		goto found; | ||||||
|  | 	prequest = request_HEAD; | ||||||
|  | 	if (strcasecmp(iobuf, prequest) == 0) | ||||||
|  | 		goto found; | ||||||
|  | 	prequest = request_POST; | ||||||
|  | 	if (strcasecmp(iobuf, prequest) == 0) | ||||||
|  | 		goto found; | ||||||
|  | 	/* For CGI, allow DELETE, PUT, OPTIONS, etc too */ | ||||||
|  | 	prequest = alloca(16); | ||||||
|  | 	safe_strncpy((char*)prequest, iobuf, 16); | ||||||
|  |  found: | ||||||
|  | #else | ||||||
|  | 	if (strcasecmp(iobuf, "GET") != 0) | ||||||
|  | 		send_headers_and_exit(HTTP_NOT_IMPLEMENTED); | ||||||
|  | #endif | ||||||
|  | 	/* Copy URL to stack-allocated char[] */ | ||||||
|  | 	urlcopy = alloca((HTTP_slash - urlp) + 2 + strlen(index_page)); | ||||||
|  | 	strcpy(urlcopy, urlp); | ||||||
|  | 	/* NB: urlcopy ptr is never changed after this */ | ||||||
|  |  | ||||||
| 	/* 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) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user