To route traffic to https://example.com
... what's are the pros and cons of these two approaches?
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(. )$
RewriteRule (.*) https://%2%{REQUEST_URI} [R=301,NE,QSA]
vs.
RewriteCond %{SERVER_PORT} 80 [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(. )$
RewriteRule (.*) https://%2%{REQUEST_URI} [R=301,NE,QSA]
Also, is there any effective difference between (.*)
and ^(.*)$
in the RewriteRule?
CodePudding user response:
The only difference between those two rule blocks is the first condition:
RewriteCond %{HTTPS} off [OR]
vs
RewriteCond %{SERVER_PORT} 80 [OR]
The first condition checks whether HTTPS is off
(regardless of server port) and the second condition specifically checks the server port that the request is being made to. Port 80 is the default port for HTTP (ie. not HTTPS).
So, if you are serving HTTP over the default port then there is effectively no difference between those two conditions. If you are not serving HTTP over the default port then the first condition will still work (as this is derived by the server), however, the second condition would need to be modified to the appropriate port number.
Also, is there any effective difference between
(.*)
and^(.*)$
in theRewriteRule
?
No difference, since regex is greedy by default and the *
quantifier will consume as much of the string (URL-path in this case) as possible. The reason you see ^(.*)$
a lot in the wild is just personal preference or blind copy/pasting.
However, in this case the surrounding parentheses are also unnecessary, since you are not making use of the captured backreference (ie. $1
). You just need .*
- although even that is not optimal since it unnecessarily traverses the entire URL-path. You don't need to match anything, you just need the rule to be successful. ie. ^
or .?
or $
would suffice and be more efficient.
RewriteRule (.*) https://%2%{REQUEST_URI} [R=301,NE,QSA]
The QSA
flag is entirely redundant here since the query string is passed through by default.