svn commit: trunk/busybox/networking

vda at busybox.net vda at busybox.net
Sun Aug 12 21:05:49 UTC 2007


Author: vda
Date: 2007-08-12 14:05:49 -0700 (Sun, 12 Aug 2007)
New Revision: 19469

Log:
httpd: sendfile support



Modified:
   trunk/busybox/networking/Config.in
   trunk/busybox/networking/httpd.c


Changeset:
Modified: trunk/busybox/networking/Config.in
===================================================================
--- trunk/busybox/networking/Config.in	2007-08-12 20:59:07 UTC (rev 19468)
+++ trunk/busybox/networking/Config.in	2007-08-12 21:05:49 UTC (rev 19469)
@@ -83,6 +83,14 @@
 	help
 	  Serve web pages via an HTTP server.
 
+config FEATURE_HTTPD_USE_SENDFILE
+	bool "Use sendfile system call"
+	default n
+	depends on HTTPD
+	help
+	  When enabled, httpd will use the kernel sendfile() function
+	  instead of read/write loop.
+
 config FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
 	bool "Support reloading the global config file using hup signal"
 	default n

Modified: trunk/busybox/networking/httpd.c
===================================================================
--- trunk/busybox/networking/httpd.c	2007-08-12 20:59:07 UTC (rev 19468)
+++ trunk/busybox/networking/httpd.c	2007-08-12 21:05:49 UTC (rev 19469)
@@ -92,6 +92,9 @@
 */
 
 #include "libbb.h"
+#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
+#include <sys/sendfile.h>
+#endif
 
 /* amount of buffering in a pipe */
 #ifndef PIPE_BUF
@@ -922,15 +925,15 @@
 	len += 2;
 	if (infoString) {
 		len += sprintf(buf+len,
-				"<HEAD><TITLE>%d %s</TITLE></HEAD>\n"
-				"<BODY><H1>%d %s</H1>\n%s\n</BODY>\n",
+				"<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n"
+				"<BODY><H1>%d %s</H1>\n%s\n</BODY></HTML>\n",
 				responseNum, responseString,
 				responseNum, responseString, infoString);
 	}
 	if (DEBUG)
 		fprintf(stderr, "headers: '%s'\n", buf);
 	i = accepted_socket;
-	if (i == 0) i++; /* write to fd# 1 in inetd mode */
+	if (i == 0) i++; /* write to fd #1 in inetd mode */
 	return full_write(i, buf, len);
 }
 
@@ -1342,10 +1345,15 @@
  ****************************************************************************/
 static int sendFile(const char *url)
 {
-	char * suffix;
+	char *suffix;
 	int f;
+	int fd;
 	const char *const *table;
 	const char *try_suffix;
+	ssize_t count;
+#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
+	off_t offset = 0;
+#endif
 
 	suffix = strrchr(url, '.');
 
@@ -1360,7 +1368,6 @@
 #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
 	if (suffix) {
 		Htaccess * cur;
-
 		for (cur = mime_a; cur; cur = cur->next) {
 			if (strcmp(cur->before_colon, suffix) == 0) {
 				found_mime_type = cur->after_colon;
@@ -1375,26 +1382,37 @@
 			url, found_mime_type);
 
 	f = open(url, O_RDONLY);
-	if (f >= 0) {
-		int count;
-		char *buf = iobuf;
-
-		sendHeaders(HTTP_OK);
-		/* TODO: sendfile() */
-		while ((count = full_read(f, buf, MAX_MEMORY_BUFF)) > 0) {
-			int fd = accepted_socket;
-			if (fd == 0) fd++; /* write to fd# 1 in inetd mode */
-			if (full_write(fd, buf, count) != count)
-				break;
-		}
-		close(f);
-	} else {
+	if (f < 0) {
 		if (DEBUG)
 			bb_perror_msg("cannot open '%s'", url);
 		sendHeaders(HTTP_NOT_FOUND);
+		return 0;
 	}
 
+	sendHeaders(HTTP_OK);
+	fd = accepted_socket;
+	if (fd == 0)
+		fd++; /* write to fd #1 in inetd mode */
+#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
+	do {
+		count = sendfile(fd, f, &offset, MAXINT(ssize_t));
+		if (count < 0) {
+			if (offset == 0)
+				goto fallback;
+			bb_perror_msg("sendfile '%s'", url);
+		}
+	} while (count > 0);
+	close(f);
 	return 0;
+
+ fallback:
+#endif
+	while ((count = full_read(f, iobuf, MAX_MEMORY_BUFF)) > 0) {
+		if (full_write(fd, iobuf, count) != count)
+			break;
+	}
+	close(f);
+	return 0;
 }
 
 static int checkPermIP(void)
@@ -1689,11 +1707,11 @@
 				if ((STRNCASECMP(buf, "Content-length:") == 0)) {
 					/* extra read only for POST */
 					if (prequest != request_GET) {
-						test = buf + sizeof("Content-length:")-1;
+						test = buf + sizeof("Content-length:") - 1;
 						if (!test[0])
 							goto bail_out;
 						errno = 0;
-						/* not using strtoul: it ignores leading munis! */
+						/* not using strtoul: it ignores leading minus! */
 						length = strtol(test, &test, 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: */




More information about the busybox-cvs mailing list