Jarek Jakubowski
Jarek Jakubowski

Reputation: 976

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:


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.

Upvotes: 2

Views: 2359

Answers (2)

Jarek Jakubowski
Jarek Jakubowski

Reputation: 976

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

Upvotes: 5

Vladimir Cvetic
Vladimir Cvetic

Reputation: 842

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.

Upvotes: 0

Related Questions