Rewrite to different path if file doesn't exist

(Thomas Boerger) #1

I’ve got some document root which gets listed by the browse directive, now I want to rewrite it to a different root path(from /var/www/app to /var/www/legacy) if a requested file doesn’t exist, but it always results in a 404.

Have somebody already done something like that? Got somebody an idea how to solve that?

I also tried to move the other folder into the document root and hide it with the internal directive, but rewrite to it also results in 404.

Thanks in advance.

(Matt Holt) #2

Timely question, I am currently tackling this design problem for Caddy 2 today.

I’m not sure if it’s possible in Caddy 1, or at least, not obvious; what have you tried?

(Thomas Boerger) #3

So far I have tried it with an approach similar to this, without the success. Would it be possible to fall back with a rewrite to legacy if the file doesn’t exist within current with a custom plugin/directive?

mkdir -p current legacy

echo "Foo" >| current/foo.txt
echo "Bar" >| legacy/bar.txt

cat << EOF >| Caddyfile
:8080/legacy {
  root legacy
  browse
  log / stdout
  errors stderr
}

:8080 {
  root current
  browse
  log / stdout
  errors stderr

  rewrite {path} {path}/ /legacy/{path}

  redir {
    if {uri} not {rewrite_uri}
    / {rewrite_uri}
  }
}
EOF

(Matthew Fay) #4

Consider instead setting your root to a common containing folder, in this case presumably /var/www, and rewriting to content in each as appropriate.

:8080 {
  root /var/www
  browse
  log stdout
  errors stderr

  rewrite {
    to /current{path} /current{path}/ /legacy{path} /legacy{path}/
  }
}

Effectively this results in “try files and folders in ./current, then try files and folders in ./legacy, then 404 out”.

It’s worth cautioning regarding the use of /var/www as the root - if you don’t explicitly rewrite every single request into the subfolder you want, someone could traverse to other folders in there. But as long as you’re careful, this will work.

3 Likes
(Thomas Boerger) #5

Thanks, a great idea. This seem to work fine so far.