[PATCH] httpd: add option to send files using gzip content-encoding if available
walter harms
wharms at bfs.de
Fri Jul 23 16:04:37 UTC 2010
Peter Korsgaard schrieb:
> From: Peter Korsgaard <peter.korsgaard at barco.com>
>
> 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 <peter.korsgaard at barco.com>
> ---
> 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 */
> }
>
More information about the busybox
mailing list