2

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.

Jarek Jakubowski
  • 948
  • 10
  • 22
  • Just a small note, 201 response is "created" status and generally you should not return response body (binary response in your case). Take a look at: http://stackoverflow.com/questions/1226810/is-http-post-request-allowed-to-send-back-a-response-body – Vladimir Cvetic Sep 27 '16 at 08:51

2 Answers2

4

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...

Jarek Jakubowski
  • 948
  • 10
  • 22
  • Same here: that fix works for me! Thank you. Bizarre error: PHP or Symfony added a single, blank line at the start of files (in my case a JPG rather than a ZIP). That is true whatever method I used to generate the file (ended up with BinaryFileResponse). Presume a bug somewhere in Symfony? This on Symfony 2.8.15, Ubuntu 16.04, Apache2, PHP 5.6. Wasn't an issue in Symfony 2.3. Love to submit as a bug but not sure I can track it down accurately enough. – Adam Knowles Jan 10 '17 at 22:24
  • If you encounter this, look for empty newlines or any extra whitespace before ` – gronostaj Nov 30 '18 at 12:59
0

Since I see you are returning 201 http header I assume file has been created with same request. As per symfony documentation:

If you just created the file during this same request, the file may be sent without any content. This may be due to cached file stats that return zero for the size of the file. To fix this issue, call clearstatcache(false, $file) with the path to the binary file.

Vladimir Cvetic
  • 832
  • 3
  • 8
  • 23