8

My site has an SSL cert and I'm hitting https://mysite.com/info.php, but under the PHP Variables section _SERVER["HTTPS"] is not being reported. I believe this is causing a problem with a Drupal site where some URLs are being written to the page as https://... where others are being written as http://...

What determines if _SERVER["HTTPS"] is set?


EDIT: This may be the answer to my problem Detecting HTTPS vs HTTP on server sending back nothing useful. Could be a load balancer issue

Community
  • 1
  • 1
SomethingOn
  • 9,813
  • 17
  • 68
  • 107
  • What webserver is this running on? – Corey Downie Jul 25 '12 at 16:32
  • Apache and I'm pretty sure the load balancer is the issue. IT department mentioned that they specifically set the PHP variable HTTP_USESSL. The Secure Pages module was altered to check that variable instead of HTTPS. – SomethingOn Jul 25 '12 at 19:46
  • 1
    Instead of altering a default module (which will break on the next upgrade), you might want to consider doing `$_SERVER['HTTPS'] = isset( $_SERVER['HTTP_USESSL'] ) ? 'YES' : '' )`, somewhere in a boostrap file instead, so future upgrades won't break. – Berry Langerak Jul 26 '12 at 13:09
  • I agree...inherited code. I'll likely make a change like this in future so the module itself isn't hacked. Thanks. – SomethingOn Jul 26 '12 at 13:11

4 Answers4

11

It turns out that because of the Load Balancer, which handles the SSL encryption/decryption the Web Server doesn't get $_SERVER["HTTPS"], but $_SERVER["HTTP_USESSL"] is set and can be used as a flash for SSL traffic.

SomethingOn
  • 9,813
  • 17
  • 68
  • 107
7

It says in the documentation $_SERVER['HTTPS']

Set to a non-empty value if the script was queried through the HTTPS protocol.

so

function checkHTTPS() {
    if(!empty($_SERVER['HTTPS']))
        if($_SERVER['HTTPS'] !== 'off')
            return true; //https
        else
            return false; //http
     else
        if($_SERVER['SERVER_PORT'] == 443)
            return true; //https
        else
            return false; //http
}
  • Ya, but what I'm saying is when I look at the output of phpinfo(); it doesn't show anything for _SERVER["HTTPS"]...it's not set at all, but it should be as far as I can tell (SSL cert and url is https://...) – SomethingOn Jul 25 '12 at 14:49
  • That depends on your server configuration (Apache, nginx, etc) and their variables passed to PHP. I guess another way to do it is `$_SERVER['SERVER_PORT'] == '443'`. –  Jul 25 '12 at 15:04
  • Here i made a function (not tested) –  Jul 25 '12 at 15:10
  • 1
    SSL port is 443 in most cases, but not always. – mikiqex May 18 '16 at 07:09
6

Behind a proxy / load balancer

$_SERVER['SERVER_PORT'] was always 80

$_SERVER["HTTPS"] and $_SERVER["HTTP_USESSL"] were NULL

I used $_SERVER['HTTP_X_FORWARDED_PROTO'] that return http or https

1

Adding to Arnaud Hallais' post, the only way I managed to get the correct protocol on my localhost (apache/mac), testing server (apache/linux) and production site (iis/win) was with:

define("PROTOCOL", isset($_SERVER['HTTP_X_FORWARDED_PROTO']) ? $_SERVER['HTTP_X_FORWARDED_PROTO'] : ((isset( $_SERVER["HTTPS"] ) && strtolower( $_SERVER["HTTPS"] ) == "on" ) ? 'https' : 'http')); 
falux
  • 129
  • 1
  • 4