Skip to content

Commit

Permalink
Merge pull request #140 from marcroberts/master
Browse files Browse the repository at this point in the history
Throw client read timeout earlier and don’t close connection
  • Loading branch information
sirn-se authored Jul 3, 2021
2 parents 62bc84e + 953a5c6 commit 45be5ab
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 2 deletions.
10 changes: 9 additions & 1 deletion lib/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,15 @@ protected function read(string $length): string
$data = '';
while (strlen($data) < $length) {
$buffer = @fread($this->socket, $length - strlen($data));

if (!$buffer) {
$meta = stream_get_meta_data($this->socket);
if (!empty($meta['timed_out'])) {
$message = 'Client read timeout';
$this->logger->error($message, $meta);
throw new TimeoutException($message, ConnectionException::TIMED_OUT, $meta);
}
}
if ($buffer === false) {
$read = strlen($data);
$this->throwException("Broken frame, read {$read} of stated {$length} bytes.");
Expand All @@ -464,7 +473,6 @@ protected function throwException(string $message, int $code = 0): void
fclose($this->socket);
$this->socket = null;
}
$json_meta = json_encode($meta);
if (!empty($meta['timed_out'])) {
$this->logger->error($message, $meta);
throw new TimeoutException($message, ConnectionException::TIMED_OUT, $meta);
Expand Down
12 changes: 12 additions & 0 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,18 @@ public function testBrokenRead(): void
$client->receive();
}

public function testReadTimeout(): void
{
MockSocket::initialize('client.connect', $this);
$client = new Client('ws://localhost:8000/my/mock/path');
$client->send('Connect');
MockSocket::initialize('receive-client-timeout', $this);
$this->expectException('WebSocket\TimeoutException');
$this->expectExceptionCode(1024);
$this->expectExceptionMessage('Client read timeout');
$client->receive();
}

public function testEmptyRead(): void
{
MockSocket::initialize('client.connect', $this);
Expand Down
17 changes: 16 additions & 1 deletion tests/scripts/receive-broken-read.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
"params": [],
"return": false
},
{
"function": "stream_get_meta_data",
"params": [
"@mock-stream"
],
"return": {
"timed_out": false,
"blocked": true,
"eof": true,
"stream_type": "tcp_socket\/ssl",
"mode": "r+",
"unread_bytes": 2,
"seekable": false
}
},
{
"function": "get_resource_type",
"params": [
Expand Down Expand Up @@ -40,4 +55,4 @@
],
"return":true
}
]
]
50 changes: 50 additions & 0 deletions tests/scripts/receive-client-timeout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"function": "get_resource_type",
"params": [
"@mock-stream"
],
"return": "stream"
},
{
"function": "fread",
"params": [],
"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
}
},
{
"function": "get_resource_type",
"params": [
"@mock-stream"
],
"return": "stream"
},
{
"function": "get_resource_type",
"params": [
"@mock-stream"
],
"return": "stream"
},
{
"function": "fclose",
"params": [
"@mock-stream"
],
"return":true
}
]
15 changes: 15 additions & 0 deletions tests/scripts/receive-empty-read.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
"params": [],
"return": ""
},
{
"function": "stream_get_meta_data",
"params": [
"@mock-stream"
],
"return": {
"timed_out": false,
"blocked": true,
"eof": false,
"stream_type": "tcp_socket\/ssl",
"mode": "r+",
"unread_bytes": 0,
"seekable": false
}
},
{
"function": "get_resource_type",
"params": [
Expand Down

0 comments on commit 45be5ab

Please sign in to comment.