80

I'm trying to redirect https://www.example.com to http://www.example.com. I tried the following code in the .htaccess file

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

This code successfully redirects https://example.com to http://www.example.com. However when I type in https://www.example.com then it gives me a "web page not available" error in the browser.

I have also tried the following 2 codes without success

Attempt 1

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*):NOSSL$ http://www.example.com/$1 [R=301,L]

Attempt 2

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}

Both above attempts failed. Any suggestions?

BiscuitBaker
  • 1,421
  • 3
  • 23
  • 37
Ansh
  • 1,121
  • 2
  • 12
  • 13

7 Answers7

132

Attempt 2 was close to perfect. Just modify it slightly:

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

UPDATE:

Above solution works from a technical point of view. BUT:

Since a few years now the user will receive a huge warning indicating that the connection is not private. That is to be expected: none of today's browsers will silently switch from an encrypted to a not encrypted connection, for obvious reasons ... You cannot get around that behavior of standard browsers. That however has nothing to do with the redirection itself. It is how the web works today, how users are protected from criminal intents.

arkascha
  • 41,620
  • 7
  • 58
  • 90
  • 11
    Will be good to use `R=302` if you don't wish to make _permanent_. This landed me in trouble when my SSL expired and I wanted to temporarily move back to `http` before I go through the painful renewal procedures. – ProfNandaa Sep 11 '16 at 15:02
  • Painful renewal? Should be either a flip of certificare files or a simple script execution... The issue with 302 is that clients have to follow it each time, so you raise the number of requests for client and server side. – arkascha Sep 11 '16 at 15:31
  • @arkascha Just wanted to understand, the RewriteCond will act as a if statement write? I mean only where it finds https it will run next rewrite rule. I am asking since Google has automatically taken a couple of https url in its index without us linking them from anywhere. Hence to rule out any miscong we are using the code above to 302 all https url – Ankur Jain Sep 14 '16 at 03:07
  • You are basically correct. It certainly does make sense for you to take a look into the excellent documentation:http://httpd.apache.org/docs/current/mod/mod_rewrite.html – arkascha Sep 14 '16 at 06:04
  • Apart from that: google indeed prefers ssl variants of urls, if it can find them. With very good reasons. I dont see a reason why you would want to prevent that... – arkascha Sep 14 '16 at 06:05
  • This works fine for www and non www redirection from https to http. – frank_108 Jun 02 '19 at 20:26
  • @arkascha, Is this working in 2020? I tested this code and it's working on firefox but not working in chrome. – Naren Verma Jul 26 '20 at 02:39
  • This has nothing to do with a browser. Rewriting operates on the server side. It handles requests. So yes, this works in 2020. Maybe you were looking at a cached result when testing with the chrome browser. – arkascha Jul 27 '20 at 18:54
  • @arkascha, I tested this code but I am getting the error. The connection has timed out. some time Your connection is not private – user9437856 Dec 18 '21 at 11:13
  • @user9437856 I cannot say anything about the connection timeout, that has nothing to do with a redirection. The warning indicating that your connection is not private is to be expected: none of todays browsers will _silently_ switch from an encrypted to n unencrypted connection, _for obvious reasons_ ... You cannot get around that behavior of standard browsers. But again, this has nothing to do with the rewriting itself. It is how the web works today. – arkascha Dec 19 '21 at 08:40
  • @arkascha, When I add the above code then I am getting the error. – user9437856 Dec 19 '21 at 10:16
  • @user9437856 I very well understood that. But that does not change what I wrote as a reply to that. What you observe (the warning / error), is not the actual redirection, which apaprently works as expected. But the browser's reaction to that redirection. Nothing wrong with the code above, nothing wrong with your setup. But the situation has changed since 2012, that's all. In short: you cannot make a redirection from https to http anymore except in extremely special situations. – arkascha Dec 19 '21 at 20:03
  • @arkascha, Thank you for the explanation. I got your point. – user9437856 Dec 20 '21 at 07:13
  • I know the answer is too old but It's not working for me. – Naren Verma Feb 28 '22 at 13:25
  • @NarenVerma Did you _really_ read the comments here? Where I explain why that is not working any more? And why that actually is a _good_ thing? – arkascha Feb 28 '22 at 14:23
  • 1
    @arkascha, Yes, I read the comment. Can you update the same in the post? You can check the above comment. I also commented the same in 2020. So better for every once just updates your answer. It will help everyone. – Naren Verma Feb 28 '22 at 14:27
41

However, if your website does not have a security certificate, it's on a shared hosting environment, and you don't want to get the "warning" when your website is being requested through https, you can't redirect it using htaccess. The reason is that the warning message gets triggered before the request even goes through to the htaccess file, so you have to fix it on the server. Go to /etc/httpd/conf.d/ssl.conf and comment out the part about the virtual server 443. But the odds are that your hosting provider won't give you that much control. So you would have to either move to a different host or buy the SSL just so the warning does not trigger before your htaccess has a chance to redirect.

Adela Ruffatti
  • 439
  • 4
  • 2
  • 2
    Thank you for this answer. As our existing site don't have an SSL certificate so that's why no matter how correct my .htaccess is, it will not work. – marknt15 Mar 30 '15 at 04:38
  • @arkascha I've tried the various methods shared here but none worked. Yes I tested in on a shared environment. SSL is not active though a shared SSL is free. The https link in question was historic/inherited from a previously SSL-enabled environment. I don't mind the browser warning (in dev mode) but I needed the redirect at least to happen. Any one able to offer any more leads? – Pageii Studio Feb 25 '16 at 10:39
  • Valid answer. I wanted to redirect IE9 from https to http, because of incompatible security protocols (TLS 1.0 is not maintained anymore). But whatever I did, it didn't work. Caused by the fact that the security protocol comes into effect before the .htaccess commands. – Frank Conijn - Support Ukraine Jun 26 '18 at 19:29
  • I found out that the new Microsoft Edge works even on a shared host site. Firefox and Chrome continue to give the warning but the new Edge sees the .htaccess information before redirecting to a warning. The new Edge browser with the Chromium engine is awesome! – DrupalFever Jun 14 '20 at 02:31
  • Just for reference...I was looking for the solution because of the "false" https when the user types https on non-https site. The only way to redirect to http that worked for me was [using JS](https://stackoverflow.com/a/10036029/3027604). – Hitokage Nov 21 '22 at 11:31
12

You can use the following rule to redirect from https to http :

 RewriteEngine On


RewriteCond %{HTTPS} ^on$
RewriteRule ^(.*)$ http://example.com/$1 [NC,L,R]

Explanation :

RewriteCond %{HTTPS} ^on$

Checks if the HTTPS is on (Request is made using https)

Then

RewriteRule ^(.*)$ http://example.com/$1 [NC,L,R]

Redirect any request (https://example.com/foo) to http://example.com/foo .

  • $1 is part of the regex in RewriteRule pattern, it contains whatever value was captured in (.+) , in this case ,it captures the full request_uri everything after the domain name.

  • [NC,L,R] are the flags, NC makes the uri case senstive, you can use both uppercase or lowercase letters in the request.

L flag tells the server to stop proccessing other rules if the currunt rule has matched, it is important to use the L flag to avoid rule confliction when you have more then on rules in a block.

R flag is used to make an external redirection.

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Amit Verma
  • 40,709
  • 21
  • 93
  • 115
11
RewriteEngine On
RewriteCond %{SERVER_PORT} 443
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Auero
  • 153
  • 2
  • 9
4

The difference between http and https is that https requests are sent over an ssl-encrypted connection. The ssl-encrypted connection must be established between the browser and the server before the browser sends the http request.

Https requests are in fact http requests that are sent over an ssl encrypted connection. If the server rejects to establish an ssl encrypted connection then the browser will have no connection to send the request over. The browser and the server will have no way of talking to each other. The browser will not be able to send the url that it wants to access and the server will not be able to respond with a redirect to another url.

So this is not possible. If you want to respond to https links, then you need an ssl certificate.

drhema
  • 113
  • 8
1
RewriteCond %{HTTP:X-Forwarded-Proto} =https
the swine
  • 10,713
  • 7
  • 58
  • 100
0

Your code is correct. Just put them inside the <VirtualHost *:443>

Example:

<VirtualHost *:443>
  SSLEnable

  RewriteEngine On
  RewriteCond %{HTTPS} on
  RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}

</VirtualHost>