Search code examples
apache.htaccessmod-rewritehttp-redirectexpressionengine

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]

Solution

  • 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>