decay decay - 1 year ago 91
PHP Question

PHP https check with flexible ssl (cloudflare), how to do?

Background: Website (, dns setup through cloudflare pro plan, this offers "flexible ssl" (read here), which means that ssl only exists between client and cloudflare and not between cloudflare and server, thus not needing dedicated ip and not needing special setups on the server. The server is setup to not use ssl (just a generic website), however cloudflare's flexible ssl is is taking care of the ssl aspect.

Language: PHP (codeignighter, but that doesnt really matter)

Goal: when browsing to domain "" or "http://", to generate a variable "http://", and when browsing to "https://*" to generate a variable "https://".

What should work (but doesnt):

$root = '';
if( isset($_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] != 'off' )
//it doesnt reach here...
$root .= 'https://';
$root .= 'http://';
$root .= "".$_SERVER['HTTP_HOST'];
$root .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']);

I can always make it do: "//", but that doesnt really solve the problem for me.
Thoughts? Should i be doing some string comparison to determine the https-ness?

Im sure the reason for this is when a request reaches the server (https or http), it comes through port 80 and it doesnt get recognized as ssl, so $_SERVER['HTTPS'] is not defined. I could setup a custom ssl between the server and cloudflare, but would be nicer (less effort) if i could just use some regexp and compare the url somehow.

I would also like to know possible issues and vulnerabilities.

Thanks :)

Answer Source

Ok, i will answer my own question for future people who has the same issue:

    $root .= $_SERVER['HTTP_X_FORWARDED_PROTO'].'://';
    $root .= !empty($_SERVER['HTTPS']) ? "https://" : "http://";

Came accross it when i was looking closely at $_SERVER, and googling around for HTTP_X_FORWARDED_PROTO and got me to few pages that confirmed this.