Remove www site-wide, force https on certain directories and http on the rest?

Anthony picture Anthony · Nov 16, 2010 · Viewed 19.6k times · Source

Firstly, I would like to remove the www. from my domain name

http://www.example.com => http://example.com

I would also like for certain directories to be secure (https), while the rest remain http

http://example.com/login => https://example.com/login

Obviously it needs to work for all conditions, for example if someone types in:

http://www.example.com/login => https://example.com/login

Also when people navigate away from the login page it returns to http. Currently in the .htaccess is the following which is done automatically by the software I am using and I suppose needs to be there for it to work:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ./index.php

Any ideas on how I can achieve dream control all these things?

Thanks in advance!

===================

@Gumbo Following your advice this is my complete .htaccess

RewriteEngine On


# remove www from host
RewriteCond %{HTTP_HOST} ^www\.(.+)
RewriteCond %{HTTPS}s/%1 ^(on(s)|offs)/(.+)
RewriteRule ^ http%2://%3%{REQUEST_URI} [L,R=301]

# force HTTPS
RewriteCond %{HTTPS} =off
RewriteRule ^(login)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# force HTTP
RewriteCond %{HTTPS} =on
RewriteRule !^(login)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]


RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ./index.php


Options -Indexes

Navigating to http://example/login still goes to http://example/index.php when it should go to https://example/login Do I have the order wrong?

Answer

Gumbo picture Gumbo · Nov 16, 2010

Try these rules:

# remove www from host
RewriteCond %{HTTP_HOST} ^www\.(.+)
RewriteCond %{HTTPS}s/%1 ^(on(s)|offs)/(.+)
RewriteRule ^ http%2://%3%{REQUEST_URI} [L,R=301]

# force HTTPS
RewriteCond %{HTTPS} =off
RewriteRule ^(login|foo|bar|…)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# force HTTP
RewriteCond %{HTTPS} =on
RewriteRule !^(login|foo|bar|…)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

You also might want to add some additional conditions to only change the protocol on GET and HEAD requests but not on POST requests.