diff --git a/src/Connection.php b/src/Connection.php index fa7a2229..1f56c5d8 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -128,9 +128,10 @@ public function handleClose() // side already closed. Shutting down may return to blocking mode on // some legacy versions, so reset to non-blocking just in case before // continuing to close the socket resource. + // Underlying Stream implementation will take care of closing file + // handle, so we otherwise keep this open here. @stream_socket_shutdown($this->stream, STREAM_SHUT_RDWR); stream_set_blocking($this->stream, false); - fclose($this->stream); } public function getRemoteAddress() diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php new file mode 100644 index 00000000..d3563dfc --- /dev/null +++ b/tests/ConnectionTest.php @@ -0,0 +1,47 @@ +markTestSkipped('HHVM does not support socket operation on test memory stream'); + } + + $resource = fopen('php://memory', 'r+'); + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + + $connection = new Connection($resource, $loop); + $connection->close(); + + $this->assertFalse(is_resource($resource)); + } + + public function testCloseConnectionWillRemoveResourceFromLoopBeforeClosingResource() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM does not support socket operation on test memory stream'); + } + + $resource = fopen('php://memory', 'r+'); + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop->expects($this->once())->method('addWriteStream')->with($resource); + + $onRemove = null; + $loop->expects($this->once())->method('removeWriteStream')->with($this->callback(function ($param) use (&$onRemove) { + $onRemove = is_resource($param); + return true; + })); + + $connection = new Connection($resource, $loop); + $connection->write('test'); + $connection->close(); + + $this->assertTrue($onRemove); + $this->assertFalse(is_resource($resource)); + } +} diff --git a/tests/TcpConnectorTest.php b/tests/TcpConnectorTest.php index 17c55240..424957e8 100644 --- a/tests/TcpConnectorTest.php +++ b/tests/TcpConnectorTest.php @@ -98,6 +98,28 @@ public function connectionToTcpServerShouldSucceedWithNullAddressesAfterConnecti $this->assertNull($connection->getLocalAddress()); } + /** @test */ + public function connectionToTcpServerWillCloseWhenOtherSideCloses() + { + $loop = Factory::create(); + + // immediately close connection and server once connection is in + $server = new TcpServer(0, $loop); + $server->on('connection', function (ConnectionInterface $conn) use ($server) { + $conn->close(); + $server->close(); + }); + + $once = $this->expectCallableOnce(); + $connector = new TcpConnector($loop); + $connector->connect($server->getAddress())->then(function (ConnectionInterface $conn) use ($once) { + $conn->write('hello'); + $conn->on('close', $once); + }); + + $loop->run(); + } + /** @test */ public function connectionToEmptyIp6PortShouldFail() {