summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorelric <elric@NetBSD.org>2012-02-20 09:26:56 +0000
committerelric <elric@NetBSD.org>2012-02-20 09:26:56 +0000
commitbb88eb882f85ea594a1318b279c48e4b1f53b02d (patch)
tree3ceae7349d6d210426bf75aa87b804ba02472e73 /libexec
parent3923eb9192c651de261bd51f086c29e9c40a2a3d (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.89
-rw-r--r--libexec/httpd/bozohttpd.c69
-rw-r--r--libexec/httpd/bozohttpd.h3
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;