I’m trying to implement the following mod_rewrite rule:
host.com/developer/ => host.com/developer/index.py
host.com/developer/branchX => host.com/developer/index.py?branch=branchX
host.com/developer/branchX/commitY => host.com/developer/index.py?branch=branchX&commit=commitY
Currently, the appropriate config section looks like this:
Options FollowSymLinks AllowOverride None RewriteEngine on RewriteRule ^([^/]+)$ /$1/index.py [L] RewriteRule ^([^/]+)/([^/]+) /$1/index.py?branch=$2 [L] RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ /$1/index.py?branch=$2&commit=$3 [L]
However, after the URL has been initially rewritten, an internal redirect occurs and the URL is being rewritten again, ruining it. The process repeats many times and eventually results into a 500 error. The log (timestamps and perdir parts removed):
[..initial] (3) strip per-dir prefix: /home/www/host.com/master/a -> master/a [..initial] (3) applying pattern '^([^/]+)$' to uri 'master/a' [..initial] (3) strip per-dir prefix: /home/www/host.com/master/a -> master/a [..initial] (3) applying pattern '^([^/]+)/([^/]+)' to uri 'master/a' [..initial] (2) rewrite 'master/a' -> '/master/index.py?branch=a' [..initial] (3) split uri=/master/index.py?branch=a -> uri=/master/index.py, args=branch=a [..initial] (1) internal redirect with /master/index.py [INTERNAL REDIRECT] [..initial/redir#1] (3) strip per-dir prefix: /home/www/host.com/master/index.py -> master/index.py [..initial/redir#1] (3) applying pattern '^([^/]+)$' to uri 'master/index.py' [..initial/redir#1] (3) strip per-dir prefix: /home/www/host.com/master/index.py -> master/index.py [..initial/redir#1] (3) applying pattern '^([^/]+)/([^/]+)' to uri 'master/index.py' [..initial/redir#1] (2) rewrite 'master/index.py' -> '/master/index.py?branch=index.py' [..initial/redir#1] (3) split uri=/master/index.py?branch=index.py -> uri=/master/index.py, args=branch=index.py
How can I fix my rules to prevent the endless internal redirects? Thanks.
The problem is that the url you are rewriting to is matched in the next pass. L specifies the last rule but only for this execution of the rules, URLs are processed again under certain circumstances (in this case, internal redirects). The solution is to add a RewriteCond to prevent looping, like this: