I'm working on something that should be really simple but hitting head against the wall second day. The URLs redirect requirements are:
- non-www => www
- non-https => https
/file.html
=>/utilities/template_handler.php?filename=file.html
The problem: when I request https://example.com/file.html
I get r=301 to
https://example.com/utilities/template_handler.php?filename=https://www.example.com/file.html
My .htaccess
:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301]
RewriteRule ^(.*)\.html$ /utilities/template_handler.php?filename=$1.html [NC]
I'm using litespeed webserver but for troubleshooting purpose set up Apache too, the same result. After debug is turned on I see:
strip base: '/' from URI: '/file.html'
Rule: Match 'file.html' with pattern '.*', result: 1
Cond: Match 'on' with pattern 'off', result: -1
Rule: Match 'file.html' with pattern '.*', result: 1
Cond: Match 'domain.com' with pattern '^www\.', result: -1
Source URI: 'file.html' => Result URI: 'https://www.example.com/file.html'
Rule: Match 'https://www.example.com/file.html' with pattern '^(.*)\.html$', result: 2
Source URI: 'https://www.example.com/file.html' => Result URI: '/utilities/template_handler.php?filename=https://www.example.com/file.html'
replace current query string with 'filename=https://www.example.com/file.html'
If I comment out the last rule I have first two requirements processed correctly.
The same error if the request sent to non-www or to www but non-ssl.
You need to include the
L
(last
) flag on both of theseRewriteRule
directives, otherwise, processing will continue through the file and the URL will get further rewritten by theRewriteRule
that follows (using the output from the previous directive). And since an external redirect has already been triggered by the preceding directives, you then get externally redirected to/utilities/template_handler.php?filename=....
, rather than internally rewritten.These directives should also be reversed to avoid an unnecessary double redirect when requesting a URL of the form
http://example.com/...
. (Particularly with the addition of theL
flag.)For example:
Note also, I've removed the
NC
flag from the negated!^www\.
condition. Since this is a negated regex, you want it to redirect when it does not startwww
- all lowercase. You still want "bad" requests of the formWwW
to be redirected - but if you include theNC
flag here they will not.You can include the
L
flag on the very lastRewriteRule
if you wish - although it would be good practise to do so. It is effectively implied, since it is the last rule anyway, but if you added more directives then you might need to remember to add it.