Help with multiple rewrites

Hey there!

Trying to stack multiple rewrites without success.
Basically the requirements are:

  1. Every path must redirect to path.php (e.g. /login → /login.php)
  2. But, if the path is /l/something, it must redirect to /l.php?i=something

Here’s what I tried, without success, both rules work independently but when I add both together, only the first one matches.

myhost.com {
    errors err.log
    root /var/www/html/sendy
    log access.log
    fastcgi / /var/run/php/php7.0-fpm.sock php



    rewrite {
            regexp ^/([a-zA-Z0-9-]+)$
            to {1}.php

            regexp ^/l/([a-zA-Z0-9/]+)$
            to /l.php?i={1}
    }
}

Any idea how to make it work?

Hi @Joe_Langlois, welcome to the Caddy community!

Try something like this untested example, using multiple rewrites where each rewrite excludes the conditions of the other:

example.com {
  rewrite /l/ { # use basepath to avoid unnecessary regex checking
    r ^/l/([a-zA-Z0-9/]+)$
    to /l.php?i={1}
  }
  rewrite { # use not_starts_with to exclude other rewrite condition
    if {uri} not_starts_with /l/
    r ^/([a-zA-Z0-9-]+)$
    to {uri}.php
  }
}

Can I confirm, then that only one rewrite is ever executed? I must admit that I started out with the idea that multiple rewrites could be executed successively (perhaps requiring the use of {rewrite_path} to carry the current state from one to the next). This would certainly make some things easier, but I can see why the design might be otherwise.

It could be useful to mention this in the documentation of rewrite to avoid confusion for others.

That’s correct, @pwhodges. The rewrite middleware is called relatively early on in the chain and it picks the first valid (i.e. passes if and regex checks) rewrite rule with the longest base path to execute before passing on to the next middleware.

https://github.com/mholt/caddy/blob/f1eaae9b0d4a6e37882ba2cd38cc842513c502cf/caddyhttp/rewrite/rewrite.go#L48-L55

So strictly speaking, if {uri} not_starts_with /l/ is unnecessary in the above example, but included for readability; since only one rewrite would run, it will either be the first when its conditions are met, or the second otherwise.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.