Skip to content

Commit f2a27c4

Browse files
committed
Add support for streamed response
1 parent 53c15a6 commit f2a27c4

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

Factory/HttpFoundationFactory.php

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313

1414
use Psr\Http\Message\ServerRequestInterface;
1515
use Psr\Http\Message\ResponseInterface;
16+
use Psr\Http\Message\StreamInterface;
1617
use Psr\Http\Message\UploadedFileInterface;
1718
use Psr\Http\Message\UriInterface;
1819
use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
1920
use Symfony\Component\HttpFoundation\Cookie;
2021
use Symfony\Component\HttpFoundation\File\UploadedFile;
2122
use Symfony\Component\HttpFoundation\Request;
22-
use Symfony\Component\HttpFoundation\Response;
23+
use Symfony\Component\HttpFoundation\StreamedResponse;
2324

2425
/**
2526
* {@inheritdoc}
@@ -28,6 +29,19 @@
2829
*/
2930
class HttpFoundationFactory implements HttpFoundationFactoryInterface
3031
{
32+
/**
33+
* @var int Maximum output buffering size for each iteration when sending the response.
34+
*/
35+
private $responseBufferMaxLength;
36+
37+
/**
38+
* @param int $responseBufferMaxLength
39+
*/
40+
public function __construct($responseBufferMaxLength = 8192)
41+
{
42+
$this->responseBufferMaxLength = $responseBufferMaxLength;
43+
}
44+
3145
/**
3246
* {@inheritdoc}
3347
*/
@@ -140,11 +154,12 @@ protected function getTemporaryPath()
140154
*/
141155
public function createResponse(ResponseInterface $psrResponse)
142156
{
143-
$response = new Response(
144-
$psrResponse->getBody()->__toString(),
157+
$response = new StreamedResponse(
158+
$this->createStreamedResponseCallback($psrResponse->getBody()),
145159
$psrResponse->getStatusCode(),
146160
$psrResponse->getHeaders()
147161
);
162+
148163
$response->setProtocolVersion($psrResponse->getProtocolVersion());
149164

150165
foreach ($psrResponse->getHeader('Set-Cookie') as $cookie) {
@@ -226,4 +241,30 @@ private function createCookie($cookie)
226241
isset($cookieHttpOnly)
227242
);
228243
}
244+
245+
/**
246+
* @param StreamInterface $body
247+
*
248+
* @return callable
249+
*/
250+
private function createStreamedResponseCallback(StreamInterface $body)
251+
{
252+
$responseBufferMaxLength = $this->responseBufferMaxLength;
253+
254+
return function () use ($body, $responseBufferMaxLength) {
255+
if ($body->isSeekable()) {
256+
$body->rewind();
257+
}
258+
259+
if (! $body->isReadable()) {
260+
echo $body;
261+
262+
return;
263+
}
264+
265+
while (! $body->eof()) {
266+
echo $body->read($responseBufferMaxLength);
267+
}
268+
};
269+
}
229270
}

Tests/Factory/HttpFoundationFactoryTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,11 @@ public function testCreateResponse()
231231
$this->assertTrue($cookies[2]->isSecure());
232232
$this->assertTrue($cookies[2]->isHttpOnly());
233233

234-
$this->assertEquals('The response body', $symfonyResponse->getContent());
234+
ob_start();
235+
$symfonyResponse->sendContent();
236+
$sentContent = ob_get_clean();
237+
238+
$this->assertEquals('The response body', $sentContent);
235239
$this->assertEquals(200, $symfonyResponse->getStatusCode());
236240
}
237241
}

Tests/Fixtures/Stream.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
class Stream implements StreamInterface
2020
{
2121
private $stringContent;
22+
private $eof = true;
2223

2324
public function __construct($stringContent = '')
2425
{
@@ -49,12 +50,12 @@ public function tell()
4950

5051
public function eof()
5152
{
52-
return true;
53+
return $this->eof;
5354
}
5455

5556
public function isSeekable()
5657
{
57-
return false;
58+
return true;
5859
}
5960

6061
public function seek($offset, $whence = SEEK_SET)
@@ -63,6 +64,7 @@ public function seek($offset, $whence = SEEK_SET)
6364

6465
public function rewind()
6566
{
67+
$this->eof = false;
6668
}
6769

6870
public function isWritable()
@@ -81,6 +83,8 @@ public function isReadable()
8183

8284
public function read($length)
8385
{
86+
$this->eof = true;
87+
8488
return $this->stringContent;
8589
}
8690

0 commit comments

Comments
 (0)