From deda3d4a7f7f297139d97d7b01a32c35c79ff4a3 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 29 Jun 2025 17:51:16 +0800 Subject: [PATCH 1/2] Fix incomplete StreamInterface implementation in PsrMessageStream --- src/Internal/PsrMessageStream.php | 11 +++++++++-- test/Internal/PsrMessageStreamTest.php | 3 +-- test/PsrAdapterTest.php | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Internal/PsrMessageStream.php b/src/Internal/PsrMessageStream.php index d495e63..1d81ffb 100644 --- a/src/Internal/PsrMessageStream.php +++ b/src/Internal/PsrMessageStream.php @@ -16,6 +16,8 @@ final class PsrMessageStream implements StreamInterface private bool $isEof = false; + private bool $isClosed = false; + private int $position = 0; public function __construct(private readonly ReadableStream $source, private readonly ?int $size = null) @@ -32,6 +34,7 @@ public function close(): void $this->source->close(); $this->buffer = ''; $this->isEof = true; + $this->isClosed = true; } public function detach(): void @@ -46,6 +49,10 @@ public function eof(): bool public function getContents(): string { + if ($this->isClosed) { + throw new \RuntimeException("Stream is closed"); + } + $buffer = $this->buffer; $this->buffer = ''; @@ -69,7 +76,7 @@ public function getSize(): ?int public function isReadable(): bool { - return !$this->eof(); + return !$this->isClosed; } public function isSeekable(): bool @@ -84,7 +91,7 @@ public function isWritable(): bool public function read(int $length): string { - if ($this->eof()) { + if ($this->isClosed) { throw new \RuntimeException("Stream is closed"); } diff --git a/test/Internal/PsrMessageStreamTest.php b/test/Internal/PsrMessageStreamTest.php index cd7c35a..a2bcb59 100644 --- a/test/Internal/PsrMessageStreamTest.php +++ b/test/Internal/PsrMessageStreamTest.php @@ -93,8 +93,7 @@ public function testTell(): void self::assertSame('', $requestStream->read(8192)); self::assertSame(6, $requestStream->tell()); self::assertTrue($requestStream->eof()); - self::assertFalse($requestStream->isReadable()); - + self::assertTrue($requestStream->isReadable()); } public function testRewindThrowsException(): void diff --git a/test/PsrAdapterTest.php b/test/PsrAdapterTest.php index 2ac7fa2..982977e 100644 --- a/test/PsrAdapterTest.php +++ b/test/PsrAdapterTest.php @@ -267,7 +267,7 @@ public function testToPsrResponseReturnsResponseWithStreamableBody(): void self::assertSame('content', $body->read(8192)); self::assertTrue($body->eof()); - self::assertFalse($body->isReadable()); + self::assertTrue($body->isReadable()); } public function testFromPsrResponseWithRequestReturnsResultWithSameRequest(): void From 2eaa4a591afcc48d3c14086fcba1f508eb49b0c3 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 28 Aug 2025 17:02:44 +0800 Subject: [PATCH 2/2] Return null from detach method according to StreamInterface --- src/Internal/PsrMessageStream.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Internal/PsrMessageStream.php b/src/Internal/PsrMessageStream.php index 1d81ffb..2aa90fb 100644 --- a/src/Internal/PsrMessageStream.php +++ b/src/Internal/PsrMessageStream.php @@ -37,9 +37,11 @@ public function close(): void $this->isClosed = true; } - public function detach(): void + public function detach() { $this->close(); + + return null; } public function eof(): bool