svn commit: trunk/busybox/networking

vda at busybox.net vda at busybox.net
Thu Feb 21 00:12:08 UTC 2008


Author: vda
Date: 2008-02-20 16:12:07 -0800 (Wed, 20 Feb 2008)
New Revision: 21083

Log:
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



Modified:
   trunk/busybox/networking/httpd.c


Changeset:
Modified: trunk/busybox/networking/httpd.c
===================================================================
--- trunk/busybox/networking/httpd.c	2008-02-20 22:57:24 UTC (rev 21082)
+++ trunk/busybox/networking/httpd.c	2008-02-21 00:12:07 UTC (rev 21083)
@@ -340,7 +340,12 @@
 #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 @@
 	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 @@
 		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 @@
  * 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 @@
 	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 @@
 	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 @@
 		} 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)
 {
 	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 @@
 #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 @@
 			/* 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 @@
 		}
 	}
 #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 @@
 	 * }
 	 */
 
-	send_file_and_exit(tptr, TRUE);
+	send_file_and_exit(tptr,
+		(prequest != request_HEAD ? SEND_HEADERS_AND_BODY : SEND_HEADERS));
 }
 
 /*




More information about the busybox-cvs mailing list