diff options
author | Alexander Sack <asac@pantacor.com> | 2021-05-04 07:41:50 +0000 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-05-04 19:20:50 +0200 |
commit | 36e932abdfd79f55fdded4142d10319ba843839e (patch) | |
tree | cf6978ea1876dac09e9e5d2b2c37e96a6e8abee1 | |
parent | 8e71f2aab8f9f893be7741af21a7c689cf165c66 (diff) | |
download | busybox-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.c | 85 |
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 | ||
347 | typedef enum CGI_type { | ||
348 | CGI_NONE = 0, | ||
349 | CGI_NORMAL, | ||
350 | CGI_INDEX, | ||
351 | CGI_INTERPRETER, | ||
352 | } CGI_type; | ||
353 | |||
354 | enum { | 347 | enum { |
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) | |||
2174 | static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) NORETURN; | 2167 | static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) NORETURN; |
2175 | static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | 2168 | static 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 | } |