We’ve built a new site for a client and now it’s live, we need to redirect a bunch of old URLs to a their new equivalents while maintaining the end of the path, no matter how deep it goes from this point. Seems like it should be simple enough. The caddy file currently looks like this…
And many, many variations on that theme, using full paths, with and without domains on both sides of the directive and so on. Everything I’ve tried, the request still gets proxied to the Django app, which then serves a 404. Am I doing Caddy wrong?
Was probably a cause of some issue. Placeholders can’t be used in a site label in this way. A placeholder is not a matcher or a substitution, either - placeholders are set in the context of a request and are available to middlewares that are designed to use them.
As such, it’s difficult, but doable, to redirect in this manner. The redir directive has no means to manipulate the URI by itself dynamically, but it can make use of existing placeholders.
rewrite takes place before redir, can manipulate the URI with substitutions, and can provide a {rewrite_uri} placeholder. We’ll need to make use of it like so (the following example is untested):
https://example.com {
rewrite /some_old_path {
r ^/some_old_path(.*)/?$
to /a-new-path{1}
}
redir {
# check if we just did a rewrite
if {rewrite_uri} starts_with /a-new-path
# redirect client to location we rewrote to dynamically
/ {rewrite_uri} 301
# alternately specify host:
# / https://example.com{rewrite_uri} 301
}
# additional site config
...
}
Won’t work, because the [from] is matching the URI, not the entire URL. Strip the host/scheme from that and it would function, but not how you think (refer: {path} is not a matcher or substitution, above).
I won’t be in a position to assist much further for the next few days, but on a hunch, try my example but without the basepath on the rewrite (i.e. rewrite { instead of rewrite /oldpath {). Everything else looks correctly configured, that’s the only thing I don’t usually do (I added it to this example to try and avoid unnecessary regex checks, the basepath is a pre-regex substring check).