I use a code igniter, our server is behind some funky configuration.
I want the certian pages to be behind https, the certian pages to be to http, and others don't bother me.
So below is my setup,
- If I go to
http://test.example.com (which has a call to disable_ssl() ), the page loads with a fine - If I go to
https://test.example.com/login (which has a call to require_ssl() ), the page loads with a fine. - If I go to
http://test.example.com/login , I am redirected to the https version. what well. - If I go to
https://test.example.com , then I get into the redirect cycle ... For some reason, the header gets the value https instead of http , although I explicitly write http .
My $_SERVER in the http request 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 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 the 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; } }