From f89be2a7fbf4b8f12c45f28bf87a2ae590f95ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Mon, 25 Apr 2022 15:06:11 +0200 Subject: [PATCH 1/2] Handle read error during handshake --- docs/Changelog.md | 4 ++ lib/Client.php | 6 ++ tests/ClientTest.php | 10 +++ .../client.connect-handshake-timeout.json | 65 +++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 tests/scripts/client.connect-handshake-timeout.json diff --git a/docs/Changelog.md b/docs/Changelog.md index e6392fa..4d98063 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -6,6 +6,10 @@ > PHP version `^7.2|^8.0` +### `1.5.8` + + * Handle read error during handshake (@sirn-se) + ### `1.5.7` * Large header block fix (@sirn-se) diff --git a/lib/Client.php b/lib/Client.php index 89e7810..0eec77a 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -180,6 +180,12 @@ function ($key, $value) { $response = ''; do { $buffer = fgets($this->socket, 1024); + if ($buffer === false) { + $meta = stream_get_meta_data($this->socket); + $message = 'Client handshake timeout'; + $this->logger->error($message, $meta); + throw new TimeoutException($message, ConnectionException::TIMED_OUT, $meta); + } $response .= $buffer; } while (substr_count($response, "\r\n\r\n") == 0); diff --git a/tests/ClientTest.php b/tests/ClientTest.php index a5c8d84..9dbeb67 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -352,6 +352,16 @@ public function testBrokenRead(): void $client->receive(); } + public function testHandshakeTimeout(): void + { + MockSocket::initialize('client.connect-handshake-timeout', $this); + $client = new Client('ws://localhost:8000/my/mock/path'); + $this->expectException('WebSocket\TimeoutException'); + $this->expectExceptionCode(1024); + $this->expectExceptionMessage('Client handshake timeout'); + $client->send('Connect'); + } + public function testReadTimeout(): void { MockSocket::initialize('client.connect', $this); diff --git a/tests/scripts/client.connect-handshake-timeout.json b/tests/scripts/client.connect-handshake-timeout.json new file mode 100644 index 0000000..f3aaced --- /dev/null +++ b/tests/scripts/client.connect-handshake-timeout.json @@ -0,0 +1,65 @@ +[ + { + "function": "stream_context_create", + "params": [], + "return": "@mock-stream-context" + }, + { + "function": "stream_socket_client", + "params": [ + "tcp:\/\/localhost:8000", + null, + null, + 5, + 4, + "@mock-stream-context" + ], + "return": "@mock-stream" + }, + { + "function": "get_resource_type", + "params": [ + "@mock-stream" + ], + "return": "stream" + }, + { + "function": "stream_set_timeout", + "params": [ + "@mock-stream", + 5 + ], + "return": true + }, + { + "function": "fwrite", + "params": [ + "@mock-stream" + ], + "return-op": "key-save", + "return": 199 + }, + { + "function": "fgets", + "params": [ + "@mock-stream", + 1024 + ], + "return": false + }, + { + "function": "stream_get_meta_data", + "params": [ + "@mock-stream" + ], + "return": { + "timed_out": true, + "blocked": true, + "eof": false, + "stream_type": "tcp_socket\/ssl", + "mode": "r+", + "unread_bytes": 0, + "seekable": false + } + } +] \ No newline at end of file From ed8996e29b71b48ad136e402f6981f6927777e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Mon, 25 Apr 2022 15:14:38 +0200 Subject: [PATCH 2/2] Error type --- lib/Client.php | 4 ++-- tests/ClientTest.php | 10 +++++----- ...imeout.json => client.connect-handshake-error.json} | 0 3 files changed, 7 insertions(+), 7 deletions(-) rename tests/scripts/{client.connect-handshake-timeout.json => client.connect-handshake-error.json} (100%) diff --git a/lib/Client.php b/lib/Client.php index 0eec77a..71d320a 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -182,9 +182,9 @@ function ($key, $value) { $buffer = fgets($this->socket, 1024); if ($buffer === false) { $meta = stream_get_meta_data($this->socket); - $message = 'Client handshake timeout'; + $message = 'Client handshake error'; $this->logger->error($message, $meta); - throw new TimeoutException($message, ConnectionException::TIMED_OUT, $meta); + throw new ConnectionException($message); } $response .= $buffer; } while (substr_count($response, "\r\n\r\n") == 0); diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 9dbeb67..e0cf94c 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -352,13 +352,13 @@ public function testBrokenRead(): void $client->receive(); } - public function testHandshakeTimeout(): void + public function testHandshakeError(): void { - MockSocket::initialize('client.connect-handshake-timeout', $this); + MockSocket::initialize('client.connect-handshake-error', $this); $client = new Client('ws://localhost:8000/my/mock/path'); - $this->expectException('WebSocket\TimeoutException'); - $this->expectExceptionCode(1024); - $this->expectExceptionMessage('Client handshake timeout'); + $this->expectException('WebSocket\ConnectionException'); + $this->expectExceptionCode(0); + $this->expectExceptionMessage('Client handshake error'); $client->send('Connect'); } diff --git a/tests/scripts/client.connect-handshake-timeout.json b/tests/scripts/client.connect-handshake-error.json similarity index 100% rename from tests/scripts/client.connect-handshake-timeout.json rename to tests/scripts/client.connect-handshake-error.json