I’m a mod_rewrite newbie. I want to force HTTPS for certain directories and HTTP for the rest of the site. I can get HTTPS working but as the site links are all relative, when in a secure section the whole site is served via HTTPS. Hope that makes sense.
As you can see I redirect everything to a PHP file which handles the URL. If I force http:// I tend to get index.php at the end of the URL instead of the rewritten URL.
Thanks for your help but when I add that I get an internal server error message. Could you help with where this should go? I’ve tried a few positions but no joy.
Just to clarify what I’m trying to achieve:
force /members/ and /store/ into HTTPS
force the rest of the site into HTTP
but I want to direct all URL requests (for both HTTPS adn HTTP) to index.php
If I add a back reference into line two of this block:
What you’d had in your code (WAY) above almost made sense - at least, the middle two sections did (the first should cause a loop and the fourth … well, I just don’t like redirecting everything to one file like that so you can label that a personal problem).
If you’re NOT using Apache 2.x, your regex needs a / after the Start anchor.
If you’re so keen on keeping “the URL fragment,” why not capture it in an atom and feed it to index.php in a query string?
HTTPS is served for the whole site when in a secure section (ie links to non-secure areas are stilled served via HTTPS rather than HTTP)
I’m running Apache 1.3 and have tried the / and without. I did read that / don’t work with .htaccess. Is this true or have I put it in the wrong place?
I’ve put the:
RewriteRule (.*) http://www.wamt.org/$1 [R,L]
which fixes the .org.uk to .org redirect but I still can’t get non-secure sections to be served via HTTP.
isn’t being matched. If I comment it out I get an HTTPS/HTTP loop for the store and members sections. But if I type https:// for another section it is redirected to serve it as http:// so the rest of that code block works.
It’s weird as it is wokring in the code block for forcing HTTPS.
Let me modify slightly rather than trying to comment on your code:
RewriteEngine on
# SSL here
# Ensure correct host
RewriteCond %{HTTP_HOST} www.example.org.uk [COLOR="Blue"][NC][/COLOR]
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/(members|store)(.*) https://%{HTTP_HOST}/$1$2 [R,L]
# not anywhere else [COLOR="Red"]AND redirect to .org[/COLOR]
[COLOR="Blue"]RewriteCond %{HTTP_HOST} www.example.org.uk [NC][/COLOR]
RewriteCond %{SERVER_PORT} ^443$
RewriteCond !^/(members|store) [NC]
RewriteRule .? http://www.example.org%{REQUEST_URI} [R,L]
# Redirect everything to index.php for processing
RewriteRule !(\\.gif|\\.jpe?g|\\.png|\\.css|.ico|\\.php|\\.pdf|\\.doc|\\.html|members/forum/.*|media_assets/.*|js/.*|files/.*)$ index.php [NC,L]
That’s nonsense! A1.x REQUIRES the / after the start anchor (in DocumentRoot while A2.x believes it’s already there - “^/?” handles both servers nicely.
Thanks again for your help. For whatever reason I can’t get your code to work. It looks like it should but despite various re-jigs, it doesn’t work for me.
This code:
RewriteEngine On
# Ensure correct host
RewriteCond %{HTTP_HOST} www.example.org.uk
RewriteRule (.*) http://www.example.org/$1 [R=301]
# SSL here
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/?(members|store)(.*) https://%{HTTP_HOST}/$1$2 [R,L]
# not anywhere else
RewriteCond %{SERVER_PORT} ^443$
RewriteCond !^/?(members|store)(.*) [NC]
RewriteRule .? http://www.example.org%{REQUEST_URI} [R,L]
# Redirect everything to index.php for processing
RewriteRule !(\\.gif|\\.jpe?g|\\.png|\\.css|.ico|\\.php|\\.pdf|\\.doc|\\.html|members/forum/.*|media_assets/.*|js/.*|files/.*)$ index.php [NC,L]
does everyhting* I want EXCEPT force HTTP where required.
It seems that the last rule is overriding the force HTTP code block. When I comment it out I can see HTTPS forced to HTTP but obviously the site stops working as the CMS works off the URL fragment.
Actually, I’d expect your last block to rewrite to the index.php IN THE REQUESTED DIRECTORY LEVEL which is, probably, NOT the desired effect. Add the R=301 flag to the last RewriteRule to see where it’s sending you (GREAT testing technique). If you change index.php to /index.php, you’ll UNDO all the https redirects above so do NOT do that![indent]Gawd! I hate these CMS redirects![/indent]
I get a loop between HTTPS and HTTP in the ‘secure’ sections. So either this line isn’t being matched (odd, as it is matched in the preceding block) or another rule is overriding it.
If I add R=301 to the last rewrite rule, I get redirected to the index.php file in my root directory which is what I’d expect and want.
I guess I’ll just have to leave visitors on HTTPS which I’d rather not but I can’t see a way round this.
I must’ve been rushing and didn’t check that RewriteCond - it was DEAD wrong and I have no valid excuse! Mea culpa! Please give the updated code a try (delete the red bits, too).
That’s what the last RewriteRule is doing. Add the exclusion RewriteCond %{SERVER_PORT} !^443$ before the last RewriteRule and the https will not get redirected to index.php. I’d thought that was weird but I don’t know exactly what you’re trying to do (nor why you’re doing it that way).
If I do that I get a 404 error for the secure sections.
To explain how my system works:
x. ALL page requests (secure and non-secure) are handled by index.php, so everything needs to end up there
x. the system uses clean URLs and loads the required classes based on what the URL fragment contains:
– /store/ (load the store class)
– /members/ (load the members class)
– /photos/ (load the photo gallery class)
– /section/page-title (load the normal content class)
x. this works extremely well normally (on many sites) but it seems whatever .htaccess rule forces https to http (where https isn’t required) is overridden.
how can I force https and http and redirect all requests to index.php?
If there is a simpler rule (or rules for each instance) or way of doing this, that will ensure all requests are eventually handled by index.php I’d be happy to try it out.
Sort {HTTPS} by requested directory (on = store and members - all others null) then redirect to index.php (which becomes the exclusion, not {HTTPS}).[indent]HTTPS is on with $_SERVER[‘SERVER_PORT’] 443 but does not exist (null) with :80.[/indent]