rewrite has higher precedence than redir, so you should be able to rely on the presence of the {rewrite_uri} placeholder to check whether rewrite fell back to its last target (after failing all preceding targets).
rewrite {
# Check for a file, then a folder
# If neither exists, we would usually issue a 404
# Instead, here we rewrite to /redir-target/
to {path} {path}/ /redir-target/
}
redir {
# /redir-target/ would usually still issue a 404
# So manually redir from this path if it was rewritten to
if {rewrite_uri} is /redir-target/
# Modify the destination and status as required
/ http://www.example.com/some/path 301
}
The only caveat is that this only works if Caddy is the file server, because we’re not checking for an actual 404 but rather the circumstances that would usually produce a 404. So if you’re proxying, and want to capture a 404 from upstream and convert it to a 301 to the client, I can’t think of a solution (other than re-configuring the upstream).
This only works with paths that do not exist anywhere on the server - For example, I am serving /folder1/folder2, so with the above configured navigating to / or /folder/ still return 404 responses.
To clarify, I’m not actually trying to serve folder1, but I am trying to serve folder1/folder2. So the root URL, and root/folder1 should redirect to another domain, but root/folder1/folder2 should serve the files as expected.
/folder1/ is unfortunately a valid target in your case. Hmm.
Do you want to be able to serve the index of /folder1/folder2/, or only real files within?
Does this solution have to be totally generic, or are you able to configure in advance which directories you want to not serve? Or maybe the folder depth? Trying to think of another way you might be able to achieve this.
Its only the index, but its more like folder1/folder2/folder3/folder4.
I’d prefer it to be generic, as I’m currently serving around 100 folders. I’m trying to serve the index of a certain depth only - they’re all the same depth if this makes it easier.
Could this not be added to the error directive, to redirect to a page, instead of serving a file?
My other thought was to create two label blocks, but I’m not sure how they’re matched or prioritised.