404

[ Avaa Bypassed ]




Upload:

Command:

botdev@3.136.18.192: ~ $
<?php

namespace React\Tests\Socket;

use Clue\React\Block;
use Evenement\EventEmitterInterface;
use React\EventLoop\Factory;
use React\Promise\Promise;
use React\Socket\ConnectionInterface;
use React\Socket\SecureConnector;
use React\Socket\SecureServer;
use React\Socket\TcpServer;
use React\Socket\TcpConnector;
use React\Socket\ServerInterface;

class FunctionalSecureServerTest extends TestCase
{
    const TIMEOUT = 0.5;

    public function setUp()
    {
        if (!function_exists('stream_socket_enable_crypto')) {
            $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
        }
    }

    public function testClientCanConnectToServer()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        /* @var ConnectionInterface $client */
        $client = Block\await($promise, $loop, self::TIMEOUT);

        $this->assertInstanceOf('React\Socket\ConnectionInterface', $client);
        $this->assertEquals($server->getAddress(), $client->getRemoteAddress());

        $client->close();
        $server->close();
    }

    public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL()
    {
        if (PHP_VERSION_ID < 70000 || !$this->supportsTls13()) {
            $this->markTestSkipped('Test requires PHP 7+ for crypto meta data and OpenSSL 1.1.1+ for TLS 1.3');
        }

        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        /* @var ConnectionInterface $client */
        $client = Block\await($promise, $loop, self::TIMEOUT);

        $this->assertInstanceOf('React\Socket\Connection', $client);
        $this->assertTrue(isset($client->stream));

        $meta = stream_get_meta_data($client->stream);
        $this->assertTrue(isset($meta['crypto']['protocol']));

        if ($meta['crypto']['protocol'] === 'UNKNOWN') {
            // TLSv1.3 protocol will only be added via https://github.com/php/php-src/pull/3700
            // prior to merging that PR, this info is still available in the cipher version by OpenSSL
            $this->assertTrue(isset($meta['crypto']['cipher_version']));
            $this->assertEquals('TLSv1.3', $meta['crypto']['cipher_version']);
        } else {
            $this->assertEquals('TLSv1.3', $meta['crypto']['protocol']);
        }
    }

    public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClient()
    {
        if (PHP_VERSION_ID < 70000) {
            $this->markTestSkipped('Test requires PHP 7+ for crypto meta data');
        }

        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false,
            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
        ));
        $promise = $connector->connect($server->getAddress());

        /* @var ConnectionInterface $client */
        $client = Block\await($promise, $loop, self::TIMEOUT);

        $this->assertInstanceOf('React\Socket\Connection', $client);
        $this->assertTrue(isset($client->stream));

        $meta = stream_get_meta_data($client->stream);
        $this->assertTrue(isset($meta['crypto']['protocol']));
        $this->assertEquals('TLSv1.2', $meta['crypto']['protocol']);
    }

    public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServer()
    {
        if (PHP_VERSION_ID < 70000) {
            $this->markTestSkipped('Test requires PHP 7+ for crypto meta data');
        }

        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem',
            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
        ));

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        /* @var ConnectionInterface $client */
        $client = Block\await($promise, $loop, self::TIMEOUT);

        $this->assertInstanceOf('React\Socket\Connection', $client);
        $this->assertTrue(isset($client->stream));

        $meta = stream_get_meta_data($client->stream);
        $this->assertTrue(isset($meta['crypto']['protocol']));
        $this->assertEquals('TLSv1.2', $meta['crypto']['protocol']);
    }

    public function testServerEmitsConnectionForClientConnection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));

        $peer = new Promise(function ($resolve, $reject) use ($server) {
            $server->on('connection', $resolve);
            $server->on('error', $reject);
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $client = $connector->connect($server->getAddress());

        // await both client and server side end of connection
        /* @var ConnectionInterface[] $both */
        $both = Block\awaitAll(array($peer, $client), $loop, self::TIMEOUT);

        // both ends of the connection are represented by different instances of ConnectionInterface
        $this->assertCount(2, $both);
        $this->assertInstanceOf('React\Socket\ConnectionInterface', $both[0]);
        $this->assertInstanceOf('React\Socket\ConnectionInterface', $both[1]);
        $this->assertNotSame($both[0], $both[1]);

        // server side end has local server address and client end has remote server address
        $this->assertEquals($server->getAddress(), $both[0]->getLocalAddress());
        $this->assertEquals($server->getAddress(), $both[1]->getRemoteAddress());

        // clean up all connections and server again
        $both[0]->close();
        $both[1]->close();
        $server->close();
    }

    public function testWritesDataToConnection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableOnce());

        $server->on('connection', function (ConnectionInterface $conn) {
            $conn->write('foo');
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $local = Block\await($promise, $loop, self::TIMEOUT);
        /* @var $local ConnectionInterface */

        $local->on('data', $this->expectCallableOnceWith('foo'));

        Block\sleep(self::TIMEOUT, $loop);
    }

    public function testWritesDataInMultipleChunksToConnection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableOnce());

        $server->on('connection', function (ConnectionInterface $conn) {
            $conn->write(str_repeat('*', 400000));
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $local = Block\await($promise, $loop, self::TIMEOUT);
        /* @var $local ConnectionInterface */

        $received = 0;
        $local->on('data', function ($chunk) use (&$received) {
            $received += strlen($chunk);
        });

        Block\sleep(self::TIMEOUT, $loop);

        $this->assertEquals(400000, $received);
    }

    public function testWritesMoreDataInMultipleChunksToConnection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableOnce());

        $server->on('connection', function (ConnectionInterface $conn) {
            $conn->write(str_repeat('*', 2000000));
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $local = Block\await($promise, $loop, self::TIMEOUT);
        /* @var $local ConnectionInterface */

        $received = 0;
        $local->on('data', function ($chunk) use (&$received) {
            $received += strlen($chunk);
        });

        Block\sleep(self::TIMEOUT, $loop);

        $this->assertEquals(2000000, $received);
    }

    public function testEmitsDataFromConnection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableOnce());

        $once = $this->expectCallableOnceWith('foo');
        $server->on('connection', function (ConnectionInterface $conn) use ($once) {
            $conn->on('data', $once);
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $local = Block\await($promise, $loop, self::TIMEOUT);
        /* @var $local ConnectionInterface */

        $local->write("foo");

        Block\sleep(self::TIMEOUT, $loop);
    }

    public function testEmitsDataInMultipleChunksFromConnection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableOnce());

        $received = 0;
        $server->on('connection', function (ConnectionInterface $conn) use (&$received) {
            $conn->on('data', function ($chunk) use (&$received) {
                $received += strlen($chunk);
            });
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $local = Block\await($promise, $loop, self::TIMEOUT);
        /* @var $local ConnectionInterface */

        $local->write(str_repeat('*', 400000));

        Block\sleep(self::TIMEOUT, $loop);

        $this->assertEquals(400000, $received);
    }

    public function testPipesDataBackInMultipleChunksFromConnection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableOnce());

        $server->on('connection', function (ConnectionInterface $conn) use (&$received) {
            $conn->pipe($conn);
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $local = Block\await($promise, $loop, self::TIMEOUT);
        /* @var $local ConnectionInterface */

        $received = 0;
        $local->on('data', function ($chunk) use (&$received) {
            $received += strlen($chunk);
        });

        $local->write(str_repeat('*', 400000));

        Block\sleep(self::TIMEOUT, $loop);

        $this->assertEquals(400000, $received);
    }

    /**
     * @requires PHP 5.6
     */
    public function testEmitsConnectionForNewTlsv11Connection()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem',
            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER
        ));
        $server->on('connection', $this->expectCallableOnce());

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false,
            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
        ));
        $promise = $connector->connect($server->getAddress());

        Block\await($promise, $loop, self::TIMEOUT);
    }

    /**
     * @requires PHP 5.6
     */
    public function testEmitsErrorForClientWithTlsVersionMismatch()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem',
            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER|STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
        ));
        $server->on('connection', $this->expectCallableNever());
        $server->on('error', $this->expectCallableOnce());

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false,
            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
        ));
        $promise = $connector->connect($server->getAddress());

        $this->setExpectedException('RuntimeException', 'handshake');
        Block\await($promise, $loop, self::TIMEOUT);
    }

    public function testServerEmitsConnectionForNewConnectionWithEncryptedCertificate()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem',
            'passphrase' => 'swordfish'
        ));

        $peer = new Promise(function ($resolve, $reject) use ($server) {
            $server->on('connection', $resolve);
            $server->on('error', $reject);
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $connector->connect($server->getAddress());

        $connection = Block\await($peer, $loop, self::TIMEOUT);

        $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
    }

    public function testClientRejectsWithErrorForServerWithInvalidCertificate()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => 'invalid.pem'
        ));

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $this->setExpectedException('RuntimeException', 'handshake');
        Block\await($promise, $loop, self::TIMEOUT);
    }

    public function testServerEmitsErrorForClientWithInvalidCertificate()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => 'invalid.pem'
        ));

        $peer = new Promise(function ($resolve, $reject) use ($server) {
            $server->on('connection', function () use ($reject) {
                $reject(new \RuntimeException('Did not expect connection to succeed'));
            });
            $server->on('error', $reject);
        });

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $connector->connect($server->getAddress());

        $this->setExpectedException('RuntimeException', 'handshake');
        Block\await($peer, $loop, self::TIMEOUT);
    }

    public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $server->on('error', $this->expectCallableOnce());

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $this->setExpectedException('RuntimeException', 'handshake');
        Block\await($promise, $loop, self::TIMEOUT);
    }

    public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassphrase()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem',
            'passphrase' => 'nope'
        ));
        $server->on('connection', $this->expectCallableNever());
        $server->on('error', $this->expectCallableOnce());

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());

        $this->setExpectedException('RuntimeException', 'handshake');
        Block\await($promise, $loop, self::TIMEOUT);
    }

    public function testEmitsErrorForConnectionWithPeerVerification()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $errorEvent = $this->createPromiseForServerError($server);

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => true
        ));
        $promise = $connector->connect($server->getAddress());
        $promise->then(null, $this->expectCallableOnce());

        Block\await($errorEvent, $loop, self::TIMEOUT);
    }

    public function testEmitsErrorIfConnectionIsCancelled()
    {
        if (PHP_OS !== 'Linux') {
            $this->markTestSkipped('Linux only (OS is ' . PHP_OS . ')');
        }

        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $errorEvent = $this->createPromiseForServerError($server);

        $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
            'verify_peer' => false
        ));
        $promise = $connector->connect($server->getAddress());
        $promise->cancel();
        $promise->then(null, $this->expectCallableOnce());

        Block\await($errorEvent, $loop, self::TIMEOUT);
    }

    public function testEmitsErrorIfConnectionIsClosedBeforeHandshake()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $errorEvent = $this->createPromiseForServerError($server);

        $connector = new TcpConnector($loop);
        $promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));

        $promise->then(function (ConnectionInterface $stream) {
            $stream->close();
        });

        $error = Block\await($errorEvent, $loop, self::TIMEOUT);

        // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshak
        $this->assertInstanceOf('RuntimeException', $error);
        $this->assertStringStartsWith('Connection from tcp://', $error->getMessage());
        $this->assertStringEndsWith('failed during TLS handshake: Connection lost during TLS handshake', $error->getMessage());
        $this->assertEquals(defined('SOCKET_ECONNRESET') ? SOCKET_ECONNRESET : 0, $error->getCode());
        $this->assertNull($error->getPrevious());
    }

    public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $errorEvent = $this->createPromiseForServerError($server);

        $connector = new TcpConnector($loop);
        $promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));

        $promise->then(function (ConnectionInterface $stream) {
            $stream->end("\x1e");
        });

        $error = Block\await($errorEvent, $loop, self::TIMEOUT);

        // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshak
        $this->assertInstanceOf('RuntimeException', $error);
        $this->assertStringStartsWith('Connection from tcp://', $error->getMessage());
        $this->assertStringEndsWith('failed during TLS handshake: Connection lost during TLS handshake', $error->getMessage());
        $this->assertEquals(defined('SOCKET_ECONNRESET') ? SOCKET_ECONNRESET : 0, $error->getCode());
        $this->assertNull($error->getPrevious());
    }

    public function testEmitsNothingIfConnectionIsIdle()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $server->on('error', $this->expectCallableNever());

        $connector = new TcpConnector($loop);
        $promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));

        $promise->then($this->expectCallableOnce());
        Block\sleep(self::TIMEOUT, $loop);
    }

    public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $errorEvent = $this->createPromiseForServerError($server);

        $connector = new TcpConnector($loop);
        $promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));

        $promise->then(function (ConnectionInterface $stream) {
            $stream->write("GET / HTTP/1.0\r\n\r\n");
        });

        $error = Block\await($errorEvent, $loop, self::TIMEOUT);

        $this->assertInstanceOf('RuntimeException', $error);

        // OpenSSL error messages are version/platform specific
        // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:SSL3_GET_RECORD:http request
        // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:ssl3_get_record:wrong version number
        // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:func(143):reason(267)
        // Unable to complete TLS handshake: Failed setting RSA key
    }

    public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandshake()
    {
        $loop = Factory::create();

        $server = new TcpServer(0, $loop);
        $server = new SecureServer($server, $loop, array(
            'local_cert' => __DIR__ . '/../examples/localhost.pem'
        ));
        $server->on('connection', $this->expectCallableNever());
        $errorEvent = $this->createPromiseForServerError($server);

        $connector = new TcpConnector($loop);
        $promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));

        $promise->then(function (ConnectionInterface $stream) {
            $stream->write("Hello world!\n");
        });

        $error = Block\await($errorEvent, $loop, self::TIMEOUT);

        $this->assertInstanceOf('RuntimeException', $error);

        // OpenSSL error messages are version/platform specific
        // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:SSL3_GET_RECORD:unknown protocol
        // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:ssl3_get_record:wrong version number
        // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:func(143):reason(267)
        // Unable to complete TLS handshake: Failed setting RSA key
    }

    private function createPromiseForServerError(ServerInterface $server)
    {
        return $this->createPromiseForEvent($server, 'error', function ($error) {
            return $error;
        });
    }

    private function createPromiseForEvent(EventEmitterInterface $emitter, $event, $fn)
    {
        return new Promise(function ($resolve) use ($emitter, $event, $fn) {
            $emitter->on($event, function () use ($resolve, $fn) {
                $resolve(call_user_func_array($fn, func_get_args()));
            });
        });
    }

    private function supportsTls13()
    {
        // TLS 1.3 is supported as of OpenSSL 1.1.1 (https://www.openssl.org/blog/blog/2018/09/11/release111/)
        // The OpenSSL library version can only be obtained by parsing output from phpinfo().
        // OPENSSL_VERSION_TEXT refers to header version which does not necessarily match actual library version
        // see php -i | grep OpenSSL
        // OpenSSL Library Version => OpenSSL 1.1.1  11 Sep 2018
        ob_start();
        phpinfo(INFO_MODULES);
        $info = ob_get_clean();

        if (preg_match('/OpenSSL Library Version => OpenSSL (\S+)/', $info, $match)) {
            return version_compare($match[1], '1.1.1', '>=');
        }
        return false;
    }
}

Filemanager

Name Type Size Permission Actions
Stub Folder 0755
ConnectionTest.php File 1.49 KB 0644
ConnectorTest.php File 4.42 KB 0644
DnsConnectorTest.php File 12.58 KB 0644
FixedUriConnectorTest.php File 525 B 0644
FunctionalConnectorTest.php File 809 B 0644
FunctionalSecureServerTest.php File 26.83 KB 0644
FunctionalTcpServerTest.php File 8.95 KB 0644
IntegrationTest.php File 11.36 KB 0644
LimitingServerTest.php File 6.03 KB 0644
SecureConnectorTest.php File 8.72 KB 0644
SecureIntegrationTest.php File 6.67 KB 0644
SecureServerTest.php File 6.04 KB 0644
ServerTest.php File 5.74 KB 0644
TcpConnectorTest.php File 8.74 KB 0644
TcpServerTest.php File 7.72 KB 0644
TestCase.php File 2.66 KB 0644
TimeoutConnectorTest.php File 4.99 KB 0644
UnixConnectorTest.php File 1.91 KB 0644
UnixServerTest.php File 7.86 KB 0644