Order of mod_rewrite rules in .htaccess not being followed

We're trying to enforce HTTPS on certain URLs and HTTP on others. We are also rewriting URLs so all requests go through our index.php. Here is our .htaccess file.

# enable mod_rewrite
RewriteEngine on

# define the base url for accessing this folder
RewriteBase /

# Enforce http and https for certain pages
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# rewrite all requests for file and folders that do not exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?query=$1 [L,QSA]

If we don't include the last rule (RewriteRule ^(.*)$ index.php?query=$1 [L,QSA]), the HTTPS and HTTP rules work perfectly however; When we add the last three lines our other rules stop working properly.

For example if we try to goto https:// www.domain.com/en/customer/login, it redirects to http:// www.domain.com/index.php?query=en/customer/login.

It's like the last rule is being applied before the redirection is done and after the [L] flag indicating the the redirection is the last rule to apply.

UPDATE

We added [NS] flags to all our rules but it made no difference.


Your first two rules are hitting it the first time and then making an additional request (because of the 301), which will hit the third RewriteRule on re-entry. Try this one instead: I added an exception for your "checkout" path:

# enable mod_rewrite
RewriteEngine on

# define the base url for accessing this folder
RewriteBase /

# Enforce http and https for certain pages
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(en|fr)/(customer|checkout)(.*)$ [NC]
RewriteRule ^(.*)$ index.php?query=$1 [L,QSA]

Hope that helps!