OpenBSD httpd and serving compressed content
Yesterday I configured the web server serving this site, an OpenBSD vm on VULTR,
to start serving gzip-compressed content if it is present. I use gzip -k FILENAME
to compress the file on the server, then I set gzip-static in my httpd.conf location block
for this site, et voilĂ , httpd serves the .gz version automatically.
GZIP, but ZSTD too?
This only works for gzip-compressed stuff. I was curious about ZSTD, so went looking in the httpd source to see if that works well, but it looks like only gzip is handled in the code.
In the OpenBSD source (usr.sbin/httpd), in server_file.c, we can spot where the gzip handling is done (inside the function server_file_access):
/* change path to path.gz if necessary. */
if (srv_conf->flags & SRVFLAG_GZIP_STATIC) {
struct http_descriptor *req = clt->clt_descreq;
struct http_descriptor *resp = clt->clt_descresp;
struct stat gzst;
int gzfd;
char gzpath[PATH_MAX];
/* check Accept-Encoding header */
key.kv_key = "Accept-Encoding";
r = kv_find(&req->http_headers, &key);
if (r != NULL && strstr(r->kv_value, "gzip") != NULL) {
/* append ".gz" to path and check existence */
ret = snprintf(gzpath, sizeof(gzpath), "%s.gz", path);
if (ret < 0 || (size_t)ret >= sizeof(gzpath)) {
close(fd);
return (500);
}
if ((gzfd = open(gzpath, O_RDONLY)) != -1) {
/* .gz must be a file, and not older */
if (fstat(gzfd, &gzst) != -1 &&
S_ISREG(gzst.st_mode) &&
timespeccmp(&gzst.st_mtim, &st.st_mtim,
>=)) {
kv_add(&resp->http_headers,
"Content-Encoding", "gzip");
/* Use original file timestamp */
gzst.st_mtim = st.st_mtim;
st = gzst;
close(fd);
fd = gzfd;
} else {
close(gzfd);
}
}
}
}
Here we can see that httpd checks:
- is the gzip-static directive present?
- did the client request send Accept-Encoding with gzip?
- is there a file with same path client requested but with .gz at end?
- if we found a .gz file, is that file not older than the original (without .gz extension)?
- if all of these are true, send the .gz version.
OpenBSD development and proposals to serve other compression algo content in httpd (.zst, .br, .bz2, etc)
I surfed around the openbsd-tech mail list for a bit, and found someone named Adam Mullins proposing some cool patches to add support for more compression extensions. He was wanting to use brotli-compressed files, and then he adapted to make it more generic , but it seems like the OpenBSD developers were lukewarm even about having allowed .gz in the first place. This might be something to just implement for our own systems, doesn't seem like people want it too much besides a few like me.
Mr. Mullins patch looks really cool, and I'm going to try it out on my OpenBSD 7.3 vm. You can find his code here