A text, audio and video chat application built with webRTC and Ratchet (PHP WebSocket)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

384 lines
12 KiB

<?php
namespace React\Tests\Socket;
use React\EventLoop\Factory;
use React\SocketClient\TcpConnector;
use React\Socket\Server;
use Clue\React\Block;
use React\Socket\SecureServer;
use React\SocketClient\SecureConnector;
use React\Stream\Stream;
use React\Socket\ConnectionInterface;
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 testEmitsConnectionForNewConnection()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
Block\await($promise, $loop, self::TIMEOUT);
}
public function testWritesDataToConnection()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$server->on('connection', function (ConnectionInterface $conn) {
$conn->write('foo');
});
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
$local = Block\await($promise, $loop, self::TIMEOUT);
/* @var $local React\Stream\Stream */
$local->on('data', $this->expectCallableOnceWith('foo'));
Block\sleep(self::TIMEOUT, $loop);
}
public function testWritesDataInMultipleChunksToConnection()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$server->on('connection', function (ConnectionInterface $conn) {
$conn->write(str_repeat('*', 400000));
});
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
$local = Block\await($promise, $loop, self::TIMEOUT);
/* @var $local React\Stream\Stream */
$received = 0;
$local->on('data', function ($chunk) use (&$received) {
$received += strlen($chunk);
});
Block\sleep(self::TIMEOUT, $loop);
$this->assertEquals(400000, $received);
}
public function testEmitsDataFromConnection()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$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->create('127.0.0.1', $port);
$local = Block\await($promise, $loop, self::TIMEOUT);
/* @var $local React\Stream\Stream */
$local->write("foo");
Block\sleep(self::TIMEOUT, $loop);
}
public function testEmitsDataInMultipleChunksFromConnection()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$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->create('127.0.0.1', $port);
$local = Block\await($promise, $loop, self::TIMEOUT);
/* @var $local React\Stream\Stream */
$local->write(str_repeat('*', 400000));
Block\sleep(self::TIMEOUT, $loop);
$this->assertEquals(400000, $received);
}
public function testPipesDataBackInMultipleChunksFromConnection()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$server->on('connection', function (ConnectionInterface $conn) use (&$received) {
$conn->pipe($conn);
});
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
$local = Block\await($promise, $loop, self::TIMEOUT);
/* @var $local React\Stream\Stream */
$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);
}
public function testEmitsConnectionForNewConnectionWithEncryptedCertificate()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem',
'passphrase' => 'swordfish'
));
$server->on('connection', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
Block\await($promise, $loop, self::TIMEOUT);
}
public function testEmitsErrorForServerWithInvalidCertificate()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => 'invalid.pem'
));
$server->on('connection', $this->expectCallableNever());
$server->on('error', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
$this->setExpectedException('RuntimeException', 'handshake');
Block\await($promise, $loop, self::TIMEOUT);
}
public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem'
));
$server->on('connection', $this->expectCallableNever());
$server->on('error', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
$this->setExpectedException('RuntimeException', 'handshake');
Block\await($promise, $loop, self::TIMEOUT);
}
public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassphrase()
{
$loop = Factory::create();
$server = new Server($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());
$server->listen(0);
$port = $server->getPort();
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
$this->setExpectedException('RuntimeException', 'handshake');
Block\await($promise, $loop, self::TIMEOUT);
}
public function testEmitsErrorForConnectionWithPeerVerification()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableNever());
$server->on('error', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => true
));
$promise = $connector->create('127.0.0.1', $port);
$promise->then(null, $this->expectCallableOnce());
Block\sleep(self::TIMEOUT, $loop);
}
public function testEmitsErrorIfConnectionIsCancelled()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableNever());
$server->on('error', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$connector = new SecureConnector(new TcpConnector($loop), $loop, array(
'verify_peer' => false
));
$promise = $connector->create('127.0.0.1', $port);
$promise->cancel();
$promise->then(null, $this->expectCallableOnce());
Block\sleep(self::TIMEOUT, $loop);
}
public function testEmitsNothingIfConnectionIsIdle()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableNever());
$server->on('error', $this->expectCallableNever());
$server->listen(0);
$port = $server->getPort();
$connector = new TcpConnector($loop);
$promise = $connector->create('127.0.0.1', $port);
$promise->then($this->expectCallableOnce());
Block\sleep(self::TIMEOUT, $loop);
}
public function testEmitsErrorIfConnectionIsNotSecureHandshake()
{
$loop = Factory::create();
$server = new Server($loop);
$server = new SecureServer($server, $loop, array(
'local_cert' => __DIR__ . '/../examples/localhost.pem'
));
$server->on('connection', $this->expectCallableNever());
$server->on('error', $this->expectCallableOnce());
$server->listen(0);
$port = $server->getPort();
$connector = new TcpConnector($loop);
$promise = $connector->create('127.0.0.1', $port);
$promise->then(function (Stream $stream) {
$stream->write("GET / HTTP/1.0\r\n\r\n");
});
Block\sleep(self::TIMEOUT, $loop);
}
}