From 868846b3b74e4a650b045befeca430c01b1eea01 Mon Sep 17 00:00:00 2001 From: Patrick Safarov Date: Mon, 6 May 2019 13:18:36 +0200 Subject: [PATCH] Stop using feof for checking if socket is closed --- lib/ResourceOutputStream.php | 16 ++++++++-------- test/ResourceOutputStreamTest.php | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/ResourceOutputStream.php b/lib/ResourceOutputStream.php index afe0e46..d7b7b81 100644 --- a/lib/ResourceOutputStream.php +++ b/lib/ResourceOutputStream.php @@ -71,10 +71,6 @@ public function __construct($stream, int $chunkSize = null) continue; } - if (!\is_resource($stream) || @\feof($stream)) { - throw new StreamException("The stream was closed by the peer"); - } - // Error reporting suppressed since fwrite() emits E_WARNING if the pipe is broken or the buffer is full. // Use conditional, because PHP doesn't like getting null passed if ($chunkSize) { @@ -101,6 +97,11 @@ public function __construct($stream, int $chunkSize = null) $emptyWrites = 0; + if (!@\fflush($stream)) { + throw new StreamException("Failed to flush data from buffer"); + } + + if ($length > $written) { $data = \substr($data, $written); $writes->unshift([$data, $written + $previous, $deferred]); @@ -179,10 +180,6 @@ private function send(string $data, bool $end = false): Promise return new Success(0); } - if (!\is_resource($this->resource) || @\feof($this->resource)) { - return new Failure(new StreamException("The stream was closed by the peer")); - } - // Error reporting suppressed since fwrite() emits E_WARNING if the pipe is broken or the buffer is full. // Use conditional, because PHP doesn't like getting null passed. if ($this->chunkSize) { @@ -194,6 +191,9 @@ private function send(string $data, bool $end = false): Promise \assert($written !== false, "Trying to write on a previously fclose()'d resource. Do NOT manually fclose() resources the loop still has a reference to."); if ($length === $written) { + if (!@\fflush($this->resource)) { + return new Failure(new StreamException("Failed to flush data from buffer")); + } if ($end) { $this->close(); } diff --git a/test/ResourceOutputStreamTest.php b/test/ResourceOutputStreamTest.php index 98ad4cc..4b8d2a5 100644 --- a/test/ResourceOutputStreamTest.php +++ b/test/ResourceOutputStreamTest.php @@ -44,7 +44,7 @@ public function testBrokenPipe() \fclose($b); $this->expectException(StreamException::class); - $this->expectExceptionMessage("The stream was closed by the peer"); + $this->expectExceptionMessage("Failed to write to stream after multiple attempts"); wait($stream->write("foobar")); } @@ -60,7 +60,7 @@ public function testClosedRemoteSocket() \fclose($b); $this->expectException(StreamException::class); - $this->expectExceptionMessage("The stream was closed by the peer"); + $this->expectExceptionMessage("Failed to write to stream after multiple attempts"); // The first write still succeeds somehow... wait($stream->write("foobar")); @@ -88,7 +88,7 @@ public function testClosedRemoteSocketWithFork() \fclose($b); $this->expectException(StreamException::class); - $this->expectExceptionMessage("The stream was closed by the peer"); + $this->expectExceptionMessage("Failed to write to stream after multiple attempts"); try { // The first write still succeeds somehow...