The problem here is that the L flag causes a restart of the rewriting process with the rewritten URL (I’ve already told you that, didn’t I?):
Remember, however, that if the RewriteRule
generates an internal redirect (which frequently occurs when rewriting in a per-directory context), this will reinject the request and will cause processing to be repeated starting from the first RewriteRule
.
Now when /about
is requested, the first rule get’s applied and redirects to /about/
. The subsequent request of /about/
is then processed, at first the third rule is applied and the URL path is rewritten to /page.php
. So far, so good.
But now the internal redirect takes place and the rewriting process is restarted with the new URL path /page.php
. This is then fetched by the first rule again and redirected externally to /page.php/
.
The second rule shouldn’t be applied at all as the pattern ^/
should never match as the per-directory path prefix is removed before testing the pattern when using mod_rewrite in an .htaccess file:
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done.
But these rules should work:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .*[^/]$ /$0/ [L,R=301]
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$ [NC]
RewriteCond %1 !=www [NC]
RewriteCond $0/%1 !^([^/]+)/\1$
RewriteRule ^[^/]* /%1%{REQUEST_URI} [L]
RewriteCond %{HTTP_HOST} !=www.example.com [NC]
RewriteCond $1 !.*\.(php|css|js|png|jpg|gif|htm|html)$
RewriteRule .* page.php?q=$0 [L]