all of them have redirected
http://sub.example.com
To https://www.sub.example.com
That would seem to suggest that you have a rule that simply checks for the absence of www
(which is correct for the first rule, but would conflict with the second) and then prefixes this to the requested host.
I assume you also want to redirect http://example.com/<something>
to https://www.example.com/<something>
etc?
Try the following at the top of your .htaccess
file:
RewriteEngine On
# www.example.com
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{HTTP_HOST} !(www\.)?sub\.example\.com
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
This basically states... for all requests that are HTTP (ie. not HTTPS) OR are for example.com
AND is not for sub.example.com
(or www.sub.example.com
) then redirect to https://www.example.com/...
.
Then add a similar rule block for the subdomain canonicalisation:
# sub.example.com
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} ^www\.sub\.example\.com [NC]
RewriteCond %{HTTP_HOST} !(www\.)?example\.com
RewriteRule (.*) https://sub.example.com/$1 [R=301,L]
Make sure you've cleared the browser cache before testing, since your earlier (erroneous) 301 redirects will have been cached. (It can often be easier to test with 302s for this reason.)
UPDATE: can I do a wildcard on the subdomain?
A subdomain of 1 or more characters...
# www.example.com (wildcard subdomain)
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{HTTP_HOST} !(www\.)?[a-z0-9-]+\.example\.com
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
# <any-subdomain>.example.com
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} ^www\.[a-z0-9-]+\.example\.com [NC]
RewriteCond %{HTTP_HOST} !(www\.)?example\.com
RewriteCond %{HTTP_HOST} ^(?:www\.)?([a-z0-9-]+)\.example\.com [NC]
RewriteRule (.*) https://%1.example.com/$1 [R=301,L]
The additional RewriteCond
directive for the subdomain block is required in order to capture the subdomain so we can use this in the RewriteRule
substitution (%1
backreference). The (?:www\.)?
part of the CondPattern is a non-capturing group that makes the www
sub-subdomain optional, since we need to be able to redirect sub.example.com
(HTTP) or www.sub.example.com
(HTTP or HTTPS).
The %1
backreference in the RewriteRule
substitution matches the first captured group in the last matched CondPattern.