From d60ba033c41d3329419575f2fbb02230855c258e Mon Sep 17 00:00:00 2001 From: Niklas Keller Date: Sun, 8 Oct 2017 09:40:53 +0200 Subject: [PATCH] Use stream_get_contents instead of fread for ResourceInputStream This fixes an issue with TLS streams: https://github.com/amphp/artax/issues/138. We still use for UDP, because stream_get_contents might read multiple packages there if I'm not mistaken. --- lib/ResourceInputStream.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/ResourceInputStream.php b/lib/ResourceInputStream.php index a434866..bdfc9ec 100644 --- a/lib/ResourceInputStream.php +++ b/lib/ResourceInputStream.php @@ -27,7 +27,7 @@ final class ResourceInputStream implements InputStream { /** * @param resource $stream Stream resource. - * @param int $chunkSize Chunk size per `fread()` operation. + * @param int $chunkSize Chunk size per read operation. */ public function __construct($stream, int $chunkSize = self::DEFAULT_CHUNK_SIZE) { if (!\is_resource($stream) || \get_resource_type($stream) !== 'stream') { @@ -35,6 +35,7 @@ public function __construct($stream, int $chunkSize = self::DEFAULT_CHUNK_SIZE) } $meta = \stream_get_meta_data($stream); + $isUdp = $meta["stream_type"] === "udp_socket"; if (\strpos($meta["mode"], "r") === false && \strpos($meta["mode"], "+") === false) { throw new \Error("Expected a readable stream"); @@ -48,9 +49,12 @@ public function __construct($stream, int $chunkSize = self::DEFAULT_CHUNK_SIZE) $deferred = &$this->deferred; $readable = &$this->readable; - $this->watcher = Loop::onReadable($this->resource, static function ($watcher, $stream) use (&$deferred, &$readable, $chunkSize) { - // Error reporting suppressed since fread() produces a warning if the stream has been shutdown - $data = @\fread($stream, $chunkSize); + $this->watcher = Loop::onReadable($this->resource, static function ($watcher, $stream) use (&$deferred, &$readable, $chunkSize, $isUdp) { + if ($isUdp) { + $data = @\fread($stream, $chunkSize); + } else { + $data = @\stream_get_contents($stream, $chunkSize); + } \assert($data !== false, "Trying to read from a previously fclose()'d resource. Do NOT manually fclose() resources the loop still has a reference to."); if ($data === '' && \feof($stream)) {