On 23/07/10 18:04, walter harms wrote:


Peter Korsgaard schrieb:
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);

you could use
                gzurl=xasprintf(%s.gz", url);
                fd = open(gzurl, O_RDONLY);
                free(gzurl);

+               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 */
        }

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox


You should probably be careful not to confuse content-encodeing and transmission-encoding.

You will find much of this covered here:
http://redmine.lighttpd.net/issues/2221

The lighttpd strategy of keeping a cache of compressed files is interesting. In any case if there is support for sending gz compressed "if a pre-compressed file is available" it seems odd not to do the compression is if needed.

Since this strategy can lighten the load in sending data and the network quite consideralby , I think it is a good addition to BB , and worth doing well.

BTW svgz is a bit of a bastard case that should probably not be the starting point for this feature. I link this because it covers the issues fairly well.

regards.
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to