diff options
| author | elric <elric@NetBSD.org> | 2012-02-20 09:26:56 +0000 |
|---|---|---|
| committer | elric <elric@NetBSD.org> | 2012-02-20 09:26:56 +0000 |
| commit | bb88eb882f85ea594a1318b279c48e4b1f53b02d (patch) | |
| tree | 3ceae7349d6d210426bf75aa87b804ba02472e73 /libexec | |
| parent | 3923eb9192c651de261bd51f086c29e9c40a2a3d (diff) | |
Check in very basic compressed file support. httpd will now serve
a precompressed .gz file if it exists, the client claims to support
gzip and the request is not ranged.
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/httpd/bozohttpd.8 | 9 | ||||
| -rw-r--r-- | libexec/httpd/bozohttpd.c | 69 | ||||
| -rw-r--r-- | libexec/httpd/bozohttpd.h | 3 |
3 files changed, 76 insertions, 5 deletions
diff --git a/libexec/httpd/bozohttpd.8 b/libexec/httpd/bozohttpd.8 index f0b229e8a48..e52d3b45e1f 100644 --- a/libexec/httpd/bozohttpd.8 +++ b/libexec/httpd/bozohttpd.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: bozohttpd.8,v 1.32 2011/11/18 09:51:31 mrg Exp $ +.\" $NetBSD: bozohttpd.8,v 1.33 2012/02/20 09:26:56 elric Exp $ .\" .\" $eterna: bozohttpd.8,v 1.101 2011/11/18 01:25:11 mrg Exp $ .\" @@ -408,6 +408,13 @@ To disable SSL SUPPORT compile with .Dq -DNO_SSL_SUPPORT on the compiler command line. +.Ss COMPRESSION +.Nm +supports a very basic form compression. +.Nm +will serve the requested file postpended with ``.gz'' if +it exists, it is readable, the client requested gzip compression, and +the client did not make a ranged request. .Sh FILES .Nm looks for a couple of special files in directories that allow certain features diff --git a/libexec/httpd/bozohttpd.c b/libexec/httpd/bozohttpd.c index 4b851eef288..df5871d0a7b 100644 --- a/libexec/httpd/bozohttpd.c +++ b/libexec/httpd/bozohttpd.c @@ -1,4 +1,4 @@ -/* $NetBSD: bozohttpd.c,v 1.30 2011/11/18 09:51:31 mrg Exp $ */ +/* $NetBSD: bozohttpd.c,v 1.31 2012/02/20 09:26:56 elric Exp $ */ /* $eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $ */ @@ -696,6 +696,9 @@ bozo_read_request(bozohttpd_t *httpd) else if (strcasecmp(hdr->h_header, "if-modified-since") == 0) request->hr_if_modified_since = hdr->h_value; + else if (strcasecmp(hdr->h_header, + "accept-encoding") == 0) + request->hr_accept_encoding = hdr->h_value; debug((httpd, DEBUG_FAT, "adding header %s: %s", hdr->h_header, hdr->h_value)); @@ -1350,6 +1353,53 @@ bad_done: } /* + * can_gzip checks if the request supports and prefers gzip encoding. + * + * XXX: we do not consider the associated q with gzip in making our + * decision which is broken. + */ + +static int +can_gzip(bozo_httpreq_t *request) +{ + const char *pos; + const char *tmp; + size_t len; + + /* First we decide if the request can be gzipped at all. */ + + /* not if we already are encoded... */ + tmp = bozo_content_encoding(request, request->hr_file); + if (tmp && *tmp) + return 0; + + /* not if we are not asking for the whole file... */ + if (request->hr_last_byte_pos != -1 || request->hr_have_range) + return 0; + + /* Then we determine if gzip is on the cards. */ + + for (pos = request->hr_accept_encoding; pos && *pos; pos += len) { + while (*pos == ' ') + pos++; + + len = strcspn(pos, ";,"); + + if ((len == 4 && strncasecmp("gzip", pos, 4) == 0) || + (len == 6 && strncasecmp("x-gzip", pos, 6) == 0)) + return 1; + + if (pos[len] == ';') + len += strcspn(&pos[len], ","); + + if (pos[len]) + len++; + } + + return 0; +} + +/* * bozo_process_request does the following: * - check the request is valid * - process cgi-bin if necessary @@ -1374,9 +1424,21 @@ bozo_process_request(bozo_httpreq_t *request) if (transform_request(request, &isindex) == 0) return; + fd = -1; + encoding = NULL; + if (can_gzip(request)) { + asprintf(&file, "%s.gz", request->hr_file); + fd = open(file, O_RDONLY); + if (fd >= 0) + encoding = "gzip"; + free(file); + } + file = request->hr_file; - fd = open(file, O_RDONLY); + if (fd < 0) + fd = open(file, O_RDONLY); + if (fd < 0) { debug((httpd, DEBUG_FAT, "open failed: %s", strerror(errno))); if (errno == EPERM) @@ -1432,7 +1494,8 @@ bozo_process_request(bozo_httpreq_t *request) if (request->hr_proto != httpd->consts.http_09) { type = bozo_content_type(request, file); - encoding = bozo_content_encoding(request, file); + if (!encoding) + encoding = bozo_content_encoding(request, file); bozo_print_header(request, &sb, type, encoding); bozo_printf(httpd, "\r\n"); diff --git a/libexec/httpd/bozohttpd.h b/libexec/httpd/bozohttpd.h index 23c56627e73..44baf4b79c9 100644 --- a/libexec/httpd/bozohttpd.h +++ b/libexec/httpd/bozohttpd.h @@ -1,4 +1,4 @@ -/* $NetBSD: bozohttpd.h,v 1.20 2011/11/18 09:51:31 mrg Exp $ */ +/* $NetBSD: bozohttpd.h,v 1.21 2012/02/20 09:26:56 elric Exp $ */ /* $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $ */ @@ -128,6 +128,7 @@ typedef struct bozo_httpreq_t { const char *hr_referrer; const char *hr_range; const char *hr_if_modified_since; + const char *hr_accept_encoding; int hr_have_range; off_t hr_first_byte_pos; off_t hr_last_byte_pos; |
