xp-framework / http

HTTP protocol support for the XP Framework
2 stars 2 forks source link

SNI with PHP 5.4 #18

Closed thekid closed 6 years ago

thekid commented 8 years ago

Scenario: HTTP proxy which talks to a HTTPS site.

When connecting to an HTTPS server through HTTP proxy, the first request to the proxy will use plain HTTP, then issuing a CONNECT call which subsequently enables cryptography.

In PHP 5.4, the (now deprecated) SNI_server_name and SNI_enabled values are read from the stream context prior to the creation of the socket; setting these values afterwards has no effect. The server then will respond with this message: [error] Hostname A provided via SNI and hostname B provided via HTTP are different.

A fix is to settle these values early in time:

  protected function connect($s, $read, $connect) {
    $s->isConnected() && $s->close();
    $s->setTimeout($read);

    $ctx= $s->getClass()->getField('context')->setAccessible(true)->get($s);
    stream_context_set_option($ctx, 'ssl', 'SNI_enabled', true);
    stream_context_set_option($ctx, 'ssl', 'SNI_server_name', 'example.com');

    $s->connect($connect);
    return $s;
  } 
thekid commented 8 years ago

Maybe enclosed inside a if (PHP_VERSION <= '5.6') { ... } block? The relevant PHP manual page states:

SNI_server_name string

If set, then this value will be used as server name for server name indication. If this value is not set, then the server name is guessed based on the hostname used when opening the stream. Note: This option is deprecated, in favour of peer_name, as of PHP 5.6.0.

thekid commented 6 years ago

Not an issue anymore, we require PHP 5.6 now.