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;

Reply via email to