$ cat ~nutts/blog/*.md

Using gzip-static with location rewrites in httpd on OpenBSD

This site is made up of many .html pages. To give two examples:

The former is the default "directory index" for the site, so when you access the root domain, it loads that page. The latter is one of the additional content pages I have.

For OpenBSD's httpd web server, in OpenBSD 7.1 they introduced support for gzip-static:

Added a gzip-static option to httpd.conf(5), allowing delivery of precompressed files with content-encoding gzip.

We use it by including the option inside our server block:

server "nutts.org" {
    listen on egress tls port 443
    root "/htdocs/nutts.org"
    gzip-static
    ...
}

It requires that if you want to support gzip compression – which almost all browsers support these days – you must provide gzipped versions of the files yourself. So for those former two pages, their gzipped partners are:

Note: These gzipped versions are only served to visitors if their dates are not older than their uncompressed partners.

They can be generated with a single command:

$ gzip -k *.html *.css`

I don't have any .js files, but *.js can be added to compress those too.

For all pages on this site, I don't want to show .html extensions. To accomplish this, I use a pair of location blocks for each page. For example:

location "/books/" {
    block return 301 "/books"
}
location "/books" {
    request rewrite "/books.html"
}

The first block removes any ending forward slash, otherwise we end up with content being accessible at two locations. The second block allows access without the file extension.

However, what I realised is that for these rewritten pages, the gzipped version was not being served:

$ curl -I -H "Accept-Encoding: gzip" https://nutts.org/books
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 20127
Content-Type: text/html

The solution I found is to duplicate the gzip-static statement inside every rewrite location block:

location "/books" {
    request rewrite "/books.html"
    gzip-static
}

Then it works properly:

$ curl -I -H "Accept-Encoding: gzip" https://nutts.org/books
HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 6599
Content-Type: text/html

Nowhere could I find anybody talking about this problem. My "dumb but fast" LLM assistant (Claude) couldn't help either, wanting me to manually serve the .html.gz version instead. This would not work for anybody using a very old browser, and I want to support everything.

Anyway, it goes to show that LLMs often cannot solve problems that nobody out there has talked about having. They are, after all, just glorified prediction machines running off all the data they could scrape from the known universe.

I'm learning as I go, so if you have any tips for ways I can improve this information or the way I'm doing things, please send me an email.

#openbsd #tech