The route directive overrides the sorting, so you’re telling Caddy to always handle /stuff/* first. The handle directive instead makes each block mutually exclusive from eachother.
Both solutions are valid, but I would personally lean towards using handle because it’s more flexible if you need to make additional changes.
I’ve tried the handle directive before and could not get it to work. Direct files were served and php files were processed, but going to //example.com/stuff/ still showed //example.com/index.php. This is the config I tried:
You can run caddy adapt --pretty to see the underlying config that the Caddyfile generates.
So maybe I misunderstood, but do you mean that you also have PHP files you want to execute in /files/*? Because if not, just remove the php_fastcgi line from that handle block and it should work fine.
Gotcha. Is it a rule that caddy processes directives bottom up?
Yes, basically, if there is a php file anywhere in that tree, I want it processed. I guess part of the problem is that php_fastcgi wraps up a lot of different functionality, including a bunch of redirect stuff. I just want the file processed without all the extras.
No, Caddy executes the HTTP handlers top to bottom, in the order they appear in the JSON config.
The Caddyfile is just a config adapter which generates a JSON config. It’s basically a UX layer, to make Caddy easier to use. And part of that, is having a default sort order so that the Caddyfile doesn’t need to be as strict about the order the user writes things in their config.
Fair enough, then route is what makes the most sense for you.
And yes, php_fastcgi is basically a shortcut for all this:
Say you get a request like /index.php/foo/bar. By default, the server doesn’t have a way to know that index.php is actually a file, and not a directory.
So split_path .php basically means "in the path, find where there might be a .php in it, then split that in two parts (i.e. /index.php and /foo/bar), where the left side is the script to run, and the right side is the bit that goes in the PATH_INFO fastcgi variable. Modern PHP apps will look at PATH_INFO to do routing.
In Apache, that’s typically handled by a rewrite rule in an .htaccess in the root of your project. In Nginx and Caddy, those types of rules are done directly in the server config.