25

I know there are many similar threads, but none of them seems to match my exact problem. Here is what I’m trying to do:

(1) http://www.mydomain.com/ -> https://mydomain.com/
(2) http://mydomain.com/     -> https://mydomain.com/
(3) https://www.mydomain.com -> https://mydomain.com/

Ideally, I would also like to cover the situation if I will ever add more subdomains, to automatically behave like the following (preferably in a generic way that will work for any subdomain I add).

(4) http://sub.mydomain.com/ -> https://sub.mydomain.com/

At this point I’m wondering if it is even possible to create a single .htaccess file that does everything I need, although I have to admit that I understand regexes, but I’m not exactly a mod_rewrite uberpro.

Here are the solutions that I already tried:

My SSL certificate covers the www-subdomain, so I’m not looking for a 'untrusted connection' error solution, I’m aware that isn’t possible.

anubhava
  • 761,203
  • 64
  • 569
  • 643
sub_lunar
  • 363
  • 1
  • 3
  • 8

7 Answers7

28

I found most of the suggestions were not catching when you had something that was https://www.example.com and redirecting to https://example.com.

The following worked for all permutations:

RewriteEngine On

# match any URL with www and rewrite it to https without the www
RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]

# match urls that are non https (without the www)
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(www\.)(.*) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Hope this helps someone!

RCheesley
  • 406
  • 1
  • 4
  • 3
  • 1
    Worked for me as an `.htaccess` file; but still didn't redirect `https://www.example.com` to `https://example.com` when used in a `` block under a virtual host config file. Any idea how to adapt it for that case? – Jackson Sep 03 '16 at 06:08
  • Please disregard my last comment. My redirection logic was getting overwritten by another virtual host that letsencrypt (certbot) had generated; your rewrite rules worked for me when I added them to a `` block under both my `*:80` and `*:443` virtual hosts. – Jackson Sep 03 '16 at 18:17
  • This solution handles rewriting `https://www.example.com` to `https://example.com`. I also had to include this in both `*:80` and `*:443` virtual host to get it working. – kimbaudi Nov 28 '16 at 05:32
15

Put this code in your DOCUMENT_ROOT/.htaccess file:

RewriteEngine On

# remove www and add https
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301,NE]

# add https
RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Although that seems to do the job of redirecting everything to https://mydomain.com/, there seem to be too many redirections going on. In Detail, here’s what browsers tell me for (1) through (3), including the desired redirection target: Opera: 301 Moved Permanently. The document has moved here (link to https://mydomain.com/, leads to same result) Chromium: This webpage has a redirect loop Firefox: The page isn't redirecting properly. […] in a way that will never complete. May that be caused by the redirect=301 in the rewrite rule? – sub_lunar Jan 31 '14 at 01:00
  • Sorry, I’m still getting the same issues. I hope it’s not something else that I’m doing wrong and am not aware of (of course I wiped all cached data, cookies and whatnot from my browsers before testing again). Maybe I’ll go with just forcing https and leaving the www-subdomain as a remainder of internet history ... maybe it’s not that important after all. Nevertheless, thank you very much for your efforts in writing me a nice universal htaccess-file, I appreciate it. – sub_lunar Jan 31 '14 at 15:29
  • Yep, I just tried a fresh new virtual machine with some new browsers, definitely without any history. Still getting the redirect loop :-( – sub_lunar Jan 31 '14 at 20:14
  • Here are screenshots of the http headers as shown in firebug of how I try to access, in that order: `http://www.edelextra.biz/`, `http://edelextra.biz/`, `https://www.edelextra.biz/` and `https://edelextra.biz` – there are always about 20 '301 Moved Permanently's until it stops trying. http://imgur.com/a/pbpcn – sub_lunar Feb 01 '14 at 10:03
  • Still no luck … well, the redirect loop is gone! But, so is the website :-) New screenshots! http://imgur.com/a/4G8kL – sub_lunar Feb 01 '14 at 12:56
  • It’s doing the looping again. http://imgur.com/a/XXDCk – But, please, I don’t want to be stealing your time here! As mentioned in my second comment, the www-subdomain is not my biggest problem right now, so if it’s impossible to do, just let it be ... maybe I’ll figure out how to do it someday when I have the time ;-) – sub_lunar Feb 01 '14 at 18:06
  • Still a loop, but no more redirection of www, apparently. http://imgur.com/a/kot4X – stop it! :-) – sub_lunar Feb 01 '14 at 18:41
  • 1
    Hm … seems to be more difficult than I expected. I have only static HTML files for testing in this new webspace, no CMS, CGI scripts or stuff using mod_rewrite that might interfere with the rules in this .htaccess. I opened a support ticket at my hoster now, told them what I’m trying to do and asked if they have any global configs that could be getting in my way. Let’s see what they say! – sub_lunar Feb 03 '14 at 22:17
  • 3
    Turns out that `%{HTTPS}` is a feature of mod_ssl, which isn’t running on my hoster’s machines. Instead, they use pound as HTTPS-frontend, which offers the environment variable `%{ENV:HTTPS}`. So I added a line to check for that and left the old in to work on legacy setups as well. My finally-working .htaccess looks like this now: `RewriteEngine On RewriteCond %{HTTPS} !=on RewriteCond %{ENV:HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE] RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301,NE]` – sub_lunar Feb 09 '14 at 14:19
  • Oh sorry, the linebreaks in my last post were omitted; but I think you get what I mean. Maybe you’ll like to include `RewriteCond %{ENV:HTTPS} !=on` in your otherwise perfectly working well-crafted code above, so I can mark this as answered! And thank you very much for your patience! – sub_lunar Feb 09 '14 at 14:21
  • Hi, this doesn't seem to be redirecting `http://domain.com` -> `https://domain.com`. Is it like this for anyone else? – Jack Aug 12 '15 at 18:07
  • @JackNicholson: Try commenting `RewriteCond %{ENV:HTTPS} off` line and retest. If it still doesn't work then please post a new question with more details. – anubhava Aug 12 '15 at 18:24
2

To Force using HTTPS

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

To Force www to non www

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.bewebdeveloper.com$
RewriteRule ^(.*) http://bewebdeveloper.com/$1  [QSA,L,R=301]
Taryn
  • 242,637
  • 56
  • 362
  • 405
rachid
  • 474
  • 1
  • 4
  • 8
2
RewriteEngine on


RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.([^.]+\.[^.]+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301,NE]

This script will redirect

to

while preserving the subdomain.

Amit Verma
  • 40,709
  • 21
  • 93
  • 115
2

I found the following answer would match to your requirement:

www to non-www with https but no other subdomains

RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Fulfill all of the three (3) conditions:

(1) http://www.example.com/ -> https://example.com/
(2) http://example.com/     -> https://example.com/
(3) https://www.example.com -> https://example.com/

but no other subdomains than www like so:

(4) http://others.example.com -> https://others.example.com/
(5) https://others.example.com -> https://others.example.com/
eQ19
  • 9,880
  • 3
  • 65
  • 77
1

just add this code in root .htaccess file

RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
user7688086
  • 421
  • 4
  • 5
0

Non of the examples worked for me, they just seemed to get stuck in a loop, the following works though.

    # match any URL with www and rewrite it to https without the www
    RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
    RewriteRule (.*) https://%2%{REQUEST_URI} [R=301,L]

    # match non https and redirect to https
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

The order matters, it will prevent a 3rd redirect in some cases.

If you want to use a sub domain (anything other than www.) just remove the first ruleset.

So for sub domains all you need is

    # match non https and redirect to https
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

I use Cloudways services and I've found this to be the only thing that works

Simon Ilett
  • 91
  • 1
  • 7