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

Reply via email to