Hey @z3ntl3_root - welcome to the Caddy community.
I don’t know what you mean by “synced”.
Any handle directives at the same nesting level are mutually exclusive. That means if Caddy picks one handle directive to operate on for a given request, any other handle directive at that level is ignored.
You can nest a handle inside a handle and Caddy will follow on. But two handles side-by-side won’t be used at the same time. This is different from regular directive behaviour, where all non-terminating directives that apply to a given request would be used together for any matching request.
To pick which singular handle block to use, if they have paths specified, Caddy will pick the most specific path (i.e. the longest). If they have other matchers, Caddy will try them in order, from top of the Caddyfile to the bottom, and the first matching handle gets used - the rest ignored.
Consider the difference in behaviour:
example.com {
header /foo* X-Foo-Handle "Handle 'Foo'"
header /foo/bar* X-FooBar-Handle "Handle 'Foo/Bar'"
}
When you send a request for /foo/bar/stuff, you will get headers back:
X-Foo-Handle: Handle 'Foo'
X-FooBar-Handle: Handle 'Foo/Bar'
That’s because /foo/bar/stuff matches both /foo* and /foo/bar*.
But if we put them in handle instead:
example.com {
handle /foo* {
header X-Foo-Handle "Handle 'Foo'"
}
handle /foo/bar* {
header X-FooBar-Handle "Handle 'Foo/Bar'"
}
}
We make a request for /foo/bar/stuff, we only get a single header:
X-FooBar-Handle: Handle 'Foo/Bar'
Because Caddy picked the second handle and ignored the first one - mutual exclusivity.