On Saturday 24 July 2010 11:28, Peter Korsgaard wrote:
> 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
> handle_incoming_and_exit                            2983    3121    +138
> send_file_and_exit                                   667     778    +111
> .rodata                                           126806  126876     +70
> send_headers                                         754     803     +49
> ------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 4/0 up/down: 368/0)             Total: 368 bytes
> 
> Signed-off-by: Peter Korsgaard <[email protected]>
> ---
> Changes since v1:
> - use xasprintf like suggested by Walter Harms, saves 55 bytes.
> 
>  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..d93eab4 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

Why two variables? One is enough. And by defining it to 0
if !ENABLE_FEATURE_HTTPD_RANGES, ifdef forest may be made
less ugly.

>  #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 */

(1) Comment becomes misplaced: it only applies to what == SEND_BODY case.
(2) So, why do we lose range upload here?

> +#if ENABLE_FEATURE_HTTPD_GZIP
> +                     if (STRNCASECMP(iobuf, "Accept-Encoding:") == 0) {
> +                             char *s = iobuf + sizeof("Accept-Encoding:")-1;
> +                             while (*s) {
> +                                     s = skip_whitespace(s);

is, e.g., "Accept-Encoding: compress,gzip" valid?
This code wouldn't detect "gzip" in such a string.

> +                                     if (STRNCASECMP(s, "gzip") == 0)
> +                                                     supports_gzip = 1;
> +                                     s = skip_non_whitespace(s);
> +                             }
> +                     }
> +#endif


I am applying attached patch. Thanks!

function                                             old     new   delta
send_file_and_exit                                   662     761     +99
handle_incoming_and_exit                            2756    2830     +74
send_headers                                         603     654     +51
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 224/0)             Total: 224 bytes
   text    data     bss     dec     hex filename
 864355     936   17204  882495   d773f busybox_old
 864643     936   17204  882783   d785f busybox_unstripped

-- 
vda

diff -ad -urpN busybox.7/networking/Config.src busybox.8/networking/Config.src
--- busybox.7/networking/Config.src	2010-07-25 02:49:39.000000000 +0200
+++ busybox.8/networking/Config.src	2010-07-25 02:49:51.000000000 +0200
@@ -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 -ad -urpN busybox.7/networking/httpd.c busybox.8/networking/httpd.c
--- busybox.7/networking/httpd.c	2010-07-25 03:10:08.000000000 +0200
+++ busybox.8/networking/httpd.c	2010-07-25 03:10:31.000000000 +0200
@@ -277,6 +277,10 @@ 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          )
@@ -319,6 +323,11 @@ 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 { \
 	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
 	IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \
@@ -1027,10 +1036,14 @@ static void send_headers(int responseNum
 #endif
 			"Last-Modified: %s\r\n%s %"OFF_FMT"u\r\n",
 				tmp_str,
-				"Content-length:",
+				content_gzip ? "Transfer-length:" : "Content-length:",
 				file_size
 		);
 	}
+
+	if (content_gzip)
+		len += sprintf(iobuf + len, "Content-Encoding: gzip\r\n");
+
 	iobuf[len++] = '\r';
 	iobuf[len++] = '\n';
 	if (infoString) {
@@ -1500,7 +1513,22 @@ static NOINLINE void send_file_and_exit(
 	int fd;
 	ssize_t count;
 
-	fd = open(url, O_RDONLY);
+	if (content_gzip) {
+		/* does <url>.gz exist? Then use it instead */
+		char *gzurl = xasprintf("%s.gz", url);
+		fd = open(gzurl, O_RDONLY);
+		free(gzurl);
+		if (fd != -1) {
+			struct stat sb;
+			fstat(fd, &sb);
+			file_size = sb.st_size;
+		} else {
+			IF_FEATURE_HTTPD_GZIP(content_gzip = 0;)
+			fd = open(url, O_RDONLY);
+		}
+	} else {
+		fd = open(url, O_RDONLY);
+	}
 	if (fd < 0) {
 		if (DEBUG)
 			bb_perror_msg("can't open '%s'", url);
@@ -1583,8 +1611,11 @@ static NOINLINE void send_file_and_exit(
 			url, found_mime_type);
 
 #if ENABLE_FEATURE_HTTPD_RANGES
-	if (what == SEND_BODY)
-		range_start = 0; /* err pages and ranges don't mix */
+	if (what == SEND_BODY /* err pages and ranges don't mix */
+	 || content_gzip /* we are sending compressed page: can't do ranges */  ///why?
+	) {
+		range_start = 0;
+	}
 	range_len = MAXINT(off_t);
 	if (range_start) {
 		if (!range_end) {
@@ -2048,6 +2079,23 @@ static void handle_incoming_and_exit(con
 				}
 			}
 #endif
+#if ENABLE_FEATURE_HTTPD_GZIP
+			if (STRNCASECMP(iobuf, "Accept-Encoding:") == 0) {
+				char *s = iobuf + sizeof("Accept-Encoding:")-1;
+				while (*s) {
+					///is "Accept-Encoding: compress,gzip" valid?
+					// (that is, no space after ',') -
+					// this code won't handle that
+					s = skip_whitespace(s);
+					if (STRNCASECMP(s, "gzip") == 0)
+						content_gzip = 1;
+					/* Note: we do not support "gzip;q=0"
+					 * method of _disabling_ gzip
+					 * delivery */
+					s = skip_non_whitespace(s);
+				}
+			}
+#endif
 		} /* while extra header reading */
 	}
 
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to