Skip to content

Commit 7acdc97

Browse files
naitsirchfabpot
authored andcommitted
[HttpFoundation] Prevent BinaryFileResponse::prepare from adding content type if no content is sent
1 parent 935f796 commit 7acdc97

File tree

2 files changed

+55
-31
lines changed

2 files changed

+55
-31
lines changed

BinaryFileResponse.php

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -201,22 +201,25 @@ public function setContentDisposition($disposition, $filename = '', $filenameFal
201201
*/
202202
public function prepare(Request $request)
203203
{
204-
if (!$this->headers->has('Content-Type')) {
205-
$this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
206-
}
204+
parent::prepare($request);
207205

208-
if ('HTTP/1.0' !== $request->server->get('SERVER_PROTOCOL')) {
209-
$this->setProtocolVersion('1.1');
206+
if ($this->isInformational() || $this->isEmpty()) {
207+
$this->maxlen = 0;
208+
209+
return $this;
210210
}
211211

212-
$this->ensureIEOverSSLCompatibility($request);
212+
if (!$this->headers->has('Content-Type')) {
213+
$this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
214+
}
213215

214216
$this->offset = 0;
215217
$this->maxlen = -1;
216218

217219
if (false === $fileSize = $this->file->getSize()) {
218220
return $this;
219221
}
222+
$this->headers->remove('Transfer-Encoding');
220223
$this->headers->set('Content-Length', $fileSize);
221224

222225
if (!$this->headers->has('Accept-Ranges')) {
@@ -286,6 +289,10 @@ public function prepare(Request $request)
286289
}
287290
}
288291

292+
if ($request->isMethod('HEAD')) {
293+
$this->maxlen = 0;
294+
}
295+
289296
return $this;
290297
}
291298

@@ -309,40 +316,42 @@ private function hasValidIfRangeHeader(?string $header): bool
309316
*/
310317
public function sendContent()
311318
{
312-
if (!$this->isSuccessful()) {
313-
return parent::sendContent();
314-
}
319+
try {
320+
if (!$this->isSuccessful()) {
321+
return parent::sendContent();
322+
}
315323

316-
if (0 === $this->maxlen) {
317-
return $this;
318-
}
324+
if (0 === $this->maxlen) {
325+
return $this;
326+
}
319327

320-
$out = fopen('php://output', 'w');
321-
$file = fopen($this->file->getPathname(), 'r');
328+
$out = fopen('php://output', 'w');
329+
$file = fopen($this->file->getPathname(), 'r');
322330

323-
ignore_user_abort(true);
331+
ignore_user_abort(true);
324332

325-
if (0 !== $this->offset) {
326-
fseek($file, $this->offset);
327-
}
333+
if (0 !== $this->offset) {
334+
fseek($file, $this->offset);
335+
}
328336

329-
$length = $this->maxlen;
330-
while ($length && !feof($file)) {
331-
$read = ($length > $this->chunkSize) ? $this->chunkSize : $length;
332-
$length -= $read;
337+
$length = $this->maxlen;
338+
while ($length && !feof($file)) {
339+
$read = ($length > $this->chunkSize) ? $this->chunkSize : $length;
340+
$length -= $read;
333341

334-
stream_copy_to_stream($file, $out, $read);
342+
stream_copy_to_stream($file, $out, $read);
335343

336-
if (connection_aborted()) {
337-
break;
344+
if (connection_aborted()) {
345+
break;
346+
}
338347
}
339-
}
340348

341-
fclose($out);
342-
fclose($file);
343-
344-
if ($this->deleteFileAfterSend && file_exists($this->file->getPathname())) {
345-
unlink($this->file->getPathname());
349+
fclose($out);
350+
fclose($file);
351+
} finally {
352+
if ($this->deleteFileAfterSend && file_exists($this->file->getPathname())) {
353+
unlink($this->file->getPathname());
354+
}
346355
}
347356

348357
return $this;

Tests/BinaryFileResponseTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,21 @@ public function testStream()
373373
$this->assertNull($response->headers->get('Content-Length'));
374374
}
375375

376+
public function testPrepareNotAddingContentTypeHeaderIfNoContentResponse()
377+
{
378+
$request = Request::create('/');
379+
$request->headers->set('If-Modified-Since', date('D, d M Y H:i:s').' GMT');
380+
381+
$response = new BinaryFileResponse(__DIR__.'/File/Fixtures/test.gif', 200, ['Content-Type' => 'application/octet-stream']);
382+
$response->setLastModified(new \DateTimeImmutable('-1 day'));
383+
$response->isNotModified($request);
384+
385+
$response->prepare($request);
386+
387+
$this->assertSame(BinaryFileResponse::HTTP_NOT_MODIFIED, $response->getStatusCode());
388+
$this->assertFalse($response->headers->has('Content-Type'));
389+
}
390+
376391
protected function provideResponse()
377392
{
378393
return new BinaryFileResponse(__DIR__.'/../README.md', 200, ['Content-Type' => 'application/octet-stream']);

0 commit comments

Comments
 (0)