What you have is perfectly OK and would need to be implemented that way (by redirecting to HTTPS on the same host) if you intend to implement HSTS.
However, to eliminate a double redirect when requesting http://example.com
, you should reverse those two rules. Otherwise, you'll get the following double redirect:
http://example.com
to https://example.com
tohttps://www.example.com
For example:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) https://www.example.com/$1 [L,R=301]
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
No need to repeat the RewriteEngine
directive.
No need to capture a backreference (ie. (.*)
) when it's not being used in the substitution. No need for the anchors ^
and $
since regex is greedy by default.
The other "style" inconsistency between the above rules, is that you are using a captured backreference ($1
) in the first RewriteRule
and the REQUEST_URI
server variable in the second. It makes no difference in how it works as it does the same thing in two different ways. But they are two different "styles" (as if written by two different people).
EDIT2:
I also have a subdomain - static.example.com
(non www). I would like to add SSL here and redirect WWW to non WWW (now users can access the site through www as well, ending up with URL like www.static.example.com
). I tried something like in EDIT2 (I just edited my post). Can you tell me what's wrong with that code?
RewriteCond %{HTTP_HOST} ^static.example\.com [NC]
RewriteRule (.*) https://static.example.com/$1 [L,R=301]
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Your first rule here is redirecting static.example.com
to static.example.com
(ie. no change) - so this will naturally result in a never ending redirect loop (the browser will eventually break with an error).
If you are wanting to redirect from www.static.example.com
then you should be checking for this in the RewriteCond
directive. For example:
RewriteCond %{HTTP_HOST} ^www\.static\.example\.com [NC]
RewriteRule (.*) https://static.example.com/$1 [L,R=301]
I don't know whether you are or not, but there is no need to repeat the HTTP to HTTPS redirect - providing you put the directives in the correct order.
So, in summary, with both redirects together:
RewriteEngine On
# Main domain non-www to www redirect
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) https://www.example.com/$1 [L,R=301]
# Subdomain www to non-www redirect
RewriteCond %{HTTP_HOST} ^www\.static\.example\.com [NC]
RewriteRule (.*) https://static.example.com/$1 [L,R=301]
# HTTP to HTTPS redirect
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]