httpd: "HEAD" support. Closes bug 1530.

send_file_and_exit                                   629     645     +16
static.request_HEAD                                    -       5      +5
handle_incoming_and_exit                            2732    2737      +5
send_headers                                         594     597      +3
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 3/0 up/down: 29/0)               Total: 29 bytes
   text    data     bss     dec     hex filename
 796283     740    7484  804507   c469b busybox_old
 796312     740    7484  804536   c46b8 busybox_unstripped
This commit is contained in:
Denis Vlasenko 2008-02-21 00:12:07 +00:00
parent 081efd1232
commit 2f518b078b

View File

@ -340,7 +340,12 @@ enum {
#define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1)
/* Prototypes */
static void send_file_and_exit(const char *url, int headers) ATTRIBUTE_NORETURN;
enum {
SEND_HEADERS = (1 << 0),
SEND_BODY = (1 << 1),
SEND_HEADERS_AND_BODY = SEND_HEADERS + SEND_BODY,
};
static void send_file_and_exit(const char *url, int what) ATTRIBUTE_NORETURN;
static void free_llist(has_next_ptr **pptr)
{
@ -957,7 +962,7 @@ static void send_headers(int responseNum)
const char *infoString = NULL;
const char *mime_type;
#if ENABLE_FEATURE_HTTPD_ERROR_PAGES
const char *error_page = 0;
const char *error_page = NULL;
#endif
unsigned i;
time_t timer = time(0);
@ -1012,7 +1017,7 @@ static void send_headers(int responseNum)
full_write(1, iobuf, len);
if (DEBUG)
fprintf(stderr, "writing error page: '%s'\n", error_page);
return send_file_and_exit(error_page, FALSE);
return send_file_and_exit(error_page, SEND_BODY);
}
#endif
@ -1480,10 +1485,10 @@ static void send_cgi_and_exit(
* Send a file response to a HTTP request, and exit
*
* Parameters:
* const char *url The requested URL (with leading /).
* headers Don't send headers before if FALSE.
* const char *url The requested URL (with leading /).
* what What to send (headers/body/both).
*/
static void send_file_and_exit(const char *url, int headers)
static void send_file_and_exit(const char *url, int what)
{
static const char *const suffixTable[] = {
/* Warning: shorter equivalent suffix in one line must be first */
@ -1516,6 +1521,10 @@ static void send_file_and_exit(const char *url, int headers)
off_t offset;
#endif
/* If you want to know about EPIPE below
* (happens if you abort downloads from local httpd): */
signal(SIGPIPE, SIG_IGN);
suffix = strrchr(url, '.');
/* If not found, set default as "application/octet-stream"; */
@ -1552,11 +1561,15 @@ static void send_file_and_exit(const char *url, int headers)
if (f < 0) {
if (DEBUG)
bb_perror_msg("cannot open '%s'", url);
if (headers)
/* Error pages are sent by using send_file_and_exit(SEND_BODY).
* IOW: it is unsafe to call send_headers_and_exit
* if what is SEND_BODY! Can recurse! */
if (what != SEND_BODY)
send_headers_and_exit(HTTP_NOT_FOUND);
log_and_exit();
}
#if ENABLE_FEATURE_HTTPD_RANGES
if (!headers)
if (what == SEND_BODY)
range_start = 0; /* err pages and ranges don't mix */
range_len = MAXINT(off_t);
if (range_start) {
@ -1571,18 +1584,14 @@ static void send_file_and_exit(const char *url, int headers)
} else {
range_len = range_end - range_start + 1;
send_headers(HTTP_PARTIAL_CONTENT);
headers = 0;
what = SEND_BODY;
}
}
#endif
if (headers)
if (what & SEND_HEADERS)
send_headers(HTTP_OK);
/* If you want to know about EPIPE below
* (happens if you abort downloads from local httpd): */
signal(SIGPIPE, SIG_IGN);
#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
offset = range_start;
do {
@ -1756,13 +1765,13 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) ATTRIBUTE
static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
{
static const char request_GET[] ALIGN1 = "GET";
struct stat sb;
char *urlcopy;
char *urlp;
char *tptr;
int ip_allowed;
#if ENABLE_FEATURE_HTTPD_CGI
static const char request_HEAD[] ALIGN1 = "HEAD";
const char *prequest;
char *cookie = NULL;
char *content_type = NULL;
@ -1827,9 +1836,12 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
#if ENABLE_FEATURE_HTTPD_CGI
prequest = request_GET;
if (strcasecmp(iobuf, prequest) != 0) {
prequest = "POST";
if (strcasecmp(iobuf, prequest) != 0)
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
prequest = request_HEAD;
if (strcasecmp(iobuf, prequest) != 0) {
prequest = "POST";
if (strcasecmp(iobuf, prequest) != 0)
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
}
}
#else
if (strcasecmp(iobuf, request_GET) != 0)
@ -1964,17 +1976,14 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
/* 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 (prequest != request_GET && prequest != request_HEAD) {
tptr = iobuf + sizeof("Content-length:") - 1;
if (!tptr[0])
send_headers_and_exit(HTTP_BAD_REQUEST);
errno = 0;
/* not using strtoul: it ignores leading minus! */
length = strtol(tptr, &tptr, 10);
length = bb_strtou(tptr, NULL, 10);
/* length is "ulong", but we need to pass it to int later */
/* so we check for negative or too large values in one go: */
/* (long -> ulong conv caused negatives to be seen as > INT_MAX) */
if (tptr[0] || errno || length > INT_MAX)
if (errno || length > INT_MAX)
send_headers_and_exit(HTTP_BAD_REQUEST);
}
}
@ -2096,7 +2105,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
}
}
#endif
if (prequest != request_GET) {
if (prequest != request_GET && prequest != request_HEAD) {
send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
}
#endif /* FEATURE_HTTPD_CGI */
@ -2123,7 +2132,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
* }
*/
send_file_and_exit(tptr, TRUE);
send_file_and_exit(tptr,
(prequest != request_HEAD ? SEND_HEADERS_AND_BODY : SEND_HEADERS));
}
/*