From 9fe8bd8d61d8cf187ad40affb1f69fe72ae74744 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 7 Apr 2018 01:13:30 +0200 Subject: httpd: do not default to Content-type: application/octet-stream Instead, simply don't send this header. On Mon, Apr 2, 2018 at 8:17 PM, xisd wrote: > I had some trouble using busybox httpd to serve a static website and I > thought the issue might be of interest. > > My problem is related to something that seem quite common for static > site generator : the use of html files without the '.html' extension > (it is called 'clean url'...) > > Most web server guess that these files are html and display them like > any other .html files. > > From what I understood, the MIME type for files without extension in > busybox htttp default settings is 'application/octet-stream', and > because of that 'clean url' pages are not displayed. > > It is only trouble because I wanted to deploy my website on freshly > installed linux without editing any configuration. > > The default MIME setting make sense to me as it is, I just thought that > might be worth mentioning since the use of 'clean url' seem to be a > common practice for static sites generators (the one I use is callled > 'yellow' (https://github.com/datenstrom/yellow)) > > Here is a link for the related issue on github : > https://github.com/datenstrom/yellow/issues/317 function old new delta send_headers 702 718 +16 send_headers_and_exit 23 20 -3 handle_incoming_and_exit 2794 2791 -3 send_file_and_exit 772 756 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/3 up/down: 16/-22) Total: -6 bytes Signed-off-by: Denys Vlasenko --- networking/httpd.c | 62 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'networking/httpd.c') diff --git a/networking/httpd.c b/networking/httpd.c index 9439e206c..b52526a78 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -392,7 +392,10 @@ static const struct { struct globals { int verbose; /* must be int (used by getopt32) */ smallint flg_deny_all; - +#if ENABLE_FEATURE_HTTPD_GZIP + /* client can handle gzip / we are going to send gzip */ + smallint content_gzip; +#endif unsigned rmt_ip; /* used for IP-based allow/deny rules */ time_t last_mod; char *rmt_ip_str; /* for $REMOTE_ADDR and $REMOTE_PORT */ @@ -440,14 +443,15 @@ struct globals { #if ENABLE_FEATURE_HTTPD_PROXY Htaccess_Proxy *proxy; #endif -#if ENABLE_FEATURE_HTTPD_GZIP - /* client can handle gzip / we are going to send gzip */ - smallint content_gzip; -#endif }; #define G (*ptr_to_globals) #define verbose (G.verbose ) #define flg_deny_all (G.flg_deny_all ) +#if ENABLE_FEATURE_HTTPD_GZIP +# define content_gzip (G.content_gzip ) +#else +# define content_gzip 0 +#endif #define rmt_ip (G.rmt_ip ) #define bind_addr_or_port (G.bind_addr_or_port) #define g_query (G.g_query ) @@ -481,11 +485,6 @@ enum { #define hdr_cnt (G.hdr_cnt ) #define http_error_page (G.http_error_page ) #define proxy (G.proxy ) -#if ENABLE_FEATURE_HTTPD_GZIP -# define content_gzip (G.content_gzip ) -#else -# define content_gzip 0 -#endif #define INIT_G() do { \ setup_common_bufsiz(); \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ @@ -944,7 +943,7 @@ static char *encodeString(const char *string) if (isalnum(ch)) *p++ = ch; else - p += sprintf(p, "&#%d;", (unsigned char) ch); + p += sprintf(p, "&#%u;", (unsigned char) ch); } *p = '\0'; return out; @@ -1040,7 +1039,7 @@ static void log_and_exit(void) * second packet is delayed for any reason. * responseNum - the result code to send. */ -static void send_headers(int responseNum) +static void send_headers(unsigned responseNum) { static const char RFC1123FMT[] ALIGN1 = "%a, %d %b %Y %H:%M:%S GMT"; /* Fixed size 29-byte string. Example: Sun, 06 Nov 1994 08:49:37 GMT */ @@ -1052,9 +1051,9 @@ static void send_headers(int responseNum) #if ENABLE_FEATURE_HTTPD_ERROR_PAGES const char *error_page = NULL; #endif + unsigned len; unsigned i; time_t timer = time(NULL); - int len; for (i = 0; i < ARRAY_SIZE(http_response_type); i++) { if (http_response_type[i] == responseNum) { @@ -1078,16 +1077,21 @@ static void send_headers(int responseNum) strftime(date_str, sizeof(date_str), RFC1123FMT, gmtime_r(&timer, &tm)); /* ^^^ using gmtime_r() instead of gmtime() to not use static data */ len = sprintf(iobuf, - "HTTP/1.0 %d %s\r\n" - "Content-type: %s\r\n" + "HTTP/1.0 %u %s\r\n" "Date: %s\r\n" "Connection: close\r\n", responseNum, responseString, - /* if it's error message, then it's HTML */ - (responseNum == HTTP_OK ? found_mime_type : "text/html"), date_str ); + if (responseNum != HTTP_OK || found_mime_type) { + len += sprintf(iobuf + len, + "Content-type: %s\r\n", + /* if it's error message, then it's HTML */ + (responseNum != HTTP_OK ? "text/html" : found_mime_type) + ); + } + #if ENABLE_FEATURE_HTTPD_BASIC_AUTH if (responseNum == HTTP_UNAUTHORIZED) { len += sprintf(iobuf + len, @@ -1147,9 +1151,9 @@ static void send_headers(int responseNum) "Accept-Ranges: bytes\r\n" #endif "Last-Modified: %s\r\n" - "%s %"OFF_FMT"u\r\n", + "%s-Length: %"OFF_FMT"u\r\n", date_str, - content_gzip ? "Transfer-Length:" : "Content-Length:", + content_gzip ? "Transfer" : "Content", file_size ); } @@ -1161,8 +1165,8 @@ static void send_headers(int responseNum) iobuf[len++] = '\n'; if (infoString) { len += sprintf(iobuf + len, - "%d %s\n" - "

%d %s

\n" + "%u %s\n" + "

%u %s

\n" "%s\n" "\n", responseNum, responseString, @@ -1300,9 +1304,9 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post continue; } if (DEBUG && WIFEXITED(status)) - bb_error_msg("CGI exited, status=%d", WEXITSTATUS(status)); + bb_error_msg("CGI exited, status=%u", WEXITSTATUS(status)); if (DEBUG && WIFSIGNALED(status)) - bb_error_msg("CGI killed, signal=%d", WTERMSIG(status)); + bb_error_msg("CGI killed, signal=%u", WTERMSIG(status)); #endif break; } @@ -1533,7 +1537,7 @@ static void send_cgi_and_exit( if (G.http_accept_language) setenv1("HTTP_ACCEPT_LANGUAGE", G.http_accept_language); if (post_len) - putenv(xasprintf("CONTENT_LENGTH=%d", post_len)); + putenv(xasprintf("CONTENT_LENGTH=%u", post_len)); if (cookie) setenv1("HTTP_COOKIE", cookie); if (content_type) @@ -1684,8 +1688,8 @@ static NOINLINE void send_file_and_exit(const char *url, int what) * (happens if you abort downloads from local httpd): */ signal(SIGPIPE, SIG_IGN); - /* If not found, default is "application/octet-stream" */ - found_mime_type = "application/octet-stream"; + /* If not found, default is to not send "Content-type:" */ + /*found_mime_type = NULL; - already is */ suffix = strrchr(url, '.'); if (suffix) { static const char suffixTable[] ALIGN1 = @@ -2543,11 +2547,9 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv) */ while (1) { int n; - len_and_sockaddr fromAddr; /* Wait for connections... */ - fromAddr.len = LSA_SIZEOF_SA; - n = accept(server_socket, &fromAddr.u.sa, &fromAddr.len); + n = accept(server_socket, NULL, NULL); if (n < 0) continue; @@ -2734,7 +2736,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) xfunc_error_retval = 0; if (opt & OPT_INETD) - mini_httpd_inetd(); + mini_httpd_inetd(); /* never returns */ #if BB_MMU if (!(opt & OPT_FOREGROUND)) bb_daemonize(0); /* don't change current directory */ -- cgit v1.2.3