views:

147

answers:

4

I have a client project where I need to force HTTPS for a certain folder and force HTTP for all others. I can sucessfully enforce HTTPS for the folder I desire but then all links back to the rest of the site end up being through HTTPS. I'd like to have a rule which forces requests for anything 'not' in the secure folder to be forced back to HTTP. Here's what I have so far:

RewriteEngine On
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]

RewriteCond %{HTTPS} !=on
RewriteRule ^(my) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1

'my' is the name of the folder that I need to force HTTPS for.

Any ideas?

Update: I also tried:

RewriteEngine On
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]

# Force HTTPS for /my
RewriteCond %{HTTPS} !=on
RewriteRule ^(my) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Force HTTP for anything which isn't /my
RewriteCond %{HTTPS} =on
RewriteRule !^my http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Remove index.php from URLs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1

But instead of requests for /my being forced through HTTPS they now just resolve to http://www.example.com/index.php/my

:?

A: 

Just invert the conditions:

RewriteCond %{HTTPS} =on
RewriteRule !^my http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]
Gumbo
Hi ya, thanks for the speedy reply. I tried that but I wasn't sure where to place it in the flow of my existing rules, any pointers? If I place it above the existing 'Force HTTPS' rule it prevents the 'Force HTTPS' from working and also prevents the final rule which rewrites index.php from executing. :?
Nathan Pitman
@Nathan Pitman: No, since they have different matching conditions they should not interact.
Gumbo
ok, I tried what you suggested (see the update to my original post) but this didn't work. I can see that it 'should' but I think I perhaps have the rules in the wrong order or certain rules are causing the rewrite to terminate before other conditions and rules can be evaluated... :/
Nathan Pitman
@Nathan Pitman: Or you didn't mention that you're defining the rules in `httpd.conf` (or similar) and everyone assumed it was in `.htaccess`, in which case you need to make sure all the test patterns match `^/`, e.g. `^/my` (I might be wrong though, it was just a thought)
Tim Stone
Hi Tim, yea this is being defined in .htaccess
Nathan Pitman
A: 

This is something that works from an old client website and could be adaptable for your purposes:

#If https off and in the cart dir
RewriteCond %{HTTPS} =off [NC]
RewriteCond %{REQUEST_URI} ^/cart/(.*) [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/cart/%1 [R=301,L]

#If https on and not in cart dir    
RewriteCond %{HTTPS} =on
RewriteCond %{REQUEST_URI} !^/cart [NC]
#Above line actually used to read RewriteCond %{REQUEST_URI} !^/cart|media|images|thumbs|css|js [NC]
#to allow js/css/images to be served so there were no mixed ssl messages popping up to visitors
RewriteCond %{REQUEST_FILENAME} !index\.php$ [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]

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

Replacing cart with my perhaps

connrs
A: 

Give the following a try, should work for you:

RewriteEngine On

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/my
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/my
RewriteRule ^(.*)$ http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
A: 

Ah, of course. The problem lies in the fact that your rewrite ruleset will be reprocessed after it is transformed to index.php following the initial redirect. Using what you currently have, you need to additionally condition the redirections to make sure they don't get applied after the rewrite to /index.php/my.

Something like the following should do:

RewriteEngine On
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]

# Force HTTPS for /my
RewriteCond %{HTTPS} !=on
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/my [NC]
RewriteRule ^(my) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Force HTTP for anything which isn't /my
RewriteCond %{HTTPS} =on
RewriteCond %{THE_REQUEST} !^[A-Z]+\s/my [NC]
RewriteRule !^my http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Remove index.php from URLs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1
Tim Stone