Hailwood
Hailwood

Reputation: 92601

Https causing redirect loop?

I am using code igniter, our server is behind some funky config.

I want certian pages to be behind https, certian pages to be behind http, and others I don't care about.

So below is my setup,

My $_SERVER array on an http request looks like looks like

Array
(
    [REDIRECT_STATUS] => 200
    [HTTP_HOST] => test.example.com:80
    [HTTP_X_REAL_IP] => 119.224.22.142
    [HTTP_X_FORWARDED_FOR] => 119.224.22.142
    [HTTP_X_URL_SCHEME] => http
    [HTTP_CONNECTION] => close
    [HTTP_CACHE_CONTROL] => max-age=0
    [HTTP_USER_AGENT] => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8
    [HTTP_ACCEPT_ENCODING] => gzip,deflate,sdch
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.8,en-NZ;q=0.6
    [HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.3
    [HTTP_COOKIE] => [...]
    [PATH] => /usr/local/bin:/usr/bin:/bin
    [SERVER_SIGNATURE] => 
Apache/2.2.14 (Ubuntu) Server at test.example.com Port 8080


    [SERVER_SOFTWARE] => Apache/2.2.14 (Ubuntu)
    [SERVER_NAME] => test.example.com
    [SERVER_ADDR] => 127.0.0.1
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 127.0.0.1
    [DOCUMENT_ROOT] => /var/www
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/index.php
    [REMOTE_PORT] => 54833
    [REDIRECT_URL] => /
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.0
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /
    [SCRIPT_NAME] => /index.php
    [PATH_INFO] => /
    [PATH_TRANSLATED] => redirect:/index.php/
    [PHP_SELF] => /index.php/
    [PHP_AUTH_USER] => ******
    [PHP_AUTH_PW] => ******
    [REQUEST_TIME] => 1308972068
)

and on a https request it looks like

Array
(
    [REDIRECT_STATUS] => 200
    [HTTP_HOST] => test.example.com:443
    [HTTP_X_REAL_IP] => 119.224.22.142
    [HTTP_X_FORWARDED_FOR] => 119.224.22.142
    [HTTP_X_URL_SCHEME] => https
    [HTTP_X_FORWARDED_PROTO] => https
    [HTTP_CONNECTION] => close
    [HTTP_USER_AGENT] => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8
    [HTTP_ACCEPT_ENCODING] => gzip,deflate,sdch
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.8,en-NZ;q=0.6
    [HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.3
    [HTTP_COOKIE] => [...]
    [PATH] => /usr/local/bin:/usr/bin:/bin
    [SERVER_SIGNATURE] => 
Apache/2.2.14 (Ubuntu) Server at test.example.com Port 8080


    [SERVER_SOFTWARE] => Apache/2.2.14 (Ubuntu)
    [SERVER_NAME] => test.example.com
    [SERVER_ADDR] => 127.0.0.1
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 127.0.0.1
    [DOCUMENT_ROOT] => /var/www
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/index.php
    [REMOTE_PORT] => 54841
    [REDIRECT_URL] => /
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.0
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /
    [SCRIPT_NAME] => /index.php
    [PATH_INFO] => /
    [PATH_TRANSLATED] => redirect:/index.php/
    [PHP_SELF] => /index.php/
    [PHP_AUTH_USER] => ********
    [PHP_AUTH_PW] => ********
    [REQUEST_TIME] => 1308972250
)

and my .htaccess looks like

Options +FollowSymlinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ %1/$1 [R=301,L]


RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico|css|images|js)
RewriteRule ^(.*)$ index.php/$1 [L] 

So at the very top of my index.php I have

$_SERVER['SERVER_PORT'] = explode(':', $_SERVER['HTTP_HOST']);
$_SERVER['HTTP_HOST'] = $_SERVER['SERVER_PORT'][0];
$_SERVER['SERVER_PORT'] = $_SERVER['SERVER_PORT'][1];
if($_SERVER['SERVER_PORT'] == 443)
  $_SERVER['HTTPS'] = 'On';
else
  $_SERVER['HTTPS'] = 'Off';

And on pages where I want HTTPS I call

function require_ssl(){
    if($_SERVER['HTTPS'] == 'Off') {
        $host = explode(':', $_SERVER['HTTP_HOST']);
        header('location: https://' . $host[0] . $_SERVER['REQUEST_URI']);
        exit;
    }
}

And on pages where I want only HTTP I call

function disable_ssl(){
    if($_SERVER['HTTPS'] == 'On') {
        $host = explode(':', $_SERVER['HTTP_HOST']);
        header('location: http://' . $host[0] . $_SERVER['REQUEST_URI']);
        exit;
    }
}

Upvotes: 6

Views: 6410

Answers (4)

Ben Lessani
Ben Lessani

Reputation: 2151

We've addressed the accurate fix for Nginx (and other reverse proxies) here:

http://www.sonassi.com/knowledge-base/magento-kb/magento-https-redirect-loop/

This avoids the necessity to have that code in your index.php file. All you needed to do was add this to your Nginx config,

fastcgi_param  HTTPS on;

Upvotes: 1

WebChemist
WebChemist

Reputation: 4411

You might consider using .htaccess rules instead, something like:

RewriteCond %{SERVER_PORT} 80 
RewriteCond %{REQUEST_URI} (optional pattern additional url matching)
RewriteRule ^(.*)$ https://test.example.com/$1 [L]

if you want to force http just replace 80 with 443 and https with http.

Upvotes: 0

Hailwood
Hailwood

Reputation: 92601

So, after hours of painful debugging we finally worked out the issue.

Nginx
Yep, the load balancer was doing it's own redirects.

In the nginx setup this line existed proxy_redirect http:// https://;

So, what was happening?

Well, My code was saying "this page should not be https, redirect"
Then nginx was saying "this request is not https, redirect"
Then my code was...
boom redirect loop.

So, by changing proxy_redirect http:// https://; to proxy_redirect Off; we fixed the problem :)

Upvotes: 5

johnvey
johnvey

Reputation: 5151

The function that you posted for disable_ssl() shows:

if($_SERVER['HTTPS'] == '0n') {

Is the 0 ('zero') a copy/paste error? I assume that you meant:

if($_SERVER['HTTPS'] == 'On') {

If I'm following your logic correctly, this function is invoked when you goto https://test.example.com, and so if this typo exists, it is probably not doing what you think it should.

Upvotes: 1

Related Questions