1

Million times asked question, but after reading many of the answers here on SO I still can't figure this out. I need to redirect all requests like below:

  1. http://domain.tld > https://domain.tld
  2. http://www.domain.tld > https://domain.tld
  3. https://www.domain.tld > https://domain.tld
  4. http://sub.domain.tld > https://sub.domain.tld (when .htaccess placed in subdomain folder)

Until now, I was using the code from html5boilerplate, that solved www to non-www

<IfModule mod_rewrite.c>
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^(.*)$ http://%1/ [R=301,L]
</IfModule>

they also have a code for http to https redirect, but after adding this piece of code (above the www redirect), page is loading and after a timeout it shows error/too many redirects

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} !=on
  RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

I've also tried examples like this SO answer but still the website doesn't work. Only solution for now is to use the first piece of code and replace http with https but that doesn't solve most important redirect (1)

current full .htaccess content:

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)\/$ /$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule /?([A-Za-z0-9_-]+)/?$ index.php?id=$1 [QSA,L]

    #RewriteCond %{HTTPS} off [OR] #by uncommenting this, site stops working
    RewriteCond %{HTTP_HOST} ^www
    RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$
    RewriteRule ^ https://%1%{REQUEST_URI} [R,L]
</IfModule>
Community
  • 1
  • 1
moped
  • 2,197
  • 2
  • 24
  • 30

2 Answers2

2

To redirect to https and non-www in a single http request, you can use

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

Clear your browser's cache before testing this rule.

Amit Verma
  • 40,709
  • 21
  • 93
  • 115
  • Tried it, but still I get "ERR_TOO_MANY_REDIRECTS" in Chrome, after Clean Cache and Hard Reload. I get https://domain.tld correctly, but after that, it's loading and throws error – moped Sep 04 '16 at 14:03
  • Are you using cloud flare? – Amit Verma Sep 04 '16 at 14:05
  • No, I'm not using CF or any other CDN. I just installed Let's Encrypt certificate and wanted to use it (it works fine if I go directly to https: page or use www.domain) – moped Sep 04 '16 at 14:07
1

Sometimes, depending on some server configuration, it appears that HTTPS variable is always set to off. That would explain the loop, and i've already seen a similar case here on SO.

A simple workaround would be to test SERVER_PORT (if you use default 80 and 443) or you could also test HTTP:X-Forwarded-Proto.

Example (1) to test if it is not https:

RewriteCond %{HTTP:X-Forwarded-Proto} !https

Example (2) to test if it is not https:

RewriteCond %{SERVER_PORT} !403
Justin Iurman
  • 18,954
  • 3
  • 35
  • 54
  • Thank you Justin, example 1 works perfectly on all hostings, example 2 behaves the same as others, too many redirects – moped Sep 13 '16 at 08:11
  • so, on one hosting, example 2 works and example 1 doesn't. good to have all possible solutions to it! – moped Sep 13 '16 at 10:41