mirror of https://github.com/mirror/busybox.git
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>pull/18/merge
parent
8e71f2aab8
commit
36e932abdf
|
@ -344,13 +344,6 @@ typedef struct Htaccess_Proxy {
|
||||||
char *url_to;
|
char *url_to;
|
||||||
} Htaccess_Proxy;
|
} Htaccess_Proxy;
|
||||||
|
|
||||||
typedef enum CGI_type {
|
|
||||||
CGI_NONE = 0,
|
|
||||||
CGI_NORMAL,
|
|
||||||
CGI_INDEX,
|
|
||||||
CGI_INTERPRETER,
|
|
||||||
} CGI_type;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HTTP_OK = 200,
|
HTTP_OK = 200,
|
||||||
HTTP_PARTIAL_CONTENT = 206,
|
HTTP_PARTIAL_CONTENT = 206,
|
||||||
|
@ -2174,7 +2167,6 @@ static void send_REQUEST_TIMEOUT_and_exit(int sig UNUSED_PARAM)
|
||||||
static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) NORETURN;
|
static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) NORETURN;
|
||||||
static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
{
|
{
|
||||||
static const char request_GET[] ALIGN1 = "GET";
|
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
char *urlcopy;
|
char *urlcopy;
|
||||||
char *urlp;
|
char *urlp;
|
||||||
|
@ -2186,13 +2178,17 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
unsigned total_headers_len;
|
unsigned total_headers_len;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI
|
#if ENABLE_FEATURE_HTTPD_CGI
|
||||||
|
static const char request_GET[] ALIGN1 = "GET";
|
||||||
static const char request_HEAD[] ALIGN1 = "HEAD";
|
static const char request_HEAD[] ALIGN1 = "HEAD";
|
||||||
|
static const char request_POST[] ALIGN1 = "POST";
|
||||||
const char *prequest;
|
const char *prequest;
|
||||||
unsigned long length = 0;
|
unsigned long POST_length;
|
||||||
enum CGI_type cgi_type = CGI_NONE;
|
enum CGI_type {
|
||||||
#elif ENABLE_FEATURE_HTTPD_PROXY
|
CGI_NONE = 0,
|
||||||
#define prequest request_GET
|
CGI_NORMAL,
|
||||||
unsigned long length = 0;
|
CGI_INDEX,
|
||||||
|
CGI_INTERPRETER,
|
||||||
|
} cgi_type = CGI_NONE;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
|
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
|
||||||
smallint authorized = -1;
|
smallint authorized = -1;
|
||||||
|
@ -2235,7 +2231,7 @@ 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) */
|
/* Determine type of request (GET/POST/...) */
|
||||||
// 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, ' ');
|
||||||
|
@ -2244,16 +2240,20 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
*urlp++ = '\0';
|
*urlp++ = '\0';
|
||||||
#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)
|
||||||
|
goto found;
|
||||||
prequest = request_HEAD;
|
prequest = request_HEAD;
|
||||||
if (strcasecmp(iobuf, prequest) != 0) {
|
if (strcasecmp(iobuf, prequest) == 0)
|
||||||
prequest = "POST";
|
goto found;
|
||||||
if (strcasecmp(iobuf, prequest) != 0)
|
prequest = request_POST;
|
||||||
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
|
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
|
#else
|
||||||
if (strcasecmp(iobuf, request_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
|
// 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)
|
||||||
* to http://hostname[:port]/new/pathSFX
|
* to http://hostname[:port]/new/pathSFX
|
||||||
*/
|
*/
|
||||||
fdprintf(proxy_fd, "%s %s%s %s\r\n",
|
fdprintf(proxy_fd, "%s %s%s %s\r\n",
|
||||||
prequest, /* "GET" or "POST" */
|
iobuf, /* "GET" / "POST" / etc */
|
||||||
proxy_entry->url_to, /* "/new/path" */
|
proxy_entry->url_to, /* "/new/path" */
|
||||||
urlcopy + strlen(proxy_entry->url_from), /* "SFX" */
|
urlcopy + strlen(proxy_entry->url_from), /* "SFX" */
|
||||||
HTTP_slash /* "HTTP/xyz" */
|
HTTP_slash /* "HTTP/xyz" */
|
||||||
|
@ -2328,7 +2328,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
/* Algorithm stolen from libbb bb_simplify_path(),
|
/* Algorithm stolen from libbb bb_simplify_path(),
|
||||||
* but don't strdup, retain trailing slash, protect root */
|
* but don't strdup, retain trailing slash, protect root */
|
||||||
urlp = tptr = urlcopy;
|
urlp = tptr = urlcopy;
|
||||||
for (;;) {
|
while (1) {
|
||||||
if (*urlp == '/') {
|
if (*urlp == '/') {
|
||||||
/* skip duplicate (or initial) slash */
|
/* skip duplicate (or initial) slash */
|
||||||
if (*tptr == '/') {
|
if (*tptr == '/') {
|
||||||
|
@ -2435,6 +2435,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
|
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI
|
#if ENABLE_FEATURE_HTTPD_CGI
|
||||||
total_headers_len = 0;
|
total_headers_len = 0;
|
||||||
|
POST_length = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Read until blank line */
|
/* Read until blank line */
|
||||||
|
@ -2450,24 +2451,17 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
#endif
|
#endif
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
bb_error_msg("header: '%s'", iobuf);
|
bb_error_msg("header: '%s'", iobuf);
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY
|
|
||||||
/* Try and do our best to parse more lines */
|
|
||||||
if (STRNCASECMP(iobuf, "Content-Length:") == 0) {
|
|
||||||
/* extra read only for POST */
|
|
||||||
if (prequest != request_GET
|
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI
|
#if ENABLE_FEATURE_HTTPD_CGI
|
||||||
&& prequest != request_HEAD
|
/* Only POST needs to know POST_length */
|
||||||
# endif
|
if (prequest == request_POST && STRNCASECMP(iobuf, "Content-Length:") == 0) {
|
||||||
) {
|
|
||||||
tptr = skip_whitespace(iobuf + sizeof("Content-Length:") - 1);
|
tptr = skip_whitespace(iobuf + sizeof("Content-Length:") - 1);
|
||||||
if (!tptr[0])
|
if (!tptr[0])
|
||||||
send_headers_and_exit(HTTP_BAD_REQUEST);
|
send_headers_and_exit(HTTP_BAD_REQUEST);
|
||||||
/* not using strtoul: it ignores leading minus! */
|
/* not using strtoul: it ignores leading minus! */
|
||||||
length = bb_strtou(tptr, NULL, 10);
|
POST_length = bb_strtou(tptr, NULL, 10);
|
||||||
/* length is "ulong", but we need to pass it to int later */
|
/* length is "ulong", but we need to pass it to int later */
|
||||||
if (errno || length > INT_MAX)
|
if (errno || POST_length > INT_MAX)
|
||||||
send_headers_and_exit(HTTP_BAD_REQUEST);
|
send_headers_and_exit(HTTP_BAD_REQUEST);
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2588,7 +2582,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
send_cgi_and_exit(
|
send_cgi_and_exit(
|
||||||
(cgi_type == CGI_INDEX) ? "/cgi-bin/index.cgi"
|
(cgi_type == CGI_INDEX) ? "/cgi-bin/index.cgi"
|
||||||
/*CGI_NORMAL or CGI_INTERPRETER*/ : urlcopy,
|
/*CGI_NORMAL or CGI_INTERPRETER*/ : urlcopy,
|
||||||
urlcopy, prequest, length
|
urlcopy, prequest, POST_length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2599,13 +2593,14 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
|
||||||
|
|
||||||
#if ENABLE_FEATURE_HTTPD_CGI
|
#if ENABLE_FEATURE_HTTPD_CGI
|
||||||
if (prequest != request_GET && prequest != request_HEAD) {
|
if (prequest != request_GET && prequest != request_HEAD) {
|
||||||
/* POST for files does not make sense */
|
/* POST / DELETE / PUT / OPTIONS for files do not make sense */
|
||||||
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
|
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
send_file_and_exit(tptr,
|
send_file_and_exit(tptr,
|
||||||
(prequest != request_HEAD ? SEND_HEADERS_AND_BODY : SEND_HEADERS)
|
(prequest != request_HEAD ? SEND_HEADERS_AND_BODY : SEND_HEADERS)
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
|
/* It was verified earlier that it is a "GET" */
|
||||||
send_file_and_exit(tptr, SEND_HEADERS_AND_BODY);
|
send_file_and_exit(tptr, SEND_HEADERS_AND_BODY);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue