Forum Moderators: phranque

Message Too Old, No Replies

https to http redirect

         

sabastian130

12:49 pm on Sep 16, 2015 (gmt 0)

10+ Year Member



Hi guys.

I hope some one can help me. I have been searching every where but I can't find a simple answer.

I am using the following in my htaccess to redirect login and signup from http to https. I only want THESE TWO pages to redirect to https but the rest of my site needs to redirect to http and NOT https.

RewriteOptions inherit
DirectoryIndex index.php


RewriteCond %{REQUEST_URI} !^/(robots\.txt|favicon\.ico|sitemap\.xml)$
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
RewriteRule ^index.php(.*)$ http://www.example.com/$1 [r=301,nc]


RewriteEngine On
#
# Externally redirect http requests for confirm and checkout page to https
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^((confirm|checkout)\.php)$ https://%{HTTP_HOST}/$1 [R=301,L]
#
# Externally redirect https requests for everything except login and signup
# pages and the resources shared between http and https to http
RewriteCond %{SERVER_PORT} =443$
RewriteCond $1 !\.(gif|jpe?g|jpg|png|ico|css|js)$
RewriteCond $1 !^((confirm|checkout)\.php)$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]

With this code login and signup redirects from http to https. When I type in https://www.example.com it doesn't redirect to https://www.example.com but if I enter https://example.com it redirects to http://www.example.com perfectly. My images also doesn't redirect to http.

What am I doing wrong?

[edited by: Ocean10000 at 1:41 pm (utc) on Sep 16, 2015]
[edit reason] broke unintenial links [/edit]

sabastian130

2:57 pm on Sep 16, 2015 (gmt 0)

10+ Year Member



Ok I got the redirects to work using...

# Redirect secure pages to HTTPS if requested with HTTP
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^checkout.php?$ https://www.example.com/checkout.php [R=301,L]
#
# Redirect non-secure pages to HTTP if requested by HTTPS
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/checkout.php?$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

But now when I open https://www.example.com/checkout.php my SSL is not working and that my site does not supply identity information.

not2easy

3:02 pm on Sep 16, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



The target of a rewrite rule does not need escaping.
The rules are confusing and use poor syntax. In the first group of rules, you have two conditions and two rules, but the first rule stops further rules.
That last rule is sort of undoing some of the previous work. The domain name stays the same so you use "http://example.com/$1" as the target - but that also removes the www that was added before if it does manage to work.

sabastian130

3:07 pm on Sep 16, 2015 (gmt 0)

10+ Year Member



If I only use

# Redirect secure pages to HTTPS if requested with HTTP
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^checkout.php?$ https://www.example.com/checkout.php [R=301,L]

Then the checkout.php works perfectly. I do not know much about htaccess and I am struggling to get this to work. @not2easy what should I use because I've been going at this for two days now without getting any where. I simply want 3 pages to open with https only and the rest of my site to never open with https.

sabastian130

3:13 pm on Sep 16, 2015 (gmt 0)

10+ Year Member



I modified the coding to this...

RewriteOptions inherit
DirectoryIndex index.php


RewriteCond %{REQUEST_URI} !^/(robots\.txt|favicon\.ico|sitemap\.xml)$
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
RewriteRule ^index.php(.*)$ http://www.example.com/$1 [r=301,nc]

# Redirect secure pages to HTTPS if requested with HTTP
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^checkout.php?$ https://www.example.com/checkout.php [R=301,L]
#
# Redirect non-secure pages to HTTP if requested by HTTPS
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/checkout.php?$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

But my CSS is still not working for that one https page.

[edited by: sabastian130 at 3:14 pm (utc) on Sep 16, 2015]

not2easy

3:13 pm on Sep 16, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Sorry, looks like you worked on it while I was writing.
That last line is rewriting to http: so that's where it goes. It is like the second rule is undoing the first rule.
One way to follow what is happening and see where to fix it it to test while using a tool that shows you the headers during processing your request, then you can see what is wrong and see what you need to work on. There are many free tools to help you check live headers.

sabastian130

3:16 pm on Sep 16, 2015 (gmt 0)

10+ Year Member



Ok I did some modification, any better?

sabastian130

3:29 pm on Sep 16, 2015 (gmt 0)

10+ Year Member



http:example.com redirects to http:www.example.com... https:www.example.com redirects to http:www.example.com and http:www.example.com/checkout.php redirects to https:www.example.com/checkout.php the only thing not working is my CSS.

not2easy

3:41 pm on Sep 16, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



You may need to have two copies of your css because all resources used with https: need to be secure or it triggers a warning. All .js, all images, all css.
Simplest suggestion to use a full https URL for the css and other resources.

lucy24

6:40 pm on Sep 16, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



RewriteRule ^checkout.php?$

So the rule will also work if someone requests
example.com/checkoutzphp
example.com/checkout.ph
example.com/checkoutzph
et cetera? I don't think that's what you intended.

RewriteRule ^index.php(.*)$ http://www.example.com/$1

Person who requests example.com/index.php4 (or indexzphp4 or index5php4 or etcetera) will be redirected to example.com/4
Person who requests example.com/index.phpxyz (or indexzphpxyz or index5phpxyz or etcetera) will be redirected to example.com/xyz
Again, I don't think that was your intention.

Older browsers kick up a fuss if you use non-secure resources (http) with a secure page (https). My impression is that newer browsers don't care. But you can always rewrite-- not redirect-- so browsers "think" they're getting https://example.com/sharedstyles.css when they're really getting http://example.com/sharedstyles.css. You may need some additional tweaks if you need your images to be indexed without fear of Duplicate Content, but I'm not sure if search engines even care.

sabastian130

6:32 am on Sep 17, 2015 (gmt 0)

10+ Year Member



So basically RewriteRule ^checkout.php?$ needs to be RewriteRule ^checkout.php and RewriteRule ^index.php(.*)$ http://www.example.com/$1 needs to be RewriteRule ^index.php http://www.example.com/$1 is the rest of my coding correct?

lucy24

6:37 pm on Sep 17, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



^checkout.php

Technically it should be checkout\.php with escaped period, but this is a non-lethal error.

If the idea behind index.php(.*) was to capture a query string, that would have to go in a RewriteCond. Looking back I also see a RewriteCond involving
!^/checkout.php?$
A question mark in any pattern or RewriteCond is a special Regular Expression form that means "the preceding character (or group) is optional". A literal question mark has to be escaped as \? -- but in mod_rewrite the only place you'd see this is in a {THE_REQUEST} condition. A RewriteRule (or {REQUEST_URI} condition) doesn't "see" the query. If you do need to change a query string, that's a {QUERY_STRING} condition-- but by default, queries are passed through unchanged, so you probably don't need to say anything about it.

Important
If you're using a CMS that involves rewriting to "index.php?blahblah" then any rule involving "index.php" has to include a RewriteCond looking at {THE_REQUEST} so you only redirect people who asked for "index.php" by name.