views:

613

answers:

2

Hi,

this is yet another .htaccess question. And I already did my literature review. Would appreciate any help.

Requirements:

  1. Force HTTPS only for a few URLs.
  2. Browser shouldn't say partially encrypted page for SSL pages.

I am using CodeIgnitor and tweaked the *base_url* in config.php to:

$config['base_url'] = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on') ? 'https://' : 'http://' ;
$config['base_url'] .= $_SERVER['HTTP_HOST'];
$config['base_url'] .= preg_replace('@/+$@','',dirname($_SERVER['SCRIPT_NAME'])).'/';

So, if a URL is accessed with https:// all links contained in it would also be on HTTPS this is to avoid "partially encrypted page" issue.

I started with the following htaccess code:

RewriteCond %{HTTPS} !on
RewriteRule ^(.*)/(abc|xyz|pqr)(.*)$ https://%{HTTP_HOST}/cart/$2$3 [R=301,NC,L]

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^(.*)/(abc|xyz|pqr)(.*)$ [NC]
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L]

With this any URL having abc, xyz or pqr will be redirected to HTTPS and any URL not having it will be forced back to HTTP.

This worked well, the only issue with this is that it is not able to avoid "partially encrypted page" issue. For example if I go for url http://www.example.com/abc/index.php, it will be redirected to https://www.example.com/abc/index.php. But the links on this page say https://www.example.com/images/logo.png, will be changed to HTTP because of the latter rewrite rule. Thereby making the page partially encrypted.

I also tried adding *http_referer* check like this to solve this issue, but obviously that wont solve the issue. Because any clicks coming from a HTTPS page would never get converted to HTTP.

RewriteCond %{HTTPS} !on
RewriteRule ^(.*)/(abc|xyz|pqr)(.*)$ https://%{HTTP_HOST}/cart/$2$3 [R=301,NC,L]

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_REFERER} !^(https)(.*)$
RewriteCond %{REQUEST_URI} !^(.*)/(abc|xyz|pqr)(.*)$ [NC]
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L]

Just want to know if there's a better approach available to this simple problem or am I doing it the wrong way. Will using CI hooks instead of .htaccess solve this?

Thanks in advance

A: 

You could put your static contents on a different domain like static.example.com and disable the HTTPS to HTTP redirect for such requests.

Use //static.example.com/… to reference that resources to use the same URI scheme as the document the reference is contained in and test in your RewriteRule if such a resource is requested:

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !=static.example.com
RewriteRule !(^|/)(abc|xyz|pqr) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L]
Gumbo
in that case if a page from example.com has contents from static.example.com, the browser shows partially encrypted page
shikhar
@shikhar: I clarified my statement.
Gumbo
A: 

Okay . I think I found the solution . i tested it too on my server . works fine .. needed a http referer condition too in the rewrite

RewriteCond %{HTTPS} !on
RewriteRule ^(.*)/(abc|xyz|pqr)(.*)$ https://%{HTTP_HOST}/cart/$2$3 [R=301,NC,L]

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_REFERER} !^https(.*)/(abc|xyz|pqr)(.*)$ [NC]
RewriteCond %{REQUEST_URI} !^(.*)/(abc|xyz|pqr)(.*)$ [NC]
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,L]

Now if you visit any of the pages with (abc,xyz,pqr) it will be redirected to https://... also all the embedded link will be served from https . so the browser wont show the partial encryption warning (red warning sign at the status bar)

when you move away from the any of these page, that page will be on ssl because of referer check, and this page might show partially encrypted warning (but i can live with it). Once you move away from this page everything will be non-ssl.

Hope this helps someone !!!

shikhar