views:

43

answers:

1

I have some rewrite rules in my .htaccess that switches the domain to https if its a secure area. I want it to switch back to http if its not a secure area, heres my rules:

RewriteCond %{SERVER_PORT} =443
RewriteCond %{REQUEST_URI} !^/account(.*)$
RewriteCond %{REQUEST_URI} !^/shop/checkout(.*)$
RewriteRule ^(.*)$ http://www.domain.com/$1 [R,L]
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^account(.*)$ https://www.domain.com/account$1 [R,L]
RewriteCond %{SERVER_PORT} !^443$ 
RewriteRule ^shop/checkout(.*)$ https://www.domain.com/shop/checkout$1 [R,L]

# Route all traffic to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?_args=$1 [L,QSA]

the first 3 lines are uncommented as it resulting in a redirect loop. any help appreciated

+1  A: 

It results in a redirect loop because your RewriteCond pair will always evaluate to true. You first want to check that you're actually on the SSL port, then you want to make sure that the request doesn't match your secure paths.

Your three commented-out lines should therefore be changed to this:

RewriteCond %{SERVER_PORT} =443
RewriteCond %{REQUEST_URI} !^/account(.*)$
RewriteCond %{REQUEST_URI} !^/shop/checkout(.*)$
RewriteRule ^(.*)$ http://www.domain.com/$1

Edit: Apparently you do actually need the explicit [R,L] on that redirect. Additionally, mod_rewrite performs an internal redirection of the URL /index.php, which doesn't match the secure paths checked for by the RewriteConds, so the rewritten rule gets re-rewritten back to the http domain. The following should resolve both of these issues, albeit in a somewhat non-foolproof way:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{SERVER_PORT} =443
RewriteCond %{REQUEST_URI} !^/account(.*)$
RewriteCond %{REQUEST_URI} !^/shop/checkout(.*)$
RewriteRule ^(.*)$ http://www.domain.com/$1 [R,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(shop/checkout|account)(.*)$ https://www.domain.com/$1$2 [R,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)?$ index.php?_args=$1 [QSA]

People could still theoretically come in unsecured via http://www.domain.com/index.php?_args=account this way, so if that bothers you it's possible to write some more complex RewriteCond directives to handle that situation. It's a bit overkill though if you aren't worried about that. Unfortunately there's no good way that I'm aware of to know that an internal rewrite was performed, otherwise this would be much easier to account for.

Tim Stone
This didn't work for me, i get a redirect loop when moving to httpsalso i assume you meant port 443
mononym
Whoops, fixed. Also, the `REQUEST_URI` starts with a forward slash, which may have been preventing the `RewriteCond` from matching correctly, hopefully that should work now.
Tim Stone
still not working, i;ve edited my rules in my original question, any help appreciated
mononym
Alright, let's try this again. I setup a test scenario this time, so I've confirmed it does work on my end, at least.
Tim Stone
Tim, you the man! thanks a lot
mononym
No problem, glad to hear it's working!
Tim Stone