I recently started using Flysystem in an existing application with the intention of abstracting the local and remote (specifically, S3) filesystems. Everything was working ok on my development environment, on which I successfully configured the LocalAdapter. However, I cannot get S3 file downloads to work. I'd like to point out that file uploads are working perfectly, given that I can successfully download the file by manually browsing the S3 bucket in the AWS management console. That being said, I will skip the code that initializes the $filesystem
variable.
My application is using a PSR-7 approach. That is, the code below is inside a function that is passed an object of type Psr\Http\Message\ServerRequestInterface
as first argument and an object of type Psr\Http\Message\ResponseInterface
as the second. Given that the local filesystem works fine, I think it is safe to assume that the problem doesn't lie there.
This is the code:
<?php
$stream = new \Zend\Diactoros\Stream($filesystem->readStream($filename));
$filesize = $stream->getSize();
return $response
->withHeader('Content-Type', 'application/pdf')
->withHeader('Content-Transfer-Encoding', 'Binary')
->withHeader('Content-Description', 'File Transfer')
->withHeader('Pragma', 'public')
->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate')
->withHeader('Content-Length', "{$filesize}")
->withBody($stream);
When I dump the $stream
variable and the $filesize
variable the results are as expected. The remote file contents are successfully printed. However, the file download is always corrupted and the file size is always of 0 bytes.
I am assuming that Flysystem takes care of everything behind the scenes and that I don't have to manually download the file to a temp folder first, before serving it to the client.
Any clue to what could be the problem?
Update 1
I have also tried with the following code, without any luck. However, it continues to work locally:
use Zend\Diactoros\CallbackStream;
$stream = new CallbackStream(function() use ($filesystem, $filename) {
$resource = $filesystem->readStream($filename);
while (!feof($resource)) {
echo fread($resource, 1024);
}
fclose($resource);
return '';
});
and
use Zend\Diactoros\CallbackStream;
$stream = new CallbackStream(function() use ($filesystem, $filename) {
$resource = $filesystem->readStream($filename);
fpassthru($resource);
return '';
});