Apache Redirect certain HTTPS requests to HTTP not working - apache

Hi I have been working on this for a while and just know I am doing something stupid but just can not see it. What I want to do is to redirect certain pages so they are always shown using HTTPS and all other pages if they are requested through HTTPS they are redirected as HTTP.
I have done lots of searching around the issue and found accepted answers on Stackoverflow that just did not work for me. So here Is my .htaccess file.
RewriteCond %{HTTPS} on
RewriteCond ${REQUEST_URI} !(finance/enquiryForm)(.*)
RewriteCond ${REQUEST_URI} !(offerentry)(.*)
RewriteRule (.*) http://dev.staging.co.uk/$1 [L,R=301]
RewriteCond %{HTTPS} off
RewriteRule ^(finance/enquiryForm|offerentry)(.*) https://dev.staging.co.uk/$1 [L,R=301]
What is currently happening is that the pages that I want to redirect from https to http work fine but the pages I want to show as HTTPS get a redirect loop and fail. If I comment out the top section the HTTPS pages I do want redirect fine. So how do I get the redirect loop to stop?
EDIT
The full .htaccess file with the codeigniter etc stuff.
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
<Files .*>
Order Deny,Allow
Deny From All
</Files>
#RewriteCond %{HTTPS} on
#RewriteCond ${REQUEST_URI} !/(finance/enquiryForm|offerentry) [NC]
#RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=302,NE]
#RewriteCond %{HTTPS} off
#RewriteCond ${REQUEST_URI} /(finance/enquiryForm|offerentry) [NC]
#RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302,NE]
# Protect application and system files from being viewed
RewriteRule ^(fuel/install/.+|fuel/crons/.+|fuel/data_backup/.+|fuel/codeigniter/.+|fuel/modules/.+|fuel/application/.+|\.$
# Remove trailing slashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_URI} !fuel/.*$
RewriteRule ^(.*)/$ $1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/$0 [L]
</IfModule>
Options -Indexes

Try these rules based on THE_REQUEST variable:
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} !/(finance/enquiryForm|offerentry) [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=302,NE]
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} /(finance/enquiryForm|offerentry) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302,NE]
Test them in Chrome dev tool and see what redirects are you getting.

Try with:
RewriteCond %{HTTPS} on
RewriteCond ${REQUEST_URI} !(finance/enquiryForm|offerentry)
RewriteRule (.*) http://dev.staging.co.uk/$1 [L,R=301]
RewriteCond %{HTTPS} off
RewriteRule (finance/enquiryForm|offerentry) https://dev.staging.co.uk%{REQUEST_URI} [NE,L,R=301]

Related

mod_rewrite rule for "www to non www" doesn't redirect sub-pages

I have made a thorough search before I have asked this question here. Please hear me out:
I am trying to redirect my blog from www to non www and it doesn't redirect any sub-pages. I have an http > https redirect in place as well and it works perfectly for both domain as well as the sub-pages. Here are the rules I have in my .htaccess
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^^rcp-pep-ipn //?rcp-pep-listener=IPN [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteBase /
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
</IfModule>
# END WordPress
I'd really appreciate an explanation if I am doing anything wrong here. I have literally pulled my hair since I have used the exact same code (from the second RewriteBase /) for all other sites and it worked flawlessly.
You should bring those protocol checking conditions to the beginning. You have some problems within the rules too. Try:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,NE,L]
RewriteRule ^rcp-pep-ipn /?rcp-pep-listener=IPN [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

HTACCESS Redirection Clarification

I am trying to redirect my web page using .htaccess. For all the requests, I want to redirect to http to https. But if the URL contains substring api, I don't want this redirection. I have tried following but it always redirecting to https.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{SERVER_PORT} ^80$
RewriteCond %{REQUEST_URI} api
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Use this instead for substring 'api' anywhere in the URI:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !api
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
And change it like this if you only want to exclude calls like '.../api/...'
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !\/api\/
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

htaccess redirect all but three pages to https

I know this sounds like a duplicate but I have tried as many methods as I can find and I still have not gotten this to work. So please do not auto mark this as a duplicate.
I am trying to redirect all pages of http://www.domian.com to https://www.domain.com with the exception of three pages:/products/product1, /products/product2, /products/product3
I also want those pages to always direct to http since if an https page links to it via a relative link, it will naturally have the https already there.
Also in play is that this is an expression engine site where I am removing the index.php from the URI.
Current Htaccess, which results in those three pages still being https even I go to Http for those pages.
### secure .htaccess file
<Files .htaccess>
order allow,deny
deny from all
</Files>
### EE 404 page for missing pages
ErrorDocument 404 /index.php/site/404
###Block Access to directories with no index file
Options -Indexes
### Simple 404 for missing files
<FilesMatch "(\.jpe?g|gif|png|bmp|css|js|flv)$">
ErrorDocument 404 "File Not Found"
</FilesMatch>
### Although highly unlikely, your host may have +FollowSymLinks enabled at the root level, yet disallow its addition in .htaccess; in which case, adding +FollowSymLinks will break your setup (probably a 500 error), so just remove it, and your rules should work fine.
###Options +FollowSymlinks
RewriteEngine On
RewriteBase /
###Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET
RewriteCond %{THE_REQUEST} ^[^/]*/index\.php [NC]
RewriteRule ^index\.php(.+) $1 [R=301,L]
### Add the www
RewriteCond %{HTTP_HOST} ^domain\.com
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=permanent,L]
###each option I try I replace in this block as a reference
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/products/product3
RewriteCond %{REQUEST_URI} !^/products/product1
RewriteCond %{REQUEST_URI} !^/products/product2
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
######
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
###
Also have tried this which results in the same as above:
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} !^(domain\.com/products/product1|domain\.com/products/product2|domain\.com/products/product2) [NC]
RewriteRule ^(.*)$ https://www.domain.com/$1 [R,L]
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^(domain\.com/products/product1|domain\.com/products/product2|domain\.com/products/product2) [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R,L]
Tried this alone just to see if would be able to navigate to http://www.domain.com/products/product1 and at least not have it rewrite, but it still rewrites to https
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !/products/product1 [NC,OR]
RewriteCond %{REQUEST_URI} !/products/product2 [NC,OR]
RewriteCond %{REQUEST_URI} !/products/product3 [NC,OR]
RewriteRule ^(.*)$ https://www.domain.com/$1 [R,L]
Tried this as well, which again still writes those pages to https. Plus if I try to go to http , it rewrites to https and doesn't remove the index.php
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} !^/products/product3
RewriteCond %{REQUEST_URI} !^/products/product1
RewriteCond %{REQUEST_URI} !^/products/product2
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^/products/product3 http://www.domain.com/products/product3 [R=301,QSA,L,NE]
RewriteRule ^/products/product1 http://www.domain.com/products/product1 [R=301,QSA,L,NE]
RewriteRule ^/products/product2 http://www.domain.com/products/product2 [R=301,QSA,L,NE]
I have honestly tried about 10 -15 versions of all this above and still cannot get it. Including adding index.php? to the request_URI in case that it sees that as part of the request_URI before it's removed. I either end up with the page still rewriting to https or redirect loop land.
Am I missing something simple, is something in the wrong order? I'm just at a loss.
thanks for any help.
UPDATE:
Here's what I used to get it to work:
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} (\s/products/product1|\s/products/product2|\s/products/product3) [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !\s/products/product1 [NC]
RewriteCond %{THE_REQUEST} !\s/products/product2 [NC]
RewriteCond %{THE_REQUEST} !\s/products/product3 [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Here's how we achieved this on a site with a webcam that was in an iframe that wouldn't work on SSL. This was also an ExpressionEngine site.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#force www instead of non-www
RewriteCond %{HTTP_HOST} ^domain.co.uk
RewriteRule ^(.*)$ http://www.domain.co.uk/$1 [R=301,L]
# HTTP/HTTPS handling
# Force HTTP for webcam page only
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} \s/webcam-page [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# Force HTTPS for all pages except webcam
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !\s/webcam-page [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
</IfModule>

How to force http:// in htaccess?

I currently have this in my htaccess file to force https on all pages on my sign in and sign up pages:
# Force https://
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond $1 ^(sign-in|sign-up) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
I want to force http whenever the page is not sign in or sign up. How do I do that?
EDIT 1:
I actually need to do the following:
Force https:// for pages in sign-up and sign-in
Force http:// for pages not in sign-up and sign-in
Remove www
Remove index.php
The relevant part of my .htaccess has this:
#
# Force https:// or http://
#
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond $1 ^(sign-in|sign-up) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#RewriteCond %{HTTPS} on
#RewriteCond $1 !^(sign-in|sign-up) [NC]
#RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#RewriteCond %{HTTPS} on
#RewriteCond %{REQUEST_URI} !^/(sign-in|sign-up)(/|$) [NC]
#RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
#
# Supress "www" at the beginning of URLs. Source: HTML5 Boilerplate
#
<IfModule mod_rewrite.c>
RewriteEngine On
#RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>
#
# Supress "index.php"
#
<IfModule mod_rewrite.c>
RewriteEngine On
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
Have your rules like this:
RewriteEngine On
# force HTTPS for sign-in|sign-up
RewriteCond %{HTTPS} off
RewriteRule ^(sign-in|sign-up)(/|$) https://%{HTTP_HOST}%{REQUEST_URI} [NC,L,R=301]
# force HTTP for NOT sign-in|sign-up
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(sign-in|sign-up)(/|$) [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I have not implemented this kind of solution personally (I have tended to use the PHP solution, like the one above, for it's simplicity), but the following may be, at least, a good start.
RewriteEngine on
# Check for POST Submission
RewriteCond %{REQUEST_METHOD} !^POST$
# Forcing HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
# Forcing HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
You can use environment variables to track the states you need and then only issue one redirect if necessary.
The following block should do exactly what you want:
<IfModule mod_rewrite.c>
RewriteEngine On
# Define default protocol for all assets
RewriteRule ^ - [E=protocol:http,E=ssl:%{HTTPS}off]
# Define HTTPS targets, add more cond as required
RewriteCond $1 (sign-in|sign-up) [NC]
RewriteRule (.*) - [E=protocol:https,E=ssl:%{HTTPS}on]
# Rewrite host if necessary and redirect on correct protocol
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ %{ENV:protocol}://%1%{REQUEST_URI} [L,R=301]
# Protocol switch if necessary (host is already correct)
RewriteCond %{ENV:ssl} ^(onoff|offon)
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|css|js)$ [NC]
RewriteRule ^ %{ENV:protocol}://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Finally, process the internal redirect
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
In this configuration, the protocol environment variable is used to track the actual protocol name to use and the ssl environment variable is the test to check if we are already on the correct protocol for the URI.
Using environment variables gives you 2 advantages :
you avoid redirection chains. This configuration will redirect the user-agent at most once.
you're DRY (Don't repeat yourself). Each condition is only expressed once, so it's easier to maintain.

htaccess - redirect to https not working

Per: https://exp-resso.com/blog/post/2011/08/securing-your-expressionengine-website-with-https
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond $1 ^(member|account|checkout|system) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
This tells your server “If HTTPS is off, and the request starts with
member OR account OR checkout OR system (not case sensitive), redirect
to https://current-domain/current-page”. It’s a nice simple method of
locking down entire subfolders / template groups.
I've added this to my htaccess file like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond $1 ^(sign-in|sign-up) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
However, when I go to my http://mydomain.com/sign-in, the URL doesn't change to https://mydomain.com/sign-in. Any idea what's wrong?
EDIT 1:
My htaccess also has the following (to remove "www") and I wonder if having both might be causing the problem?
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
EDIT 2:
Process of elimination, it turns out this is causing the problem:
<IfModule mod_rewrite.c>
RewriteEngine On
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
When I comment out the RewriteRule, the https:// is forces. What's causing the conflict?
Try to put (sign-in|sign-up) condition inside RewriteRule:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(sign-in|sign-up)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,NC,R=301]
What about this? (If port == 80 then redirect )
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} member [OR]
RewriteCond %{REQUEST_URI} account [OR]
RewriteCond %{REQUEST_URI} checkout [OR]
RewriteCond %{REQUEST_URI} system
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
First make sure that rewrite works on your server and that the htaccess is read (e.g. by issuing a redirect on every URL).
Then use RewriteCond %{REQUEST_URI} ^/(sign-in|sign-up) instead of RewriteCond $1 ^(sign-in|sign-up) [NC]
It works and is easier to read too
So you htaccess should look like this
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} ^/(sign-in|sign-up) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]