statamic / v2-hub

Statamic 2 - Feature Requests and Bug Reports
https://statamic.com
95 stars 5 forks source link

Memory exhausted error when downloading large assets #2401

Closed anakadote closed 5 years ago

anakadote commented 5 years ago

When attempting to download a very large file via \Statamic\Http\Controllers\AssetContainer:download() a php memory exhaustion error is thrown, e.g.:

Symfony\Component\Debug\Exception\FatalErrorException: Allowed memory size of 536870912 bytes exhausted (tried to allocate 584040448 bytes) in ...

Replacing the call to passthru() on line 324 with the following resolves the issue for me:

while (! feof($stream)) {
    echo fread($stream, 8192);
}
fclose($stream);

Full updated method code:

public function download($container_id, $path)
{
    $container = AssetContainer::find($container_id);
    $asset = $container->asset($path);

    $file = $asset->path();

    $filesystem = $asset->disk()->filesystem()->getDriver();
    $stream = $filesystem->readStream($file);

    return response()->stream(function () use ($stream) {
        while (! feof($stream)) {
            echo fread($stream, 8192);
        }
        fclose($stream);
    }, 200, [
        "Content-Type" => $filesystem->getMimetype($file),
        "Content-Length" => $filesystem->getSize($file),
        "Content-disposition" => "attachment; filename=\"" . basename($file) . "\"",
    ]);
}