My Recommended Publicfile Patches

While djb is perhaps best known for writing qmail, he also wrote a web server, publicfile. Like his other software, publicfile is simple and robust. I use it to serve this site, among other software.

Characteristically for djb, publicfile is pretty minimal out of the box. Here are a few patches I applied to the source to make my server faster, more flexible, and easier to use.

I found these patches on publicfile.org, which maintains a great list of community-contributed enhancements.

GZIP Encoding

Web browsers will accept either raw content, or content compressed with GZIP. Serving GZIP’d content will make your web pages feel more responsive, since they can tranfer faster. It also saves you and your visitors money.

Historically, some websites avoided serving GZIP’d content because of the CPU overhead. Their servers had to do significantly more work compressing every page as it was delivered.

And that’s why I like Peter Conrad’s GZIP patch. Out of the box, publicfile serves only raw static content from files on disk. This patch teaches it to also look for a GZIP’d version right next to the file, and serve that — without recompressing — to the client. This brings all the advantages of serving GZIP’d content, with zero overhead.

This does cause your website to use slightly more disk space: you need to store both compressed and uncompressed versions of your files, because some clients may not accept GZIP. That can be a bit of a maintenance problem, but if you’re using Jekyll, I have a plugin to fix this.

Custom Errors and Redirection

Sometimes people will visit pages on your site that don’t actually exist — either because they followed a broken link, or just spelled your URL wrong. Out of the box, publicfile serves very spartan, generic error pages.

Frustratingly, this also happens if you visit a URL that happens to be a directory, like http://yoursite.com/foo. publicfile won’t search inside that directory for an index.html like most servers — it will only do that if there’s a trailing slash.

Ari Edelkind fixed both problems with a patch. This patch changes publicfile’s behavior in two ways:

  1. If someone tries to access a directory without the trailing slash, it redirects them to use the trailing slash. Because it uses an HTTP redirect, crawlers and other software can update their URLs.
  2. If someone does follow a broken link despite this, publicfile will now serve a page /errors/<errorcode>.html, where <errorcode> is an HTTP numeric code like 404.

This patch makes your website much more pleasant to visit.

File Types from the Environment

Out of the box, publicfile serves content using a hardcoded mapping from file extension to MIME type. The mapping was chosen in the late 90s, and is missing most modern content types. (It also has some idiosyncracies, such as requiring JPEG files to be named .jpeg instead of the more common .jpg.)

Uwe Ohse fixed this with a patch that teaches publicfile to consult its environment, instead. If it finds an unknown file extension .ext, it looks for an environment variable called CT_ext. If it exists, publicflie will use its contents as the MIME type.

Since djb’s daemontools provide a program, envdir, that configures a program’s environment using files in a directory, you can now create your content mapping as a directory of small text files instead of having to modify publicfile itself.