aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-21 00:12:07 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-21 00:12:07 +0000
commit2f518b078b4d657b618589cce9a3d66edb5f31da (patch)
tree4a269736951c517cbd9baa17b2e449719833222b
parent081efd12325ed0b768d404e10f1ac749a90f8225 (diff)
downloadbusybox-w32-2f518b078b4d657b618589cce9a3d66edb5f31da.tar.gz
busybox-w32-2f518b078b4d657b618589cce9a3d66edb5f31da.tar.bz2
busybox-w32-2f518b078b4d657b618589cce9a3d66edb5f31da.zip
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
-rw-r--r--networking/httpd.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index bcd1126a6..5be53179f 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -340,7 +340,12 @@ enum {
340#define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1) 340#define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1)
341 341
342/* Prototypes */ 342/* Prototypes */
343static void send_file_and_exit(const char *url, int headers) ATTRIBUTE_NORETURN; 343enum {
344 SEND_HEADERS = (1 << 0),
345 SEND_BODY = (1 << 1),
346 SEND_HEADERS_AND_BODY = SEND_HEADERS + SEND_BODY,
347};
348static void send_file_and_exit(const char *url, int what) ATTRIBUTE_NORETURN;
344 349
345static void free_llist(has_next_ptr **pptr) 350static void free_llist(has_next_ptr **pptr)
346{ 351{
@@ -957,7 +962,7 @@ static void send_headers(int responseNum)
957 const char *infoString = NULL; 962 const char *infoString = NULL;
958 const char *mime_type; 963 const char *mime_type;
959#if ENABLE_FEATURE_HTTPD_ERROR_PAGES 964#if ENABLE_FEATURE_HTTPD_ERROR_PAGES
960 const char *error_page = 0; 965 const char *error_page = NULL;
961#endif 966#endif
962 unsigned i; 967 unsigned i;
963 time_t timer = time(0); 968 time_t timer = time(0);
@@ -1012,7 +1017,7 @@ static void send_headers(int responseNum)
1012 full_write(1, iobuf, len); 1017 full_write(1, iobuf, len);
1013 if (DEBUG) 1018 if (DEBUG)
1014 fprintf(stderr, "writing error page: '%s'\n", error_page); 1019 fprintf(stderr, "writing error page: '%s'\n", error_page);
1015 return send_file_and_exit(error_page, FALSE); 1020 return send_file_and_exit(error_page, SEND_BODY);
1016 } 1021 }
1017#endif 1022#endif
1018 1023
@@ -1480,10 +1485,10 @@ static void send_cgi_and_exit(
1480 * Send a file response to a HTTP request, and exit 1485 * Send a file response to a HTTP request, and exit
1481 * 1486 *
1482 * Parameters: 1487 * Parameters:
1483 * const char *url The requested URL (with leading /). 1488 * const char *url The requested URL (with leading /).
1484 * headers Don't send headers before if FALSE. 1489 * what What to send (headers/body/both).
1485 */ 1490 */
1486static void send_file_and_exit(const char *url, int headers) 1491static void send_file_and_exit(const char *url, int what)
1487{ 1492{
1488 static const char *const suffixTable[] = { 1493 static const char *const suffixTable[] = {
1489 /* Warning: shorter equivalent suffix in one line must be first */ 1494 /* 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)
1516 off_t offset; 1521 off_t offset;
1517#endif 1522#endif
1518 1523
1524 /* If you want to know about EPIPE below
1525 * (happens if you abort downloads from local httpd): */
1526 signal(SIGPIPE, SIG_IGN);
1527
1519 suffix = strrchr(url, '.'); 1528 suffix = strrchr(url, '.');
1520 1529
1521 /* If not found, set default as "application/octet-stream"; */ 1530 /* If not found, set default as "application/octet-stream"; */
@@ -1552,11 +1561,15 @@ static void send_file_and_exit(const char *url, int headers)
1552 if (f < 0) { 1561 if (f < 0) {
1553 if (DEBUG) 1562 if (DEBUG)
1554 bb_perror_msg("cannot open '%s'", url); 1563 bb_perror_msg("cannot open '%s'", url);
1555 if (headers) 1564 /* Error pages are sent by using send_file_and_exit(SEND_BODY).
1565 * IOW: it is unsafe to call send_headers_and_exit
1566 * if what is SEND_BODY! Can recurse! */
1567 if (what != SEND_BODY)
1556 send_headers_and_exit(HTTP_NOT_FOUND); 1568 send_headers_and_exit(HTTP_NOT_FOUND);
1569 log_and_exit();
1557 } 1570 }
1558#if ENABLE_FEATURE_HTTPD_RANGES 1571#if ENABLE_FEATURE_HTTPD_RANGES
1559 if (!headers) 1572 if (what == SEND_BODY)
1560 range_start = 0; /* err pages and ranges don't mix */ 1573 range_start = 0; /* err pages and ranges don't mix */
1561 range_len = MAXINT(off_t); 1574 range_len = MAXINT(off_t);
1562 if (range_start) { 1575 if (range_start) {
@@ -1571,18 +1584,14 @@ static void send_file_and_exit(const char *url, int headers)
1571 } else { 1584 } else {
1572 range_len = range_end - range_start + 1; 1585 range_len = range_end - range_start + 1;
1573 send_headers(HTTP_PARTIAL_CONTENT); 1586 send_headers(HTTP_PARTIAL_CONTENT);
1574 headers = 0; 1587 what = SEND_BODY;
1575 } 1588 }
1576 } 1589 }
1577#endif 1590#endif
1578 1591
1579 if (headers) 1592 if (what & SEND_HEADERS)
1580 send_headers(HTTP_OK); 1593 send_headers(HTTP_OK);
1581 1594
1582 /* If you want to know about EPIPE below
1583 * (happens if you abort downloads from local httpd): */
1584 signal(SIGPIPE, SIG_IGN);
1585
1586#if ENABLE_FEATURE_HTTPD_USE_SENDFILE 1595#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
1587 offset = range_start; 1596 offset = range_start;
1588 do { 1597 do {
@@ -1756,13 +1765,13 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) ATTRIBUTE
1756static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) 1765static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1757{ 1766{
1758 static const char request_GET[] ALIGN1 = "GET"; 1767 static const char request_GET[] ALIGN1 = "GET";
1759
1760 struct stat sb; 1768 struct stat sb;
1761 char *urlcopy; 1769 char *urlcopy;
1762 char *urlp; 1770 char *urlp;
1763 char *tptr; 1771 char *tptr;
1764 int ip_allowed; 1772 int ip_allowed;
1765#if ENABLE_FEATURE_HTTPD_CGI 1773#if ENABLE_FEATURE_HTTPD_CGI
1774 static const char request_HEAD[] ALIGN1 = "HEAD";
1766 const char *prequest; 1775 const char *prequest;
1767 char *cookie = NULL; 1776 char *cookie = NULL;
1768 char *content_type = NULL; 1777 char *content_type = NULL;
@@ -1827,9 +1836,12 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1827#if ENABLE_FEATURE_HTTPD_CGI 1836#if ENABLE_FEATURE_HTTPD_CGI
1828 prequest = request_GET; 1837 prequest = request_GET;
1829 if (strcasecmp(iobuf, prequest) != 0) { 1838 if (strcasecmp(iobuf, prequest) != 0) {
1830 prequest = "POST"; 1839 prequest = request_HEAD;
1831 if (strcasecmp(iobuf, prequest) != 0) 1840 if (strcasecmp(iobuf, prequest) != 0) {
1832 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 1841 prequest = "POST";
1842 if (strcasecmp(iobuf, prequest) != 0)
1843 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
1844 }
1833 } 1845 }
1834#else 1846#else
1835 if (strcasecmp(iobuf, request_GET) != 0) 1847 if (strcasecmp(iobuf, request_GET) != 0)
@@ -1964,17 +1976,14 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1964 /* Try and do our best to parse more lines */ 1976 /* Try and do our best to parse more lines */
1965 if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { 1977 if ((STRNCASECMP(iobuf, "Content-length:") == 0)) {
1966 /* extra read only for POST */ 1978 /* extra read only for POST */
1967 if (prequest != request_GET) { 1979 if (prequest != request_GET && prequest != request_HEAD) {
1968 tptr = iobuf + sizeof("Content-length:") - 1; 1980 tptr = iobuf + sizeof("Content-length:") - 1;
1969 if (!tptr[0]) 1981 if (!tptr[0])
1970 send_headers_and_exit(HTTP_BAD_REQUEST); 1982 send_headers_and_exit(HTTP_BAD_REQUEST);
1971 errno = 0;
1972 /* not using strtoul: it ignores leading minus! */ 1983 /* not using strtoul: it ignores leading minus! */
1973 length = strtol(tptr, &tptr, 10); 1984 length = bb_strtou(tptr, NULL, 10);
1974 /* length is "ulong", but we need to pass it to int later */ 1985 /* length is "ulong", but we need to pass it to int later */
1975 /* so we check for negative or too large values in one go: */ 1986 if (errno || length > INT_MAX)
1976 /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */
1977 if (tptr[0] || errno || length > INT_MAX)
1978 send_headers_and_exit(HTTP_BAD_REQUEST); 1987 send_headers_and_exit(HTTP_BAD_REQUEST);
1979 } 1988 }
1980 } 1989 }
@@ -2096,7 +2105,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2096 } 2105 }
2097 } 2106 }
2098#endif 2107#endif
2099 if (prequest != request_GET) { 2108 if (prequest != request_GET && prequest != request_HEAD) {
2100 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 2109 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
2101 } 2110 }
2102#endif /* FEATURE_HTTPD_CGI */ 2111#endif /* FEATURE_HTTPD_CGI */
@@ -2123,7 +2132,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2123 * } 2132 * }
2124 */ 2133 */
2125 2134
2126 send_file_and_exit(tptr, TRUE); 2135 send_file_and_exit(tptr,
2136 (prequest != request_HEAD ? SEND_HEADERS_AND_BODY : SEND_HEADERS));
2127} 2137}
2128 2138
2129/* 2139/*