From: Peter Korsgaard <[email protected]> With this option enabled, httpd sends compressed data if supported by the client and a pre-compressed <file>.gz is available.
bloat-o-meter: function old new delta send_file_and_exit 667 833 +166 handle_incoming_and_exit 2983 3121 +138 .rodata 126806 126876 +70 send_headers 754 803 +49 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/0 up/down: 423/0) Total: 423 bytes Signed-off-by: Peter Korsgaard <[email protected]> --- networking/Config.src | 8 +++++++ networking/httpd.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletions(-) diff --git a/networking/Config.src b/networking/Config.src index 2d29c42..8604c53 100644 --- a/networking/Config.src +++ b/networking/Config.src @@ -270,6 +270,14 @@ config FEATURE_HTTPD_PROXY Then a request to /url/myfile will be forwarded to http://hostname[:port]/new/path/myfile. +config FEATURE_HTTPD_GZIP + bool "Support for GZIP content encoding" + default y + depends on HTTPD + help + Makes httpd send files using GZIP content encoding if the + client supports it and a pre-compressed <file>.gz exists. + config IFCONFIG bool "ifconfig" default y diff --git a/networking/httpd.c b/networking/httpd.c index 8ad7e88..55b11c8 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -284,6 +284,10 @@ struct globals { #if ENABLE_FEATURE_HTTPD_PROXY Htaccess_Proxy *proxy; #endif +#if ENABLE_FEATURE_HTTPD_GZIP + smallint supports_gzip; /* client can handle gzip */ + smallint gzipped; /* file is gzipped */ +#endif }; #define G (*ptr_to_globals) #define verbose (G.verbose ) @@ -326,6 +330,8 @@ enum { #define hdr_cnt (G.hdr_cnt ) #define http_error_page (G.http_error_page ) #define proxy (G.proxy ) +#define supports_gzip (G.supports_gzip ) +#define gzipped (G.gzipped ) #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ @@ -1034,10 +1040,18 @@ static void send_headers(int responseNum) #endif "Last-Modified: %s\r\n%s %"OFF_FMT"u\r\n", tmp_str, +#if ENABLE_FEATURE_HTTPD_GZIP + gzipped ? "Transfer-length:" : +#endif "Content-length:", file_size ); } +#if ENABLE_FEATURE_HTTPD_GZIP + if (gzipped) + len += sprintf(iobuf + len, "Content-Encoding: gzip\r\n"); +#endif + iobuf[len++] = '\r'; iobuf[len++] = '\n'; if (infoString) { @@ -1507,6 +1521,26 @@ static NOINLINE void send_file_and_exit(const char *url, int what) int fd; ssize_t count; +#if ENABLE_FEATURE_HTTPD_GZIP + if (supports_gzip) { + char *gzurl; + + /* does <url>.gz exist? Then use it instead */ + gzurl = alloca(strlen(url) + strlen(".gz") + 1); + sprintf(gzurl, "%s.gz", url); + fd = open(gzurl, O_RDONLY); + if (fd != -1) { + struct stat sb; + + fstat(fd, &sb); + file_size = sb.st_size; + gzipped = 1; + } + else + fd = open(url, O_RDONLY); + } + else +#endif fd = open(url, O_RDONLY); if (fd < 0) { if (DEBUG) @@ -1590,7 +1624,11 @@ static NOINLINE void send_file_and_exit(const char *url, int what) url, found_mime_type); #if ENABLE_FEATURE_HTTPD_RANGES - if (what == SEND_BODY) + if (what == SEND_BODY +#if ENABLE_FEATURE_HTTPD_GZIP + || gzipped +#endif + ) range_start = 0; /* err pages and ranges don't mix */ range_len = MAXINT(off_t); if (range_start) { @@ -2055,6 +2093,17 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) } } #endif +#if ENABLE_FEATURE_HTTPD_GZIP + if (STRNCASECMP(iobuf, "Accept-Encoding:") == 0) { + char *s = iobuf + sizeof("Accept-Encoding:")-1; + while (*s) { + s = skip_whitespace(s); + if (STRNCASECMP(s, "gzip") == 0) + supports_gzip = 1; + s = skip_non_whitespace(s); + } + } +#endif } /* while extra header reading */ } -- 1.7.1 _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
