httpd: sendfile support

This commit is contained in:
Denis Vlasenko 2007-08-12 21:05:49 +00:00
parent ff65cd469b
commit 1b9064d535
2 changed files with 47 additions and 21 deletions

View File

@ -83,6 +83,14 @@ config HTTPD
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

View File

@ -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 @@ static int sendHeaders(HttpResponseNum responseNum)
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 sendCgi(const char *url,
****************************************************************************/
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 @@ static int sendFile(const char *url)
#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,25 +1382,36 @@ static int sendFile(const char *url)
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;
}
@ -1689,11 +1707,11 @@ static void handleIncoming(void)
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: */