diff options
Diffstat (limited to 'networking')
-rw-r--r-- | networking/Config.in | 16 | ||||
-rw-r--r-- | networking/httpd.c | 157 |
2 files changed, 56 insertions, 117 deletions
diff --git a/networking/Config.in b/networking/Config.in index b3d07e6..af160e7 100644 --- a/networking/Config.in +++ b/networking/Config.in @@ -141,14 +141,6 @@ config FEATURE_HTTPD_USE_SENDFILE When enabled, httpd will use the kernel sendfile() function instead of read/write loop. -config FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP - bool "Support reloading of global config file on HUP signal" - default n - depends on HTTPD - help - This option enables processing of SIGHUP to reload cached - configuration settings. - config FEATURE_HTTPD_SETUID bool "Enable -u <user> option" default n @@ -175,14 +167,6 @@ config FEATURE_HTTPD_AUTH_MD5 Enables basic per URL authentication from /etc/httpd.conf using md5 passwords. -config FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES - bool "Support loading additional MIME types at run-time" - default n - depends on HTTPD - help - This option enables support for additional MIME types at - run-time to be specified in the configuration file. - config FEATURE_HTTPD_CGI bool "Support Common Gateway Interface (CGI)" default y diff --git a/networking/httpd.c b/networking/httpd.c index fc8b512..66ce1e1 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -97,7 +97,7 @@ #include "libbb.h" #if ENABLE_FEATURE_HTTPD_USE_SENDFILE -#include <sys/sendfile.h> +# include <sys/sendfile.h> #endif //#define DEBUG 1 @@ -268,9 +268,7 @@ struct globals { #if ENABLE_FEATURE_HTTPD_BASIC_AUTH Htaccess *g_auth; /* config user:password lines */ #endif -#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES Htaccess *mime_a; /* config mime types */ -#endif #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR Htaccess *script_i; /* config script interpreters */ #endif @@ -310,6 +308,12 @@ struct globals { #define range_start (G.range_start ) #define range_end (G.range_end ) #define range_len (G.range_len ) +#else +enum { + range_start = 0, + range_end = MAXINT(off_t) - 1, + range_len = MAXINT(off_t), +}; #endif #define rmt_ip_str (G.rmt_ip_str ) #define g_auth (G.g_auth ) @@ -328,14 +332,6 @@ struct globals { file_size = -1; \ } while (0) -#if !ENABLE_FEATURE_HTTPD_RANGES -enum { - range_start = 0, - range_end = MAXINT(off_t) - 1, - range_len = MAXINT(off_t), -}; -#endif - #define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1) @@ -358,14 +354,10 @@ static void free_llist(has_next_ptr **pptr) *pptr = NULL; } -#if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR static ALWAYS_INLINE void free_Htaccess_list(Htaccess **pptr) { free_llist((has_next_ptr**)pptr); } -#endif static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr) { @@ -488,11 +480,7 @@ static void parse_conf(const char *path, int flag) #if ENABLE_FEATURE_HTTPD_BASIC_AUTH Htaccess *prev; #endif -#if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR Htaccess *cur; -#endif const char *filename = configFile; char buf[160]; char *p, *p0; @@ -502,22 +490,16 @@ static void parse_conf(const char *path, int flag) /* discard old rules */ free_Htaccess_IP_list(&ip_a_d); flg_deny_all = 0; -#if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR /* retain previous auth and mime config only for subdir parse */ if (flag != SUBDIR_PARSE) { #if ENABLE_FEATURE_HTTPD_BASIC_AUTH free_Htaccess_list(&g_auth); #endif -#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES free_Htaccess_list(&mime_a); -#endif #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR free_Htaccess_list(&script_i); #endif } -#endif if (flag == SUBDIR_PARSE || filename == NULL) { filename = alloca(strlen(path) + sizeof(httpd_conf) + 2); @@ -701,9 +683,6 @@ static void parse_conf(const char *path, int flag) continue; } -#if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ - || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR /* storing current config line */ cur = xzalloc(sizeof(Htaccess) + strlen(p0)); strcpy(cur->before_colon, p0); @@ -713,14 +692,12 @@ static void parse_conf(const char *path, int flag) #endif cur->after_colon = strchr(cur->before_colon, ':'); *cur->after_colon++ = '\0'; -#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES if (cur->before_colon[0] == '.') { /* .mime line: prepend to mime_a list */ cur->next = mime_a; mime_a = cur; continue; } -#endif #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR if (cur->before_colon[0] == '*' && cur->before_colon[1] == '.') { /* script interpreter line: prepend to script_i list */ @@ -762,7 +739,6 @@ static void parse_conf(const char *path, int flag) } } #endif /* BASIC_AUTH */ -#endif /* BASIC_AUTH || MIME_TYPES || SCRIPT_INTERPR */ } /* while (fgets) */ fclose(f); } @@ -1507,7 +1483,7 @@ static void send_cgi_and_exit( * 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 what) +static NOINLINE 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 */ @@ -1532,13 +1508,26 @@ static void send_file_and_exit(const char *url, int what) }; 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; -#endif + + fd = open(url, O_RDONLY); + if (fd < 0) { + if (DEBUG) + bb_perror_msg("can't open '%s'", url); + /* 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 (DEBUG) + bb_error_msg("sending file '%s' content-type: %s", + url, found_mime_type); /* If you want to know about EPIPE below * (happens if you abort downloads from local httpd): */ @@ -1549,9 +1538,7 @@ static void send_file_and_exit(const char *url, int what) /* If not found, set default as "application/octet-stream"; */ found_mime_type = "application/octet-stream"; if (suffix) { -#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES Htaccess *cur; -#endif for (table = suffixTable; *table; table += 2) { try_suffix = strstr(table[0], suffix); if (try_suffix) { @@ -1562,30 +1549,12 @@ static void send_file_and_exit(const char *url, int what) } } } -#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES for (cur = mime_a; cur; cur = cur->next) { if (strcmp(cur->before_colon, suffix) == 0) { found_mime_type = cur->after_colon; break; } } -#endif - } - - if (DEBUG) - bb_error_msg("sending file '%s' content-type: %s", - url, found_mime_type); - - f = open(url, O_RDONLY); - if (f < 0) { - if (DEBUG) - bb_perror_msg("can't open '%s'", url); - /* 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 (what == SEND_BODY) @@ -1596,9 +1565,9 @@ static void send_file_and_exit(const char *url, int what) range_end = file_size - 1; } if (range_end < range_start - || lseek(f, range_start, SEEK_SET) != range_start + || lseek(fd, range_start, SEEK_SET) != range_start ) { - lseek(f, 0, SEEK_SET); + lseek(fd, 0, SEEK_SET); range_start = 0; } else { range_len = range_end - range_start + 1; @@ -1607,43 +1576,42 @@ static void send_file_and_exit(const char *url, int what) } } #endif - if (what & SEND_HEADERS) send_headers(HTTP_OK); - #if ENABLE_FEATURE_HTTPD_USE_SENDFILE - offset = range_start; - do { - /* sz is rounded down to 64k */ - ssize_t sz = MAXINT(ssize_t) - 0xffff; - USE_FEATURE_HTTPD_RANGES(if (sz > range_len) sz = range_len;) - count = sendfile(1, f, &offset, sz); - if (count < 0) { - if (offset == range_start) - goto fallback; - goto fin; + { + off_t offset = range_start; + while (1) { + /* sz is rounded down to 64k */ + ssize_t sz = MAXINT(ssize_t) - 0xffff; + USE_FEATURE_HTTPD_RANGES(if (sz > range_len) sz = range_len;) + count = sendfile(STDOUT_FILENO, fd, &offset, sz); + if (count < 0) { + if (offset == range_start) + break; /* fall back to read/write loop */ + goto fin; + } + USE_FEATURE_HTTPD_RANGES(range_len -= sz;) + if (count == 0 || range_len == 0) + log_and_exit(); } - USE_FEATURE_HTTPD_RANGES(range_len -= sz;) - } while (count > 0 && range_len); - log_and_exit(); - - fallback: + } #endif - while ((count = safe_read(f, iobuf, IOBUF_SIZE)) > 0) { + while ((count = safe_read(fd, iobuf, IOBUF_SIZE)) > 0) { ssize_t n; USE_FEATURE_HTTPD_RANGES(if (count > range_len) count = range_len;) n = full_write(STDOUT_FILENO, iobuf, count); if (count != n) break; USE_FEATURE_HTTPD_RANGES(range_len -= count;) - if (!range_len) + if (range_len == 0) break; } -#if ENABLE_FEATURE_HTTPD_USE_SENDFILE - fin: -#endif - if (count < 0 && verbose > 1) - bb_perror_msg("error"); + if (count < 0) { + USE_FEATURE_HTTPD_USE_SENDFILE(fin:) + if (verbose > 1) + bb_perror_msg("error"); + } log_and_exit(); } @@ -2199,10 +2167,8 @@ static void mini_httpd(int server_socket) if (fork() == 0) { /* child */ -#if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP /* Do not reload config on HUP */ signal(SIGHUP, SIG_IGN); -#endif close(server_socket); xmove_fd(n, 0); xdup2(0, 1); @@ -2244,10 +2210,8 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv) if (vfork() == 0) { /* child */ -#if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP /* Do not reload config on HUP */ signal(SIGHUP, SIG_IGN); -#endif close(server_socket); xmove_fd(n, 0); xdup2(0, 1); @@ -2278,13 +2242,10 @@ static void mini_httpd_inetd(void) handle_incoming_and_exit(&fromAddr); } -#if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP -static void sighup_handler(int sig) +static void sighup_handler(int sig UNUSED_PARAM) { - parse_conf(default_path_httpd_conf, sig ? SIGNALED_PARSE : FIRST_PARSE); - signal_SA_RESTART_empty_mask(SIGHUP, sighup_handler); + parse_conf(default_path_httpd_conf, SIGNALED_PARSE); } -#endif enum { c_opt_config_file = 0, @@ -2395,7 +2356,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) #endif } -#if 0 /*was #if ENABLE_FEATURE_HTTPD_CGI*/ +#if 0 /* User can do it himself: 'env - PATH="$PATH" httpd' * We don't do it because we don't want to screw users * which want to do @@ -2413,15 +2374,9 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) } #endif -#if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP - if (!(opt & OPT_INETD)) { - /* runs parse_conf() inside */ - sighup_handler(0); - } else -#endif - { - parse_conf(default_path_httpd_conf, FIRST_PARSE); - } + parse_conf(default_path_httpd_conf, FIRST_PARSE); + if (!(opt & OPT_INETD)) + signal(SIGHUP, sighup_handler); xfunc_error_retval = 0; if (opt & OPT_INETD) |