Redirect with a splat placeholder?

Caddy supports redir directive that allows to perform a redirect while preserving the URI part:

redir /vl1/* /scm/hg/{uri} 302

It works fine as long as the destination URI matches the same pattern, e.g. /scm/hg/vl1/*.

But how to redirect the ‘splat’ part of the source URI? For instance, /vl1/* URI should be redirected to /scm/hg/volumes/1/*. How to capture the value of the splat part in the destination URL?

My attempts so far:

redir /vl1/* /scm/hg/volumes/1/* 302

It does not work because * symbol in the destination URL is interpreted as a literal character, not a placeholder.

Another approach is:

redir /vl1/* /scm/hg/volumes/1/{uri} 302

But it leads to the wrong result because {uri} placeholder captures the whole source URI, leading to the wrong destination URI of /scm/hg/volumes/1/vl1/* instead of just /scm/hg/volumes/1/*.

I would expect to be able to write something like this:

redir /vl1/* /scm/hg/volumes/1/{splat} 302

where {splat} is a placeholder that returns the value that was captured by * in the source URI matcher.

In this way, a URI like /vl1/sample could be correctly redirected to /scm/hg/volumes/1/sample, /vl1/nested/sample to /scm/hg/volumes/1/nested/sample, and so on.

For instance, Netlify allows such syntax in its _redirects file format which is super handy and frequently used: Redirect options | Netlify Docs

Is there a way to achieve this with Caddy?

Use handle_path which will strip the matched path portion before handling things within:

handle_path /vl1/* {
	redir * /scm/hg/volumes/1/{uri} 302
}

Keep in mind though that handle_path has a different (lower) directive order than redir, so make sure to run caddy adapt --pretty on your config to make sure the handle is positioned in the right place in your config.

Next time, please fill out the help topic template, as per the forum rules. Without it, I have to make assumptions and I can’t fully answer your question. I don’t know what version you’re on, and I don’t know your config, so I can’t suggest whether handle_path is an appropriate solution contextually. It depends on what else you have in your config whether it’ll just work or whether you’ll need to make other changes to make it fit.

1 Like

Your suggestion works as expected. Thank you!

The only thing I had to change for the ideal result is to remove the unneeded / symbol before the {uri} (source URI already contains it, otherwise there will be a duplicate):

handle_path /vl1/* {
	redir * /scm/hg/volumes/1{uri} 302
}
2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.