From 834de74a296caa918720470b0459ea78ac59f324 Mon Sep 17 00:00:00 2001 From: Matt Bonneau Date: Sat, 10 Feb 2018 11:57:48 -0500 Subject: [PATCH 1/7] Suggest correct subprotocol when subprotocol mismatch Fixes #24 --- src/Handshake/ServerNegotiator.php | 2 +- tests/unit/Handshake/ServerNegotiatorTest.php | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Handshake/ServerNegotiator.php b/src/Handshake/ServerNegotiator.php index 5a0073b..618b8e2 100644 --- a/src/Handshake/ServerNegotiator.php +++ b/src/Handshake/ServerNegotiator.php @@ -61,7 +61,7 @@ class ServerNegotiator implements NegotiatorInterface { 'Sec-WebSocket-Version' => $this->getVersionNumber() ]; if (count($this->_supportedSubProtocols) > 0) { - $upgradeSuggestion['Sec-WebSocket-Protocol'] = implode(', ', $this->_supportedSubProtocols); + $upgradeSuggestion['Sec-WebSocket-Protocol'] = implode(', ', array_keys($this->_supportedSubProtocols)); } if (true !== $this->verifier->verifyUpgradeRequest($request->getHeader('Upgrade'))) { return new Response(426, $upgradeSuggestion, null, '1.1', 'Upgrade header MUST be provided'); diff --git a/tests/unit/Handshake/ServerNegotiatorTest.php b/tests/unit/Handshake/ServerNegotiatorTest.php index 9c9aa8d..1d97c3c 100644 --- a/tests/unit/Handshake/ServerNegotiatorTest.php +++ b/tests/unit/Handshake/ServerNegotiatorTest.php @@ -172,4 +172,34 @@ Accept-Language: en-US,en;q=0.8'; $this->assertEquals('websocket', $response->getHeaderLine('Upgrade')); $this->assertFalse($response->hasHeader('Sec-WebSocket-Protocol')); } + + public function testSuggestsAppropriateSubprotocol() + { + $negotiator = new ServerNegotiator(new RequestVerifier()); + $negotiator->setStrictSubProtocolCheck(true); + $negotiator->setSupportedSubProtocols(['someproto']); + + $requestText = 'GET / HTTP/1.1 +Host: localhost:8080 +Connection: Upgrade +Upgrade: websocket +Sec-WebSocket-Version: 13 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 +Accept-Encoding: gzip, deflate, br +Accept-Language: en-US,en;q=0.9 +Sec-WebSocket-Key: HGt8eQax7nAOlXUw0/asPQ== +Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits + +'; + + $request = \GuzzleHttp\Psr7\parse_request($requestText); + + $response = $negotiator->handshake($request); + + $this->assertEquals('1.1', $response->getProtocolVersion()); + $this->assertEquals(426, $response->getStatusCode()); + $this->assertEquals('Upgrade', $response->getHeaderLine('Connection')); + $this->assertEquals('websocket', $response->getHeaderLine('Upgrade')); + $this->assertEquals('someproto', $response->getHeaderLine('Sec-WebSocket-Protocol')); + } } \ No newline at end of file From cb7c115211fbcdedc4925aea8d975948537e7db2 Mon Sep 17 00:00:00 2001 From: Andrey Bolonin Date: Tue, 10 Apr 2018 13:43:56 +0300 Subject: [PATCH 2/7] Update .travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 11d51b4..ea480f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,9 @@ php: - 5.4 - 5.5 - 5.6 - - 7 + - 7.0 + - 7.1 + - 7.2 - hhvm before_install: From 7b36995d0099fd5e240a31655f456d0f52dfd01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0tefan=20Ku=C5=A1n=C3=ADr?= Date: Wed, 2 May 2018 08:45:50 +0200 Subject: [PATCH 3/7] FIX PHP Fatal error: Allowed memory size of exhausted --- src/Messaging/Frame.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Messaging/Frame.php b/src/Messaging/Frame.php index 40f9eb2..360b70f 100644 --- a/src/Messaging/Frame.php +++ b/src/Messaging/Frame.php @@ -74,7 +74,7 @@ class Frame implements FrameInterface { * @param callable<\UnderflowException> $ufExceptionFactory */ public function __construct($payload = null, $final = true, $opcode = 1, callable $ufExceptionFactory = null) { - $this->ufeg = $ufExceptionFactory ?: function($msg = '') { + $this->ufeg = $ufExceptionFactory ?: static function($msg = '') { return new \UnderflowException($msg); }; From 6d7d1b8ff146fccd7f75edf4ac38c1594751a83d Mon Sep 17 00:00:00 2001 From: "me@jmoo.io" Date: Sat, 7 Jul 2018 17:40:12 -0400 Subject: [PATCH 4/7] Null out message buffer before calling onMessage handler --- src/Messaging/MessageBuffer.php | 8 ++++-- tests/unit/Messaging/MessageBufferTest.php | 33 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/Messaging/MessageBuffer.php b/src/Messaging/MessageBuffer.php index 07ff4f1..22f247c 100644 --- a/src/Messaging/MessageBuffer.php +++ b/src/Messaging/MessageBuffer.php @@ -98,13 +98,15 @@ class MessageBuffer { if ($this->messageBuffer->isCoalesced()) { $msgCheck = $this->checkMessage($this->messageBuffer); + + $msgBuffer = $this->messageBuffer; + $this->messageBuffer = null; + if (true !== $msgCheck) { $onControl($this->newCloseFrame($msgCheck, 'Ratchet detected an invalid UTF-8 payload')); } else { - $onMessage($this->messageBuffer); + $onMessage($msgBuffer); } - - $this->messageBuffer = null; } return $overflow; diff --git a/tests/unit/Messaging/MessageBufferTest.php b/tests/unit/Messaging/MessageBufferTest.php index c33ff0c..567afa2 100644 --- a/tests/unit/Messaging/MessageBufferTest.php +++ b/tests/unit/Messaging/MessageBufferTest.php @@ -6,6 +6,7 @@ use Ratchet\RFC6455\Messaging\CloseFrameChecker; use Ratchet\RFC6455\Messaging\Frame; use Ratchet\RFC6455\Messaging\Message; use Ratchet\RFC6455\Messaging\MessageBuffer; +use React\EventLoop\Factory; class MessageBufferTest extends \PHPUnit_Framework_TestCase { @@ -36,4 +37,36 @@ class MessageBufferTest extends \PHPUnit_Framework_TestCase $this->assertEquals(1000, $messageCount); } + + public function testProcessingMessagesAsynchronouslyWhileBlockingInMessageHandler() { + $loop = Factory::create(); + + $frameA = new Frame('a', true, Frame::OP_TEXT); + $frameB = new Frame('b', true, Frame::OP_TEXT); + + $bReceived = false; + + $messageBuffer = new MessageBuffer( + new CloseFrameChecker(), + function (Message $message) use (&$messageCount, &$bReceived, $loop) { + $payload = $message->getPayload(); + $bReceived = $payload === 'b'; + + if (!$bReceived) { + $loop->run(); + } + }, + null, + false + ); + + $loop->addPeriodicTimer(0.1, function () use ($messageBuffer, $frameB, $loop) { + $loop->stop(); + $messageBuffer->onData($frameB->getContents()); + }); + + $messageBuffer->onData($frameA->getContents()); + + $this->assertTrue($bReceived); + } } \ No newline at end of file From 26ea6c2d45ecf219ad6fb7026797476a0a471b50 Mon Sep 17 00:00:00 2001 From: Chris Boden Date: Mon, 11 Mar 2019 09:56:13 -0400 Subject: [PATCH 5/7] Add new lines to end of header in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guzzle had a BC break between minor versions throwing an exception if a header wasn’t passed without ending delimiters. --- tests/unit/Handshake/ServerNegotiatorTest.php | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/tests/unit/Handshake/ServerNegotiatorTest.php b/tests/unit/Handshake/ServerNegotiatorTest.php index 1d97c3c..6fa8e64 100644 --- a/tests/unit/Handshake/ServerNegotiatorTest.php +++ b/tests/unit/Handshake/ServerNegotiatorTest.php @@ -19,7 +19,9 @@ 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'; +Accept-Language: en-US,en;q=0.8 + +'; $request = \GuzzleHttp\Psr7\parse_request($requestText); @@ -46,7 +48,9 @@ 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'; +Accept-Language: en-US,en;q=0.8 + +'; $request = \GuzzleHttp\Psr7\parse_request($requestText); @@ -71,7 +75,9 @@ 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'; +Accept-Language: en-US,en;q=0.8 + +'; $request = \GuzzleHttp\Psr7\parse_request($requestText); @@ -96,7 +102,9 @@ 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'; +Accept-Language: en-US,en;q=0.8 + +'; $request = \GuzzleHttp\Psr7\parse_request($requestText); @@ -128,7 +136,9 @@ 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'; +Accept-Language: en-US,en;q=0.8 + +'; $request = \GuzzleHttp\Psr7\parse_request($requestText); @@ -160,7 +170,9 @@ 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'; +Accept-Language: en-US,en;q=0.8 + +'; $request = \GuzzleHttp\Psr7\parse_request($requestText); @@ -202,4 +214,4 @@ Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits $this->assertEquals('websocket', $response->getHeaderLine('Upgrade')); $this->assertEquals('someproto', $response->getHeaderLine('Sec-WebSocket-Protocol')); } -} \ No newline at end of file +} From acc1d28f0ad32258b4374364d9c1df977f5687c0 Mon Sep 17 00:00:00 2001 From: Chris Boden Date: Mon, 11 Mar 2019 10:03:22 -0400 Subject: [PATCH 6/7] Remove hhvm from testing --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ea480f5..09125d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ php: - 7.0 - 7.1 - 7.2 - - hhvm before_install: - export PATH=$HOME/.local/bin:$PATH From 4fb7c30a5d32c802537330d98e921d98f5460edf Mon Sep 17 00:00:00 2001 From: Ludwig Rafelsberger Date: Wed, 13 Mar 2019 10:57:40 +0100 Subject: [PATCH 7/7] Fix small typo in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7c09148..0f17c14 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ This library a protocol handler for the RFC6455 specification. It contains components for both server and client side handshake and messaging protocol negotation. -Aspects that are left open to interpertation in the specification are also left open in this library. -It is up to the implementation to determine how those interpertations are to be dealt with. +Aspects that are left open to interpretation in the specification are also left open in this library. +It is up to the implementation to determine how those interpretations are to be dealt with. This library is independent, framework agnostic, and does not deal with any I/O. HTTP upgrade negotiation integration points are handled with PSR-7 interfaces.