20

The problem that I am having has to do with the need to keep some urls of a website protected by HTTPS and the rest kicked to HTTP.

Normally, you have $_SERVER['HTTP_HTTPS'] or $_SERVER['HTTPS'] (depending on your flavor of Apache). You also can check the port - it's 80 for normal traffic and 443 for HTTPS.

My problem is that the certificate sits on the loadbalancer, and all these variables are unavailable, and the webserver sees http://www.foo.com on port 80. One way to fix this is to tell the loadbalancer to send the traffic on a different port, but I wonder if there are other ways to detect HTTPS coming from the load balancer?

PhearOfRayne
  • 4,990
  • 3
  • 31
  • 44
deadprogrammer
  • 11,253
  • 24
  • 74
  • 85

3 Answers3

48

If anybody has the same issue behind an Amazon AWS Elastic Load Balancer, the solution is simple because the $_SERVER variable will include:

[HTTP_X_FORWARDED_PORT] => 443
[HTTP_X_FORWARDED_PROTO] => https

So, to get the protocol, you could use:

function getRequestProtocol() {
    if(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']))
        return $_SERVER['HTTP_X_FORWARDED_PROTO'];
    else 
        return !empty($_SERVER['HTTPS']) ? "https" : "http";
}
mrucci
  • 4,342
  • 3
  • 33
  • 35
  • 2
    is there ever a case where `$_SERVER['HTTP_X_FORWARDED_PROTO']` won't be included in the $_SERVER var? – eipark Jul 29 '12 at 09:13
  • @eipark sure since its client-set header, but there is conditional return. – Zaffy Jul 29 '12 at 10:36
  • @elpark Until you are behind an aws load balancer, I would say no, since it is a documented feature: http://aws.typepad.com/aws/2010/10/keeping-customers-happy-another-new-elastic-load-balancer-feature.html. – mrucci Jul 30 '12 at 10:01
  • @eipark Yes, when you are between a load balancer and your server – kaiser Sep 24 '15 at 17:53
15

If the load balancer is the other end of the SSL connection, you cannot get any more info than the load balancer explicitly provides. I would go for adding a http header, it may already be doing that, dump all the HTTP headers and look.

As another solution, you can do the redirection on the load balancer based on URL.

hayalci
  • 4,089
  • 2
  • 27
  • 30
  • Yep, good answer hayalci. I've just been looking into this same issue (on a site I believe is also load-balanced) and it seems the only way I can identify HTTPS use is via the header `HTTP_NOSSL`. True means HTTP, false means HTTPS. – Simon East Aug 17 '11 at 02:54
1

the $_SERVER['HTTP_X_FORWARDED_PROTO'] seems to be a good solution for joomla users because if your loadbalancer does the rediretion and you set the force_ssl setting to 1 or 2 then you will end in an infinite loop because joomla always sees http:

Elyoukey
  • 39
  • 2