Search code examples
symfonysymfony-http-foundation

Symfony BinaryFileResponse cuts off end of file?


I have a ZIP File to be served via Symfony. The controller looks like this:

$headers = [
    'Content-Type' => 'application/zip',
    'Content-Disposition' => 'attachment; filename="archive.zip"'
];
return new Response(file_get_contents($pathToFile), 201, $headers);

And this one works well. However, if I try to use BinaryFileResponse (as the Documentation recommends), the ZIP File gets corrupted:

$response = new BinaryFileResponse($pathToFile);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
$response->setStatusCode(Response::HTTP_CREATED);
return $response;

The output I get when trying to fix the file with zip -FF archive.zip --out fixed.zip :

zip warning: End record (EOCDR) only 17 bytes - assume truncated

(this command fixes the archive correctly)

Is it a bug or am I doing something wrong?

My setup:

  • Symfony 2.8.11
  • PHP 7.0.8
  • Ubuntu 16.04
  • nginx 1.10.0

EDIT:

I have made proposed changes, but the problem still exists:

$response = new BinaryFileResponse($pathToFile);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'archive.zip');
$response->headers->set('Content-Type', 'application/zip');
clearstatcache(false, $pathToFile);
return $response;

EDIT2:

I found one more interesting thing: serving this ZIP file with standard Response (the working code) creates openable file, however running zip -T on it gives:

1 extra byte at beginning or within zipfile

Testing original file gives:

OK

The size of file is less than 1MB.


Solution

  • SOLUTION:

    When I opened generated ZIP file in text editor, I found an extra empty line at the beggining of it...

    So I've added ob_clean(); before returning Response object and now it works!

    No idea where this newline character came from, though...