31

Possible Duplicate:
How To Find Out If You are Using HTTPS Without $_SERVER['HTTPS']

I went looking around the web for ways to detect if a server is using an HTTPS connection, but no one site seemed to have all the answers (and some different ones). What exactly are all the ways to detect if a server is using an HTTPS connection with PHP? I need to know several ways to detect SSL as some of my scripts are redistributed and various servers handle things differently.

Community
  • 1
  • 1
Phillip
  • 1,558
  • 3
  • 15
  • 25
  • 1
    *"I need to know several ways to detect SSL as some of my scripts are redistributed and various servers handle things differently."* Not all servers will necessarily allow you to detect what transport mechanism was used. You should instead support a few different methods of determining if HTTPS was used and specifically only list servers that offer those methods as supported. It's unreasonable to support every PHP environment out there. – cdhowie Sep 05 '11 at 05:37
  • I know this, but I need to be able to cover as much as possible. Its my duty to make things as easy as possible for my clients, rather than limit them. – Phillip Sep 05 '11 at 05:40
  • variable `$_SERVER['REQUEST_SCHEME']` returns `http` or `https` – adrianTNT Feb 02 '17 at 10:57

2 Answers2

89

$_SERVER['HTTPS']

Set to a non-empty value if the script was queried through the HTTPS protocol.
Note: Note that when using ISAPI with IIS, the value will be off if the request was not made through the HTTPS protocol.

http://www.php.net/manual/en/reserved.variables.server.php

Ergo, this'll do:

if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
    // SSL connection
}
deceze
  • 510,633
  • 85
  • 743
  • 889
  • 3
    "Will do" on correctly-behaved servers ;-) Of course, if the server is misconfigured then all bets are already off. +1. –  Sep 05 '11 at 05:37
  • Exactly, I gotta make sure I catch everything. People who get my scripts most of the time have free hosting and not all of them are good. I just need to catch as many possibilities as possible. – Phillip Sep 05 '11 at 05:40
  • @Phillip If the web server doesn't communicate the connection method to PHP, then there's very little you can do. The HTTPS env variable is meant to communicate the SSL status, if a server doesn't use it or uses something else it could be *anything*. If this needs to be customized to fit a specific non-compliant host you could define an overridable method or function that the client can customize. – deceze Sep 05 '11 at 05:41
  • Yea but I definitely have to try. More happy customers equals more repeat buyers. Thanks for the help though. – Phillip Sep 05 '11 at 05:51
16

WordPress's core is_ssl() function also adds a check for the server port:

function is_ssl() {
    if ( isset($_SERVER['HTTPS']) ) {
        if ( 'on' == strtolower($_SERVER['HTTPS']) )
            return true;
        if ( '1' == $_SERVER['HTTPS'] )
            return true;
    } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
        return true;
    }
    return false;
}
Hackmodford
  • 3,901
  • 4
  • 35
  • 78
yoavf
  • 20,945
  • 9
  • 37
  • 38
  • 8
    Not that port 443 necessarily means the connection is SSL encrypted... :) – deceze Sep 05 '11 at 05:44
  • True, I was just pointing out another method to try and detect that. This is less for making sure the connection is encrypted, more about trying to detect your server mode so you can make sure you load all your assets from the same server (ie http s://yoursite.com vs http ://yoursite.com) – yoavf Sep 05 '11 at 05:46
  • 1
    For the simplest use case, just checking for the port is _good enough_, as long as you know your own server. – TecBrat Sep 20 '13 at 19:55
  • 2
    I use a third party CDN service CloudFlare that provides SSL. but it's only the connection to CloudFlare that is secure, when CloudFlare contacts our server it is unsecure. so look out for that one when testing this code... haha – rorypicko Apr 09 '15 at 08:46
  • 6
    @rorypicko for reverse proxies like Cloudflare you should check for the header `X-Forwarded-Proto` which should be set to `https` if the browser connected to CF with HTTPS. Another header that's sometimes used, particularly for MS software, is `Front-End-Https: on` – Bugster May 20 '15 at 00:28