Can't get simple alias to work

Evaluates a group of directives mutually exclusively from other handle blocks at the same level of nesting.

The handle directive is kind of similar to the location directive from nginx config: the first matching handle block will be evaluated. Handle blocks can be nested if needed. Only HTTP handler directives can be used inside handle blocks.
handle (Caddyfile directive) — Caddy Documentation

So, at each level, only one handle directive is evaluated, and it’s the first one that matches.

I did note that when setting the same header like that multiple times, the generic one was always selected (header *), with no regard to either specificity or the order in which they’re set, so the longer-duration ones never seemed to apply.

Putting the longer-duration ones in a handle block while leaving the generic one on the top level seemed to fix that. This must be something to do with the fact they’re put in a subroute?

Wouldn’t mind @matt’s eyes and input on this one. At the very least, there should be some clear method of exercising control over which header is executed, so that cases of specific-over-general can be configured. Certainly, having to use handle groups in this manner to enable specificity of header directives isn’t ergonomic, nor is it particularly discoverable from documentation.

Anyway, I discovered through testing that the headers don’t need to be handled separately, they just need to be put in any subroute to “beat” the generic header. So here’s the neatest Caddyfile I could come up with that seems to work:

solovyov.net {
  encode zstd gzip
  header Cache-Control max-age=3600

  handle /q/* {
    uri strip_prefix /q
    root * /mnt/share
    file_server browse
  }

  handle {
    header /static/* Cache-Control max-age=31536000
    header /favicon.ico Cache-Control max-age=31536000
    root * /opt/solovyov.net/www
    file_server
  }
}
1 Like