Reputation: 36514
I want to rewrite the path /health
to /health.php
.
I currently have have the following .htaccess
file, with a catch-all rule:
RewriteEngine On
RewriteRule ^.*$ index.php [L]
So I just added a new rule before the catch-all:
RewriteEngine On
RewriteRule ^health$ health.php [L]
RewriteRule ^.*$ index.php [L]
But to my surprise, it doesn't rewrite to health.php
when I request /health
in the browser.
However, when I remove the last (catch-all) rule, it works as expected.
Why doesn't mod_rewrite stop processing rules after matching a rule with the [L]
flag?
Upvotes: 2
Views: 774
Reputation: 36514
Found it. I always thought that the [L]
flag stopped the processing of all the rules, period. Actually, it just stops processing rules in the current ruleset, but then re-runs the whole ruleset on the rewritten request.
Hence, my catch-all code was finally catching it, as the rewrite log shows:
strip per-dir prefix: [...]/public/health -> health
applying pattern '^health$' to uri 'health'
rewrite 'health' -> 'health.php'
add per-dir prefix: health.php -> [...]/public/health.php
strip document_root prefix: [...]/public/health.php -> /health.php
internal redirect with /health.php [INTERNAL REDIRECT]
strip per-dir prefix: [...]/public/health.php -> health.php
applying pattern '^health$' to uri 'health.php'
strip per-dir prefix: [...]/public/health.php -> health.php
applying pattern '^.*$' to uri 'health.php'
rewrite 'health.php' -> 'index.php'
add per-dir prefix: index.php -> [...]/public/index.php
strip document_root prefix: [...]/public/index.php -> /index.php
internal redirect with /index.php [INTERNAL REDIRECT]
strip per-dir prefix: [...]/public/index.php -> index.php
applying pattern '^health$' to uri 'index.php'
strip per-dir prefix: [...]/public/index.php -> index.php
applying pattern '^.*$' to uri 'index.php'
rewrite 'index.php' -> 'index.php'
add per-dir prefix: index.php -> [...]/public/index.php
initial URL equal rewritten URL: [...]/public/index.php [IGNORING REWRITE]
The solution, found on this blog, involves putting a conditional before the catch-all rule, to only execute it when no internal redirect has been processed before:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^.*$ index.php [L]
Upvotes: 5