1

I would like to find a solution to switch between HTTP and HTTPS protocol on a PHP server and this solution have to works from a local network and from Internet network.

A scheme:

            DNS: domain.com
                IP: x.x.x.x <╌┬╌> IP: 192.168.1.1
                              ┆
┌──────────┐       HTTP 80┌───┴────┐      HTTP 8000┌────────┐
│ INTERNET ╞══════════════╡ ROUTER ╞═══════════════╡ SERVER │ IP: 192.168.1.2
│          ╞══════════════╡        ╞═══════════════╡        │ DNS: SERVER.local
└────╥╥────┘     HTTPS 443└───╥╥───┘     HTTPS 8001└────────┘
     ║║                       ║║
 ┌───╨╨───┐               ┌───╨╨───┐
 │ CLIENT │               │ CLIENT │
 └────────┘               └────────┘

The problem:

  • From local network, the client have to be redirected:

    from http://SERVER.local:8000 (port 8000 explicit) to https://SERVER.local:8001 (port 8001 explicit) or from http://192.168.1.2:8000 to https://192.168.1.2:8001

  • From Internet network, the client have to be redirected:

    from http://domain.com (port 80 implicit) to https://domain.com (port 443 implicit) or from http://x.x.x.x to https://x.x.x.x

The question:

  • How can I detect the origin of the client (Internet or local network) to switch him to the correct URL?

A global solution with IPv6 support too will be welcome! Thank you for your help.

Community
  • 1
  • 1
alex
  • 5,661
  • 6
  • 33
  • 54
  • 1
    `$_SERVER['HTTP_HOST']` to get the requested host name. `$_SERVER['REMOTE_ADDR']` to get the clients IP (which will be in a local range (192.168.*, or 10.*) if local). – Petah Oct 02 '14 at 03:27
  • Unfortunately this is not enough... – alex Oct 02 '14 at 03:29
  • The unfortunately your question is not clear enough. Do you care to elaborate? – Petah Oct 02 '14 at 03:31

2 Answers2

1
switch ($_SERVER['HTTP_HOST']) {
    case 'SERVER.local:8000': {
        header('Location: https://SERVER.local:8001/' . $_SERVER['REQUEST_URI']);
        exit;
    }
    case '192.168.1.2:8000': {
        header('Location: https://192.168.1.2:8001/' . $_SERVER['REQUEST_URI']);
        exit;
    }
    case 'domain.com:80': {
        header('Location: https://domain.com/' . $_SERVER['REQUEST_URI']);
        exit;
    }
}
Petah
  • 45,477
  • 28
  • 157
  • 213
  • Thank you for your help, just a thing: when the port is explicitly specified, $_SERVER['HTTP_HOST'] already contains the port number. But it is not a problem – alex Oct 02 '14 at 03:41
  • @alex, so it does. Updated. – Petah Oct 02 '14 at 04:05
0

I finally use this method without dependance with any static IP address or DNS records:

define('HTTP_LOCAL_PORT', 8000);
define('HTTPS_LOCAL_PORT', 8001);

define('HTTPS', isset($_SERVER['HTTPS']) && filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN));
define('REQUEST_URL', (HTTPS ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
define('REQUEST_HOST', parse_url(REQUEST_URL, PHP_URL_HOST));
define('REQUEST_PORT', parse_url(REQUEST_URL, PHP_URL_PORT));
define('LOCAL_REMOTE', REQUEST_PORT == HTTP_LOCAL_PORT || REQUEST_PORT == HTTPS_LOCAL_PORT);
define('HTTP_REQUEST_URL', 'http://'.REQUEST_HOST.(LOCAL_REMOTE?':'.HTTP_LOCAL_PORT:'').$_SERVER['REQUEST_URI']);
define('HTTPS_REQUEST_URL', 'https://'.REQUEST_HOST.(LOCAL_REMOTE?':'.HTTPS_LOCAL_PORT:'').$_SERVER['REQUEST_URI']);

if REQUEST_URL = 'http://domain.com/uri'
 > HTTPS_REQUEST_URL = 'https://domain.com/uri'

if REQUEST_URL = 'http://x.x.x.x/uri'
 > HTTPS_REQUEST_URL = 'https://x.x.x.x/uri'

if REQUEST_URL = 'http://SERVER.local:8000/uri'
 > HTTPS_REQUEST_URL = 'https://SERVER.local:8001/uri'

if REQUEST_URL = 'http://192.168.1.2:8000/uri'
 > HTTPS_REQUEST_URL = 'https://http://192.168.1.2:8001/uri'
alex
  • 5,661
  • 6
  • 33
  • 54