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 RewriteCond
s, 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.