diff --git a/config/reverb.php b/config/reverb.php index f874e814..29adbcc4 100644 --- a/config/reverb.php +++ b/config/reverb.php @@ -31,6 +31,9 @@ 'reverb' => [ 'host' => env('REVERB_HOST', '0.0.0.0'), 'port' => env('REVERB_PORT', 8080), + 'options' => [ + 'tls' => [], + ], 'scaling' => [ 'enabled' => env('REVERB_SCALING_ENABLED', false), 'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'), diff --git a/src/Servers/Reverb/Console/Commands/StartServer.php b/src/Servers/Reverb/Console/Commands/StartServer.php index e267ff08..5bd1d903 100644 --- a/src/Servers/Reverb/Console/Commands/StartServer.php +++ b/src/Servers/Reverb/Console/Commands/StartServer.php @@ -54,6 +54,7 @@ public function handle(): void $server = ServerFactory::make( $host = $this->option('host') ?: $config['host'], $port = $this->option('port') ?: $config['port'], + $config['options'] ?? [], loop: $loop ); diff --git a/src/Servers/Reverb/Factory.php b/src/Servers/Reverb/Factory.php index 7ee44081..9bce4e07 100644 --- a/src/Servers/Reverb/Factory.php +++ b/src/Servers/Reverb/Factory.php @@ -34,7 +34,7 @@ class Factory /** * Create a new WebSocket server instance. */ - public static function make(string $host = '0.0.0.0', string $port = '8080', string $protocol = 'pusher', ?LoopInterface $loop = null): HttpServer + public static function make(string $host = '0.0.0.0', string $port = '8080', array $options = [], string $protocol = 'pusher', ?LoopInterface $loop = null): HttpServer { $loop = $loop ?: Loop::get(); @@ -43,8 +43,10 @@ public static function make(string $host = '0.0.0.0', string $port = '8080', str default => throw new InvalidArgumentException("Unsupported protocol [{$protocol}]."), }; + $uri = empty($options['tls']) ? "{$host}:{$port}" : "tls://{$host}:{$port}"; + return new HttpServer( - new SocketServer("{$host}:{$port}", [], $loop), + new SocketServer($uri, $options, $loop), $router, $loop ); diff --git a/tests/ReverbTestCase.php b/tests/ReverbTestCase.php index 01f8f3a0..71f9655a 100644 --- a/tests/ReverbTestCase.php +++ b/tests/ReverbTestCase.php @@ -6,7 +6,6 @@ use Laravel\Reverb\ServerProviderManager; use Laravel\Reverb\Servers\Reverb\Contracts\PubSubProvider; use Laravel\Reverb\Servers\Reverb\Factory; -use Ratchet\Client\WebSocket; use React\Async\SimpleFiber; use React\EventLoop\Loop; use React\Http\Browser; diff --git a/tests/Unit/Servers/Reverb/FactoryTest.php b/tests/Unit/Servers/Reverb/FactoryTest.php new file mode 100644 index 00000000..d29bbc46 --- /dev/null +++ b/tests/Unit/Servers/Reverb/FactoryTest.php @@ -0,0 +1,57 @@ +getValue($server); + $socketServer = (new ReflectionProperty($socket, 'server'))->getValue($socket); + + expect($socketServer)->toBeInstanceOf(TcpServer::class); + + $server->stop(); +}); + +it('can create a server with the given host and port', function () { + $server = Factory::make('127.0.0.1', '8001'); + + $socket = (new ReflectionProperty($server, 'socket'))->getValue($server); + $socketServer = (new ReflectionProperty($socket, 'server'))->getValue($socket); + + expect($socketServer)->toBeInstanceOf(TcpServer::class); + expect($socketServer->getAddress())->toBe('tcp://127.0.0.1:8001'); + + $server->stop(); +}); + +it('can create a tls server using a user provided certificate', function () { + $this->app->config->set('reverb.servers.reverb.options.tls.local_cert', '/path/to/cert.pem'); + $this->app->config->set('reverb.servers.reverb.options.tls.verify_peer', false); + $server = Factory::make(options: $this->app->config->get('reverb.servers.reverb.options')); + + $socket = (new ReflectionProperty($server, 'socket'))->getValue($server); + $socketServer = (new ReflectionProperty($socket, 'server'))->getValue($socket); + $context = (new ReflectionProperty($socketServer, 'context'))->getValue($socketServer); + + expect($socketServer)->toBeInstanceOf(SecureServer::class); + expect($context['local_cert'])->toBe('/path/to/cert.pem'); + expect($context['verify_peer'])->toBeFalse(); + + $server->stop(); +}); + +it('can create a server using tls on the given host and port', function () { + $this->app->config->set('reverb.servers.reverb.options.tls.local_cert', '/path/to/cert.pem'); + $server = Factory::make('127.0.0.1', '8002', $this->app->config->get('reverb.servers.reverb.options')); + + $socket = (new ReflectionProperty($server, 'socket'))->getValue($server); + $socketServer = (new ReflectionProperty($socket, 'server'))->getValue($socket); + + expect($socketServer)->toBeInstanceOf(SecureServer::class); + expect($socketServer->getAddress())->toBe('tls://127.0.0.1:8002'); + + $server->stop(); +}); \ No newline at end of file