aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Sack <asac@pantacor.com>2021-05-04 07:41:50 +0000
committerDenys Vlasenko <vda.linux@googlemail.com>2021-05-04 19:20:50 +0200
commit36e932abdfd79f55fdded4142d10319ba843839e (patch)
treecf6978ea1876dac09e9e5d2b2c37e96a6e8abee1
parent8e71f2aab8f9f893be7741af21a7c689cf165c66 (diff)
downloadbusybox-w32-36e932abdfd79f55fdded4142d10319ba843839e.tar.gz
busybox-w32-36e932abdfd79f55fdded4142d10319ba843839e.tar.bz2
busybox-w32-36e932abdfd79f55fdded4142d10319ba843839e.zip
httpd: cgi-bin support for DELETE, PUT, OPTIONS etc methods
function old new delta handle_incoming_and_exit 2217 2240 +23 static.request_POST - 5 +5 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/0 up/down: 28/0) Total: 28 bytes Signed-off-by: Alexander Sack <asac@pantacor.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/httpd.c85
1 files changed, 40 insertions, 45 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index e6757d943..09e19dc29 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -344,13 +344,6 @@ typedef struct Htaccess_Proxy {
344 char *url_to; 344 char *url_to;
345} Htaccess_Proxy; 345} Htaccess_Proxy;
346 346
347typedef enum CGI_type {
348 CGI_NONE = 0,
349 CGI_NORMAL,
350 CGI_INDEX,
351 CGI_INTERPRETER,
352} CGI_type;
353
354enum { 347enum {
355 HTTP_OK = 200, 348 HTTP_OK = 200,
356 HTTP_PARTIAL_CONTENT = 206, 349 HTTP_PARTIAL_CONTENT = 206,
@@ -2174,7 +2167,6 @@ static void send_REQUEST_TIMEOUT_and_exit(int sig UNUSED_PARAM)
2174static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) NORETURN; 2167static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) NORETURN;
2175static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) 2168static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2176{ 2169{
2177 static const char request_GET[] ALIGN1 = "GET";
2178 struct stat sb; 2170 struct stat sb;
2179 char *urlcopy; 2171 char *urlcopy;
2180 char *urlp; 2172 char *urlp;
@@ -2186,13 +2178,17 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2186 unsigned total_headers_len; 2178 unsigned total_headers_len;
2187#endif 2179#endif
2188#if ENABLE_FEATURE_HTTPD_CGI 2180#if ENABLE_FEATURE_HTTPD_CGI
2181 static const char request_GET[] ALIGN1 = "GET";
2189 static const char request_HEAD[] ALIGN1 = "HEAD"; 2182 static const char request_HEAD[] ALIGN1 = "HEAD";
2183 static const char request_POST[] ALIGN1 = "POST";
2190 const char *prequest; 2184 const char *prequest;
2191 unsigned long length = 0; 2185 unsigned long POST_length;
2192 enum CGI_type cgi_type = CGI_NONE; 2186 enum CGI_type {
2193#elif ENABLE_FEATURE_HTTPD_PROXY 2187 CGI_NONE = 0,
2194#define prequest request_GET 2188 CGI_NORMAL,
2195 unsigned long length = 0; 2189 CGI_INDEX,
2190 CGI_INTERPRETER,
2191 } cgi_type = CGI_NONE;
2196#endif 2192#endif
2197#if ENABLE_FEATURE_HTTPD_BASIC_AUTH 2193#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
2198 smallint authorized = -1; 2194 smallint authorized = -1;
@@ -2235,7 +2231,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2235 if (!get_line()) /* EOF or error or empty line */ 2231 if (!get_line()) /* EOF or error or empty line */
2236 send_headers_and_exit(HTTP_BAD_REQUEST); 2232 send_headers_and_exit(HTTP_BAD_REQUEST);
2237 2233
2238 /* Determine type of request (GET/POST) */ 2234 /* Determine type of request (GET/POST/...) */
2239 // rfc2616: method and URI is separated by exactly one space 2235 // rfc2616: method and URI is separated by exactly one space
2240 //urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed 2236 //urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed
2241 urlp = strchr(iobuf, ' '); 2237 urlp = strchr(iobuf, ' ');
@@ -2244,16 +2240,20 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2244 *urlp++ = '\0'; 2240 *urlp++ = '\0';
2245#if ENABLE_FEATURE_HTTPD_CGI 2241#if ENABLE_FEATURE_HTTPD_CGI
2246 prequest = request_GET; 2242 prequest = request_GET;
2247 if (strcasecmp(iobuf, prequest) != 0) { 2243 if (strcasecmp(iobuf, prequest) == 0)
2248 prequest = request_HEAD; 2244 goto found;
2249 if (strcasecmp(iobuf, prequest) != 0) { 2245 prequest = request_HEAD;
2250 prequest = "POST"; 2246 if (strcasecmp(iobuf, prequest) == 0)
2251 if (strcasecmp(iobuf, prequest) != 0) 2247 goto found;
2252 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 2248 prequest = request_POST;
2253 } 2249 if (strcasecmp(iobuf, prequest) == 0)
2254 } 2250 goto found;
2251 /* For CGI, allow other requests too (DELETE, PUT, OPTIONS, etc) */
2252 prequest = alloca(16);
2253 safe_strncpy((char*)prequest, iobuf, 16);
2254 found:
2255#else 2255#else
2256 if (strcasecmp(iobuf, request_GET) != 0) 2256 if (strcasecmp(iobuf, "GET") != 0)
2257 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 2257 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
2258#endif 2258#endif
2259 // rfc2616: method and URI is separated by exactly one space 2259 // rfc2616: method and URI is separated by exactly one space
@@ -2300,7 +2300,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2300 * to http://hostname[:port]/new/pathSFX 2300 * to http://hostname[:port]/new/pathSFX
2301 */ 2301 */
2302 fdprintf(proxy_fd, "%s %s%s %s\r\n", 2302 fdprintf(proxy_fd, "%s %s%s %s\r\n",
2303 prequest, /* "GET" or "POST" */ 2303 iobuf, /* "GET" / "POST" / etc */
2304 proxy_entry->url_to, /* "/new/path" */ 2304 proxy_entry->url_to, /* "/new/path" */
2305 urlcopy + strlen(proxy_entry->url_from), /* "SFX" */ 2305 urlcopy + strlen(proxy_entry->url_from), /* "SFX" */
2306 HTTP_slash /* "HTTP/xyz" */ 2306 HTTP_slash /* "HTTP/xyz" */
@@ -2328,7 +2328,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2328 /* Algorithm stolen from libbb bb_simplify_path(), 2328 /* Algorithm stolen from libbb bb_simplify_path(),
2329 * but don't strdup, retain trailing slash, protect root */ 2329 * but don't strdup, retain trailing slash, protect root */
2330 urlp = tptr = urlcopy; 2330 urlp = tptr = urlcopy;
2331 for (;;) { 2331 while (1) {
2332 if (*urlp == '/') { 2332 if (*urlp == '/') {
2333 /* skip duplicate (or initial) slash */ 2333 /* skip duplicate (or initial) slash */
2334 if (*tptr == '/') { 2334 if (*tptr == '/') {
@@ -2435,6 +2435,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2435 2435
2436#if ENABLE_FEATURE_HTTPD_CGI 2436#if ENABLE_FEATURE_HTTPD_CGI
2437 total_headers_len = 0; 2437 total_headers_len = 0;
2438 POST_length = 0;
2438#endif 2439#endif
2439 2440
2440 /* Read until blank line */ 2441 /* Read until blank line */
@@ -2450,24 +2451,17 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2450#endif 2451#endif
2451 if (DEBUG) 2452 if (DEBUG)
2452 bb_error_msg("header: '%s'", iobuf); 2453 bb_error_msg("header: '%s'", iobuf);
2453#if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY 2454#if ENABLE_FEATURE_HTTPD_CGI
2454 /* Try and do our best to parse more lines */ 2455 /* Only POST needs to know POST_length */
2455 if (STRNCASECMP(iobuf, "Content-Length:") == 0) { 2456 if (prequest == request_POST && STRNCASECMP(iobuf, "Content-Length:") == 0) {
2456 /* extra read only for POST */ 2457 tptr = skip_whitespace(iobuf + sizeof("Content-Length:") - 1);
2457 if (prequest != request_GET 2458 if (!tptr[0])
2458# if ENABLE_FEATURE_HTTPD_CGI 2459 send_headers_and_exit(HTTP_BAD_REQUEST);
2459 && prequest != request_HEAD 2460 /* not using strtoul: it ignores leading minus! */
2460# endif 2461 POST_length = bb_strtou(tptr, NULL, 10);
2461 ) { 2462 /* length is "ulong", but we need to pass it to int later */
2462 tptr = skip_whitespace(iobuf + sizeof("Content-Length:") - 1); 2463 if (errno || POST_length > INT_MAX)
2463 if (!tptr[0]) 2464 send_headers_and_exit(HTTP_BAD_REQUEST);
2464 send_headers_and_exit(HTTP_BAD_REQUEST);
2465 /* not using strtoul: it ignores leading minus! */
2466 length = bb_strtou(tptr, NULL, 10);
2467 /* length is "ulong", but we need to pass it to int later */
2468 if (errno || length > INT_MAX)
2469 send_headers_and_exit(HTTP_BAD_REQUEST);
2470 }
2471 continue; 2465 continue;
2472 } 2466 }
2473#endif 2467#endif
@@ -2588,7 +2582,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2588 send_cgi_and_exit( 2582 send_cgi_and_exit(
2589 (cgi_type == CGI_INDEX) ? "/cgi-bin/index.cgi" 2583 (cgi_type == CGI_INDEX) ? "/cgi-bin/index.cgi"
2590 /*CGI_NORMAL or CGI_INTERPRETER*/ : urlcopy, 2584 /*CGI_NORMAL or CGI_INTERPRETER*/ : urlcopy,
2591 urlcopy, prequest, length 2585 urlcopy, prequest, POST_length
2592 ); 2586 );
2593 } 2587 }
2594#endif 2588#endif
@@ -2599,13 +2593,14 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2599 2593
2600#if ENABLE_FEATURE_HTTPD_CGI 2594#if ENABLE_FEATURE_HTTPD_CGI
2601 if (prequest != request_GET && prequest != request_HEAD) { 2595 if (prequest != request_GET && prequest != request_HEAD) {
2602 /* POST for files does not make sense */ 2596 /* POST / DELETE / PUT / OPTIONS for files do not make sense */
2603 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 2597 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
2604 } 2598 }
2605 send_file_and_exit(tptr, 2599 send_file_and_exit(tptr,
2606 (prequest != request_HEAD ? SEND_HEADERS_AND_BODY : SEND_HEADERS) 2600 (prequest != request_HEAD ? SEND_HEADERS_AND_BODY : SEND_HEADERS)
2607 ); 2601 );
2608#else 2602#else
2603 /* It was verified earlier that it is a "GET" */
2609 send_file_and_exit(tptr, SEND_HEADERS_AND_BODY); 2604 send_file_and_exit(tptr, SEND_HEADERS_AND_BODY);
2610#endif 2605#endif
2611} 2606}