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