httpd: optional support for gzip-compressed pages

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

Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Peter Korsgaard 2010-07-25 03:20:53 +02:00 committed by Denys Vlasenko
parent 535ce1df5c
commit 7a2ba329b9
2 changed files with 60 additions and 4 deletions

View File

@ -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

View File

@ -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(const char *url, int what)
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(const char *url, int what)
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) {
@ -2047,6 +2078,23 @@ 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) {
///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 */
}