Module Name: src
Committed By: elric
Date: Mon Feb 20 09:26:56 UTC 2012
Modified Files:
src/libexec/httpd: bozohttpd.8 bozohttpd.c bozohttpd.h
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/libexec/httpd/bozohttpd.8
cvs rdiff -u -r1.30 -r1.31 src/libexec/httpd/bozohttpd.c
cvs rdiff -u -r1.20 -r1.21 src/libexec/httpd/bozohttpd.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/libexec/httpd/bozohttpd.8
diff -u src/libexec/httpd/bozohttpd.8:1.32 src/libexec/httpd/bozohttpd.8:1.33
--- src/libexec/httpd/bozohttpd.8:1.32 Fri Nov 18 09:51:31 2011
+++ src/libexec/httpd/bozohttpd.8 Mon Feb 20 09:26:56 2012
@@ -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
Index: src/libexec/httpd/bozohttpd.c
diff -u src/libexec/httpd/bozohttpd.c:1.30 src/libexec/httpd/bozohttpd.c:1.31
--- src/libexec/httpd/bozohttpd.c:1.30 Fri Nov 18 09:51:31 2011
+++ src/libexec/httpd/bozohttpd.c Mon Feb 20 09:26:56 2012
@@ -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 *req
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 *req
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");
Index: src/libexec/httpd/bozohttpd.h
diff -u src/libexec/httpd/bozohttpd.h:1.20 src/libexec/httpd/bozohttpd.h:1.21
--- src/libexec/httpd/bozohttpd.h:1.20 Fri Nov 18 09:51:31 2011
+++ src/libexec/httpd/bozohttpd.h Mon Feb 20 09:26:56 2012
@@ -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;