From 3981ec56ab3bfbbcdcd534d770cf82f7757e3f54 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Thu, 23 Jul 2026 08:52:08 -0400 Subject: [PATCH] Use the response factory instead of Guzzle for error response --- src/Handshake/ServerNegotiator.php | 3 +- tests/unit/Handshake/ServerNegotiatorTest.php | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/Handshake/ServerNegotiator.php b/src/Handshake/ServerNegotiator.php index 94f0549..bd762b8 100644 --- a/src/Handshake/ServerNegotiator.php +++ b/src/Handshake/ServerNegotiator.php @@ -2,7 +2,6 @@ namespace Ratchet\RFC6455\Handshake; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseFactoryInterface; -use GuzzleHttp\Psr7\Response; use Psr\Http\Message\ResponseInterface; /** @@ -127,7 +126,7 @@ public function handshake(RequestInterface $request): ResponseInterface { try { $perMessageDeflateRequest = PermessageDeflateOptions::fromRequestOrResponse($request)[0]; } catch (InvalidPermessageDeflateOptionsException $e) { - return new Response(400, [], null, '1.1', $e->getMessage()); + return $this->responseFactory->createResponse(400, $e->getMessage()); } if ($this->enablePerMessageDeflate && $perMessageDeflateRequest->isEnabled()) { diff --git a/tests/unit/Handshake/ServerNegotiatorTest.php b/tests/unit/Handshake/ServerNegotiatorTest.php index 382d96a..04136e8 100644 --- a/tests/unit/Handshake/ServerNegotiatorTest.php +++ b/tests/unit/Handshake/ServerNegotiatorTest.php @@ -4,6 +4,7 @@ use GuzzleHttp\Psr7\Message; use GuzzleHttp\Psr7\HttpFactory; +use Psr\Http\Message\ResponseFactoryInterface; use Ratchet\RFC6455\Handshake\RequestVerifier; use Ratchet\RFC6455\Handshake\ServerNegotiator; use PHPUnit\Framework\TestCase; @@ -124,6 +125,43 @@ public function testInvalidSecWebsocketVersion(): void { $this->assertEquals('13', $response->getHeaderLine('Sec-WebSocket-Version')); } + public function testInvalidPermessageDeflate(): void { + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $responseFactory->expects($this->exactly(2)) + ->method('createResponse') + ->willReturnOnConsecutiveCalls( + (new HttpFactory())->createResponse(), + (new HttpFactory())->createResponse(400, 'server_max_window_bits must have a value between 8 and 15.') + ); + + $negotiator = new ServerNegotiator(new RequestVerifier(), $responseFactory); + + $requestText = 'GET / HTTP/1.1 +Host: 127.0.0.1:6789 +Connection: Upgrade +Pragma: no-cache +Cache-Control: no-cache +Upgrade: websocket +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Sec-WebSocket-Version: 13 +Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=99 +Upgrade-Insecure-Requests: 1 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 +Accept-Encoding: gzip, deflate, sdch, br +Accept-Language: en-US,en;q=0.8 + +'; + + $request = Message::parseRequest($requestText); + + $response = $negotiator->handshake($request); + + $this->assertEquals('1.1', $response->getProtocolVersion()); + $this->assertEquals(400, $response->getStatusCode()); + $this->assertEquals('server_max_window_bits must have a value between 8 and 15.', $response->getReasonPhrase()); + } + public function testBadSubprotocolResponse(): void { $negotiator = new ServerNegotiator(new RequestVerifier(), new HttpFactory()); $negotiator->setStrictSubProtocolCheck(true);