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;