Skip to content

Commit

Permalink
Only close stream when the we reached end of the stream
Browse files Browse the repository at this point in the history
  • Loading branch information
WyriHaximus committed Dec 31, 2018
1 parent 2f39d05 commit 5b9d87d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/DuplexResourceStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public function handleData($stream)

if ($data !== '') {
$this->emit('data', array($data));
} else{
} elseif (\feof($this->stream)) {
// no data read => we reached the end and close the stream
$this->emit('end');
$this->close();
Expand Down
2 changes: 1 addition & 1 deletion src/ReadableResourceStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function handleData()

if ($data !== '') {
$this->emit('data', array($data));
} else{
} elseif (\feof($this->stream)) {
// no data read => we reached the end and close the stream
$this->emit('end');
$this->close();
Expand Down
38 changes: 38 additions & 0 deletions tests/DuplexResourceStreamIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace React\Tests\Stream;

use Clue\StreamFilter as Filter;
use React\Stream\DuplexResourceStream;
use React\Stream\ReadableResourceStream;
use React\EventLoop\ExtEventLoop;
Expand Down Expand Up @@ -342,6 +343,43 @@ public function testReadsNothingFromProcessPipeWithNoOutput($condition, $loopFac
$loop->run();
}

/**
* @covers React\Stream\ReadableResourceStream::handleData
* @dataProvider loopProvider
*/
public function testEmptyReadShouldntFcloseStream($condition, $loopFactory)
{
if (true !== $condition()) {
return $this->markTestSkipped('Loop implementation not available');
}

$server = stream_socket_server('tcp://127.0.0.1:0');

$client = stream_socket_client(stream_socket_get_name($server, false));
$stream = stream_socket_accept($server);


// add a filter which returns an error when encountering an 'a' when reading
Filter\append($stream, function ($chunk) {
return '';
}, STREAM_FILTER_READ);

$loop = $loopFactory();

$conn = new DuplexResourceStream($stream, $loop);
$conn->on('error', $this->expectCallableNever());
$conn->on('data', $this->expectCallableNever());
$conn->on('end', $this->expectCallableNever());

fwrite($client, "foobar\n");

$conn->handleData($stream);

fclose($stream);
fclose($client);
fclose($server);
}

private function loopTick(LoopInterface $loop)
{
$loop->addTimer(0, function () use ($loop) {
Expand Down
19 changes: 19 additions & 0 deletions tests/ReadableResourceStreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,25 @@ public function testDataErrorShouldEmitErrorAndClose()
$conn->handleData($stream);
}

/**
* @covers React\Stream\ReadableResourceStream::handleData
*/
public function testEmptyReadShouldntFcloseStream()
{
list($stream, $_) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
$loop = $this->createLoopMock();

$conn = new ReadableResourceStream($stream, $loop);
$conn->on('error', $this->expectCallableNever());
$conn->on('data', $this->expectCallableNever());
$conn->on('end', $this->expectCallableNever());

$conn->handleData();

fclose($stream);
fclose($_);
}

private function createLoopMock()
{
return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
Expand Down

0 comments on commit 5b9d87d

Please sign in to comment.