From 66c8eb065780bd1c5f58c5818863d62bdbfe3081 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sat, 25 Jan 2020 22:46:25 +0100 Subject: [PATCH] fixes #2 SimpleStreamResponseSender::sendStream if content-length was provided --- .../SimpleStreamResponseSender.php | 10 ++++- .../SimpleStreamResponseSenderTest.php | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/ResponseSender/SimpleStreamResponseSender.php b/src/ResponseSender/SimpleStreamResponseSender.php index 5a57bfac3..2d0f554a4 100644 --- a/src/ResponseSender/SimpleStreamResponseSender.php +++ b/src/ResponseSender/SimpleStreamResponseSender.php @@ -23,9 +23,17 @@ public function sendStream(SendResponseEvent $event) if ($event->contentSent()) { return $this; } + $response = $event->getResponse(); $stream = $response->getStream(); - fpassthru($stream); + $length = $response->getContentLength(); + + if ($length) { + stream_copy_to_stream($stream, fopen('php://output', 'wb'), $length); + } else { + fpassthru($stream); + } + $event->setContentSent(); } diff --git a/test/ResponseSender/SimpleStreamResponseSenderTest.php b/test/ResponseSender/SimpleStreamResponseSenderTest.php index 1cbc45831..56e17c409 100644 --- a/test/ResponseSender/SimpleStreamResponseSenderTest.php +++ b/test/ResponseSender/SimpleStreamResponseSenderTest.php @@ -46,6 +46,50 @@ public function testSendResponseTwoTimesPrintsResponseOnlyOnce() $this->assertEquals('', $body); } + public function testSendResponseContentLengthTruncate() + { + $file = fopen(__DIR__ . '/TestAsset/sample-stream-file.txt', 'rb'); + $content = file_get_contents(__DIR__ . '/TestAsset/sample-stream-file.txt'); + $length = strlen($content) - 1; + + $mockResponse = $this->createMock(Response\Stream::class); + $mockResponse->expects($this->once())->method('getStream')->will($this->returnValue($file)); + $mockResponse->expects($this->once())->method('getContentLength')->will($this->returnValue($length)); + $mockSendResponseEvent = $this->getSendResponseEventMock($mockResponse); + $responseSender = new SimpleStreamResponseSender(); + ob_start(); + $responseSender($mockSendResponseEvent); + $body = ob_get_clean(); + $this->assertEquals(substr($content, 0, $length), $body); + + ob_start(); + $responseSender($mockSendResponseEvent); + $body = ob_get_clean(); + $this->assertEquals('', $body); + } + + public function testSendResponseContentLengthOverflow() + { + $file = fopen(__DIR__ . '/TestAsset/sample-stream-file.txt', 'rb'); + $content = file_get_contents(__DIR__ . '/TestAsset/sample-stream-file.txt'); + $length = strlen($content) + 10; + + $mockResponse = $this->createMock(Response\Stream::class); + $mockResponse->expects($this->once())->method('getStream')->will($this->returnValue($file)); + $mockResponse->expects($this->once())->method('getContentLength')->will($this->returnValue($length)); + $mockSendResponseEvent = $this->getSendResponseEventMock($mockResponse); + $responseSender = new SimpleStreamResponseSender(); + ob_start(); + $responseSender($mockSendResponseEvent); + $body = ob_get_clean(); + $this->assertEquals($content, $body); + + ob_start(); + $responseSender($mockSendResponseEvent); + $body = ob_get_clean(); + $this->assertEquals('', $body); + } + protected function getSendResponseEventMock($response) { $mockSendResponseEvent = $this->getMockBuilder(ResponseSender\SendResponseEvent::class)