|
13 | 13 |
|
14 | 14 | use Psr\Http\Message\ResponseInterface;
|
15 | 15 | use Psr\Http\Message\ServerRequestInterface;
|
| 16 | +use Psr\Http\Message\StreamInterface; |
16 | 17 | use Psr\Http\Message\UploadedFileInterface;
|
17 | 18 | use Psr\Http\Message\UriInterface;
|
18 | 19 | use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
|
19 | 20 | use Symfony\Component\HttpFoundation\Cookie;
|
20 | 21 | use Symfony\Component\HttpFoundation\File\UploadedFile;
|
21 | 22 | use Symfony\Component\HttpFoundation\Request;
|
22 | 23 | use Symfony\Component\HttpFoundation\Response;
|
| 24 | +use Symfony\Component\HttpFoundation\StreamedResponse; |
23 | 25 |
|
24 | 26 | /**
|
25 | 27 | * {@inheritdoc}
|
|
28 | 30 | */
|
29 | 31 | class HttpFoundationFactory implements HttpFoundationFactoryInterface
|
30 | 32 | {
|
| 33 | + /** |
| 34 | + * @var int The maximum output buffering size for each iteration when sending the response |
| 35 | + */ |
| 36 | + private $responseBufferMaxLength; |
| 37 | + |
| 38 | + public function __construct(int $responseBufferMaxLength = 16372) |
| 39 | + { |
| 40 | + $this->responseBufferMaxLength = $responseBufferMaxLength; |
| 41 | + } |
| 42 | + |
31 | 43 | /**
|
32 | 44 | * {@inheritdoc}
|
33 | 45 | */
|
@@ -138,16 +150,25 @@ protected function getTemporaryPath()
|
138 | 150 | /**
|
139 | 151 | * {@inheritdoc}
|
140 | 152 | */
|
141 |
| - public function createResponse(ResponseInterface $psrResponse) |
| 153 | + public function createResponse(ResponseInterface $psrResponse, bool $streamed = false) |
142 | 154 | {
|
143 | 155 | $cookies = $psrResponse->getHeader('Set-Cookie');
|
144 | 156 | $psrResponse = $psrResponse->withoutHeader('Set-Cookie');
|
145 | 157 |
|
146 |
| - $response = new Response( |
147 |
| - $psrResponse->getBody()->__toString(), |
148 |
| - $psrResponse->getStatusCode(), |
149 |
| - $psrResponse->getHeaders() |
150 |
| - ); |
| 158 | + if ($streamed) { |
| 159 | + $response = new StreamedResponse( |
| 160 | + $this->createStreamedResponseCallback($psrResponse->getBody()), |
| 161 | + $psrResponse->getStatusCode(), |
| 162 | + $psrResponse->getHeaders() |
| 163 | + ); |
| 164 | + } else { |
| 165 | + $response = new Response( |
| 166 | + $psrResponse->getBody()->__toString(), |
| 167 | + $psrResponse->getStatusCode(), |
| 168 | + $psrResponse->getHeaders() |
| 169 | + ); |
| 170 | + } |
| 171 | + |
151 | 172 | $response->setProtocolVersion($psrResponse->getProtocolVersion());
|
152 | 173 |
|
153 | 174 | foreach ($cookies as $cookie) {
|
@@ -237,4 +258,23 @@ private function createCookie($cookie)
|
237 | 258 | isset($samesite) ? $samesite : null
|
238 | 259 | );
|
239 | 260 | }
|
| 261 | + |
| 262 | + private function createStreamedResponseCallback(StreamInterface $body): callable |
| 263 | + { |
| 264 | + return function () use ($body) { |
| 265 | + if ($body->isSeekable()) { |
| 266 | + $body->rewind(); |
| 267 | + } |
| 268 | + |
| 269 | + if (!$body->isReadable()) { |
| 270 | + echo $body; |
| 271 | + |
| 272 | + return; |
| 273 | + } |
| 274 | + |
| 275 | + while (!$body->eof()) { |
| 276 | + echo $body->read($this->responseBufferMaxLength); |
| 277 | + } |
| 278 | + }; |
| 279 | + } |
240 | 280 | }
|
0 commit comments