diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2010-07-25 03:20:53 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-25 03:20:53 +0200 |
commit | 7a2ba329b9235af4c647e0a88c1db023b51cf8a4 (patch) | |
tree | 41f3b67abcd66ef219da52f4b88298031a06cfbc | |
parent | 535ce1df5cb6a2bf588e1c2655cf09f49ed455db (diff) | |
download | busybox-w32-7a2ba329b9235af4c647e0a88c1db023b51cf8a4.tar.gz busybox-w32-7a2ba329b9235af4c647e0a88c1db023b51cf8a4.tar.bz2 busybox-w32-7a2ba329b9235af4c647e0a88c1db023b51cf8a4.zip |
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>
-rw-r--r-- | networking/Config.src | 8 | ||||
-rw-r--r-- | networking/httpd.c | 56 |
2 files changed, 60 insertions, 4 deletions
diff --git a/networking/Config.src b/networking/Config.src index 2d29c423a..8604c53e9 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -270,6 +270,14 @@ config FEATURE_HTTPD_PROXY | |||
270 | Then a request to /url/myfile will be forwarded to | 270 | Then a request to /url/myfile will be forwarded to |
271 | http://hostname[:port]/new/path/myfile. | 271 | http://hostname[:port]/new/path/myfile. |
272 | 272 | ||
273 | config FEATURE_HTTPD_GZIP | ||
274 | bool "Support for GZIP content encoding" | ||
275 | default y | ||
276 | depends on HTTPD | ||
277 | help | ||
278 | Makes httpd send files using GZIP content encoding if the | ||
279 | client supports it and a pre-compressed <file>.gz exists. | ||
280 | |||
273 | config IFCONFIG | 281 | config IFCONFIG |
274 | bool "ifconfig" | 282 | bool "ifconfig" |
275 | default y | 283 | default y |
diff --git a/networking/httpd.c b/networking/httpd.c index 12bad597a..cad45cd5d 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -277,6 +277,10 @@ struct globals { | |||
277 | #if ENABLE_FEATURE_HTTPD_PROXY | 277 | #if ENABLE_FEATURE_HTTPD_PROXY |
278 | Htaccess_Proxy *proxy; | 278 | Htaccess_Proxy *proxy; |
279 | #endif | 279 | #endif |
280 | #if ENABLE_FEATURE_HTTPD_GZIP | ||
281 | /* client can handle gzip / we are going to send gzip */ | ||
282 | smallint content_gzip; | ||
283 | #endif | ||
280 | }; | 284 | }; |
281 | #define G (*ptr_to_globals) | 285 | #define G (*ptr_to_globals) |
282 | #define verbose (G.verbose ) | 286 | #define verbose (G.verbose ) |
@@ -319,6 +323,11 @@ enum { | |||
319 | #define hdr_cnt (G.hdr_cnt ) | 323 | #define hdr_cnt (G.hdr_cnt ) |
320 | #define http_error_page (G.http_error_page ) | 324 | #define http_error_page (G.http_error_page ) |
321 | #define proxy (G.proxy ) | 325 | #define proxy (G.proxy ) |
326 | #if ENABLE_FEATURE_HTTPD_GZIP | ||
327 | # define content_gzip (G.content_gzip ) | ||
328 | #else | ||
329 | # define content_gzip 0 | ||
330 | #endif | ||
322 | #define INIT_G() do { \ | 331 | #define INIT_G() do { \ |
323 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 332 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
324 | IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ | 333 | IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ |
@@ -1027,10 +1036,14 @@ static void send_headers(int responseNum) | |||
1027 | #endif | 1036 | #endif |
1028 | "Last-Modified: %s\r\n%s %"OFF_FMT"u\r\n", | 1037 | "Last-Modified: %s\r\n%s %"OFF_FMT"u\r\n", |
1029 | tmp_str, | 1038 | tmp_str, |
1030 | "Content-length:", | 1039 | content_gzip ? "Transfer-length:" : "Content-length:", |
1031 | file_size | 1040 | file_size |
1032 | ); | 1041 | ); |
1033 | } | 1042 | } |
1043 | |||
1044 | if (content_gzip) | ||
1045 | len += sprintf(iobuf + len, "Content-Encoding: gzip\r\n"); | ||
1046 | |||
1034 | iobuf[len++] = '\r'; | 1047 | iobuf[len++] = '\r'; |
1035 | iobuf[len++] = '\n'; | 1048 | iobuf[len++] = '\n'; |
1036 | if (infoString) { | 1049 | if (infoString) { |
@@ -1500,7 +1513,22 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |||
1500 | int fd; | 1513 | int fd; |
1501 | ssize_t count; | 1514 | ssize_t count; |
1502 | 1515 | ||
1503 | fd = open(url, O_RDONLY); | 1516 | if (content_gzip) { |
1517 | /* does <url>.gz exist? Then use it instead */ | ||
1518 | char *gzurl = xasprintf("%s.gz", url); | ||
1519 | fd = open(gzurl, O_RDONLY); | ||
1520 | free(gzurl); | ||
1521 | if (fd != -1) { | ||
1522 | struct stat sb; | ||
1523 | fstat(fd, &sb); | ||
1524 | file_size = sb.st_size; | ||
1525 | } else { | ||
1526 | IF_FEATURE_HTTPD_GZIP(content_gzip = 0;) | ||
1527 | fd = open(url, O_RDONLY); | ||
1528 | } | ||
1529 | } else { | ||
1530 | fd = open(url, O_RDONLY); | ||
1531 | } | ||
1504 | if (fd < 0) { | 1532 | if (fd < 0) { |
1505 | if (DEBUG) | 1533 | if (DEBUG) |
1506 | bb_perror_msg("can't open '%s'", url); | 1534 | bb_perror_msg("can't open '%s'", url); |
@@ -1583,8 +1611,11 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |||
1583 | url, found_mime_type); | 1611 | url, found_mime_type); |
1584 | 1612 | ||
1585 | #if ENABLE_FEATURE_HTTPD_RANGES | 1613 | #if ENABLE_FEATURE_HTTPD_RANGES |
1586 | if (what == SEND_BODY) | 1614 | if (what == SEND_BODY /* err pages and ranges don't mix */ |
1587 | range_start = 0; /* err pages and ranges don't mix */ | 1615 | || content_gzip /* we are sending compressed page: can't do ranges */ ///why? |
1616 | ) { | ||
1617 | range_start = 0; | ||
1618 | } | ||
1588 | range_len = MAXINT(off_t); | 1619 | range_len = MAXINT(off_t); |
1589 | if (range_start) { | 1620 | if (range_start) { |
1590 | if (!range_end) { | 1621 | if (!range_end) { |
@@ -2048,6 +2079,23 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2048 | } | 2079 | } |
2049 | } | 2080 | } |
2050 | #endif | 2081 | #endif |
2082 | #if ENABLE_FEATURE_HTTPD_GZIP | ||
2083 | if (STRNCASECMP(iobuf, "Accept-Encoding:") == 0) { | ||
2084 | char *s = iobuf + sizeof("Accept-Encoding:")-1; | ||
2085 | while (*s) { | ||
2086 | ///is "Accept-Encoding: compress,gzip" valid? | ||
2087 | // (that is, no space after ',') - | ||
2088 | // this code won't handle that | ||
2089 | s = skip_whitespace(s); | ||
2090 | if (STRNCASECMP(s, "gzip") == 0) | ||
2091 | content_gzip = 1; | ||
2092 | /* Note: we do not support "gzip;q=0" | ||
2093 | * method of _disabling_ gzip | ||
2094 | * delivery */ | ||
2095 | s = skip_non_whitespace(s); | ||
2096 | } | ||
2097 | } | ||
2098 | #endif | ||
2051 | } /* while extra header reading */ | 2099 | } /* while extra header reading */ |
2052 | } | 2100 | } |
2053 | 2101 | ||