Forum Moderators: phranque

Message Too Old, No Replies

Interfering RewriteRules

2 RewriteRules interfering with each other

         

HandyBiteSize

12:28 pm on Nov 17, 2006 (gmt 0)

10+ Year Member



Hi All

I have 4 RewriteRules in a .htaccess files, 2 of which are interfering with each other. They can each run fine individualy but if they are both on then on ewill fail depending on the order of the rules. I've tried playing with the [S=x] flag but my logic is failing me at the moment.

Heres the code


RewriteEngine on
RewriteRule ^images/(.*)$ - [L]

#RewriteCond %{HTTPS} on
#RewriteRule!^checkout$ [%{SERVER_NAME}%{REQUEST_URI}...] [R,L]

RewriteCond %{HTTPS}!=on
RewriteRule ^checkout(/?¦/.*)$ [%{SERVER_NAME}...] [R,L]

RewriteRule!^(index.php)$ /index.php

I'm trying to serve all requests from http except the page called by www.mydomain.com/checkout which should by over https.

In the current form above (with the 2 lines commented out) the switch to https works perfectly, but adding the lines back in (hoping to redirect request such as [mydomain.com...] to [mydomain.com...] cause an error (page returns a 302 which I wasnt expecting)

Ive tried experimenting with the flags, but I'm just guessing, not learning.

Any help would be much appreciated

jdMorgan

2:19 pm on Nov 17, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The first two rules will redirect to each other forever. This is because a redirect causes a new HTTP request, which has no "memory" of the previous HTTP request.

A redirect sends a response back to the client saying, "The resource your requested has moved; Ask for it again using this address." The response also contains the redirect target URL that you specify in your code. So, the client (browser, in this case) starts an entirely new request with the specified URL, and the server then invokes your other Rule, which redirects it right back to the first URL.

You will need to make the requests unique in some way other than the current request's HTTPS on/off status. Although it looks like it might defeat your purpose, using a unique URL for the checkout page(s) is the easiest way.

The third rule may be problematic as well, in that it passes all requests to index.php -- including requests for robots.txt, images and other media, included client-side scripts (JavaScript), stylesheets, compact privacy policy, sitemaps, etc. Normally, pass-to-script rewrites are a bit more selective...

Jim

HandyBiteSize

9:06 pm on Nov 17, 2006 (gmt 0)

10+ Year Member



Thanks jd

My head was thinking of the pattern part of the RewriteRule as another condition.

I've ended up with


RewriteCond %{HTTPS}!=on
RewriteCond %{REQUEST_URI} ^/checkout
RewriteRule / [%{SERVER_NAME}...] [R,L]

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI}!^/checkout
RewriteRule / [%{SERVER_NAME}%{REQUEST_URI}...] [R,L]

which seems to do exactly what i wanted

thanks again

jdMorgan

3:45 am on Nov 18, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmm... I missed the "!" character on the "!^checkout" pattern in your first post, so some of what I said isn't applicable, er... That is to say, some of it was wrong.

The pattern in the rule is part of the condition determining if the rule is executed.

The code you came up with should be entirely equivalent to:


RewriteCond %{HTTPS} !^on$
RewriteRule ^/checkout https://%{SERVER_NAME}/checkout [R,L]
#
RewriteCond %{HTTPS} ^on$
RewriteRule !^/checkout http://%{SERVER_NAME}%{REQUEST_URI} [R,L]

where the patterns in the two rules are perfect logical complements of each other, and all pattern-anchoring is consistent. I assume your code is located in httpd.conf, conf.d, or another server config file; If it's in .htaccess in your Web root directory instead, then remove the leading slashes from both RewriteRule patterns.

Jim