Turning HTTPS ON and OFF from .htaccess for certain directories

Hey SP,

I’ve tried to solve this issue before but couldn’t quite understand the help that was being offered, so I’m going to try again.

My goal is to have the .htaccess file forward the URL to https:<url> if the directory being browsed is /basket or /cms and vice versa, URL to http:<url> if the directory being browsed is not /basket or /cms. Currently what I have in my .htaccess forwards to https correctly, but not does forward back the other way. Any tips would be greatly appreciated.

This is my current .htaccess file

RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} ^/(basket|cms)\\/
RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(basket|cms)\\/
RewriteCond %{REQUEST_FILENAME} !\\.(gif|png|jpg|jpeg|css|js)$ [NC]
RewriteRule .? http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]


Why not just force everything over HTTPS? Loads cleaner and you never have to worry about a cookie leaking out.

We have our reasons unfortunately lol.


I note that you are aware that support files should not be redirected back to http from an https request so you are aware of the pitfall of forcing in both directions. :tup:

When Apache 2 first came out, it broke my mod_rewrite code by refusing to match the / after an opening ^ in the DocumentRoot. Since you have that in your mod_rewrite code, either you’re using Apache 1 or that is the likely problem (apart from unnecessarily escaping /'s which is not a problem, just a waste of your effort … and makes reading your code more difficult).

Finally, when you’re using http, {HTTPS} is null, not off. While !on should work, it didn’t so I recommend using {SERVER_PORT} instead (using port 80 for http and 443 for https). Try:

RewriteEngine on
RewriteCond %{SERVER_PORT} ^80$
RewriteCond %{REQUEST_URI} ^(basket|cms)/
RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} on
# or RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^(basket|cms)/
RewriteCond %{REQUEST_FILENAME} !\\.(gif|png|jpg|jpeg|css|js)$ [NC]
# You don't need the No Case flag if you're consistent in your use of lowercase file extensions
RewriteRule .? http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Basically, a very good job!



I copy-pasted your code, but everything worked as expected. The real problem must be elsewhere. One possible place to check is whether the secure server’s configuration will read htaccess files (the secured and unsecured server configuration may be different).

If you like, we can start a new thread to troubleshoot this former issue of yours, because not even Apache 1.3 will match a leading slash from an htaccess file.

The value will indeed be “off”. This is confirmed by the documentation:

HTTPS: Will contain the text “on” if the connection is using SSL/TLS, or “off” otherwise.

As well as by the logs:

RewriteCond: input=‘off’ pattern=‘!on’ => matched

Hey guys, I really appreciate all of the information that has been shared here. It got me thinking and I figured out what my issue was.

My domain is split into two versions a dev. subdomain and the www. live domain. I do all of my tests on the dev (development) subdomain and that’s where I had my .htaccess file that I was experimenting with. However I’ve been aware from earlier tests that when I turn on https://dev.domain.com that for some reason I’m actually browsing the live site. I presume that has to do with how the secure certificate is made. So to make a long story short, the issue was that the dev. .htaccess file was correctly forwarding me to HTTPS://, however once I did that I was now browsing the live site (even though it still said dev.domain.com in the URL!) and of course the www.domain had the old .htaccess file that would not switch back correctly. Very weird, but I’ve learned my lesson!

Thank you for your help.