diff --git a/config/reverb.php b/config/reverb.php index b919ea11..59bd022e 100644 --- a/config/reverb.php +++ b/config/reverb.php @@ -73,6 +73,7 @@ 'secret' => env('PUSHER_APP_SECRET'), 'allowed_origins' => ['*'], 'ping_interval' => env('REVERB_APP_PING_INTERVAL', 5), + 'max_message_size' => env('REVERB_APP_MAX_MESSAGE_SIZE', 10000), ], ], diff --git a/src/Application.php b/src/Application.php index d0990c8e..818a1670 100644 --- a/src/Application.php +++ b/src/Application.php @@ -9,7 +9,8 @@ public function __construct( protected string $key, protected string $secret, protected int $pingInterval, - protected array $allowedOrigins + protected array $allowedOrigins, + protected int $maxMessageSize, ) { } @@ -52,4 +53,12 @@ public function pingInterval(): int { return $this->pingInterval; } + + /** + * Get the maximum message size allowed from the client. + */ + public function maxMessageSize(): int + { + return $this->maxMessageSize; + } } diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index bb4e5559..b5629922 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -63,6 +63,7 @@ public function find(string $key, $value): Application $app['secret'], $app['ping_interval'], $app['allowed_origins'], + $app['max_message_size'], ); } } diff --git a/src/Servers/Reverb/Controller.php b/src/Servers/Reverb/Controller.php index bc9d27e9..088ed1b8 100644 --- a/src/Servers/Reverb/Controller.php +++ b/src/Servers/Reverb/Controller.php @@ -25,6 +25,7 @@ public function __invoke(RequestInterface $request, WsConnection $connection, st return; } + $connection->withMaxMessageSize($reverbConnection->app()->maxMessageSize()); $connection->onMessage(fn (string $message) => $this->server->message($reverbConnection, $message)); $connection->onClose(fn () => $this->server->close($reverbConnection)); $connection->openBuffer(); diff --git a/src/WebSockets/WsConnection.php b/src/WebSockets/WsConnection.php index 9a2cbbca..06dc35dd 100644 --- a/src/WebSockets/WsConnection.php +++ b/src/WebSockets/WsConnection.php @@ -33,6 +33,13 @@ class WsConnection extends EventEmitter */ protected $onClose; + /** + * The maximum number of allowed bytes for each message. + * + * @var int + */ + protected $maxMessageSize; + public function __construct(public Connection $connection) { // @@ -45,6 +52,7 @@ public function openBuffer(): void { $this->buffer = new MessageBuffer( new CloseFrameChecker, + maxMessagePayloadSize: $this->maxMessageSize, onMessage: $this->onMessage ?: fn () => null, onControl: fn (FrameInterface $message) => $this->control($message), sender: [$this->connection, 'send'] @@ -94,6 +102,14 @@ public function onClose(callable $callback): void $this->onClose = $callback; } + /** + * Set the maximum number of allowed bytes for each message from the client. + */ + public function withMaxMessageSize(int $size): void + { + $this->maxMessageSize = $size; + } + /** * Close the connection. */ diff --git a/tests/Feature/Reverb/ServerTest.php b/tests/Feature/Reverb/ServerTest.php index c062b0de..d9a312e7 100644 --- a/tests/Feature/Reverb/ServerTest.php +++ b/tests/Feature/Reverb/ServerTest.php @@ -323,6 +323,13 @@ $this->connect(); })->throws('Connection closed before handshake'); +it('limits the size of messages', function () { + $connection = $this->connect(key: 'pusher-key-3', headers: ['Origin' => 'http://laravel.com']); + $message = $this->send(['This message is waaaaaay longer than the 1 byte limit'], $connection); + + expect($message)->toBe('Maximum message size exceeded'); +}); + it('clears application state between requests', function () { $this->subscribe('test-channel'); diff --git a/tests/ReverbTestCase.php b/tests/ReverbTestCase.php index fbf254bb..7edc18be 100644 --- a/tests/ReverbTestCase.php +++ b/tests/ReverbTestCase.php @@ -67,6 +67,7 @@ protected function defineEnvironment($app) 'capacity' => null, 'allowed_origins' => ['*'], 'ping_interval' => 10, + 'max_message_size' => 1000000, ]); $app['config']->set('reverb.apps.apps.2', [ @@ -76,6 +77,7 @@ protected function defineEnvironment($app) 'capacity' => null, 'allowed_origins' => ['laravel.com'], 'ping_interval' => 10, + 'max_message_size' => 1, ]); } @@ -177,6 +179,10 @@ public function send(array $message, WebSocket $connection = null): string $promise->resolve((string) $message); }); + $connection->on('close', function ($code, $message) use ($promise) { + $promise->resolve((string) $message); + }); + $connection->send(json_encode($message)); return await($promise->promise());