I'm using a PHP script to control access to download files. This works fine for anything under 2Gb but fails for larger files.
The guts of the PHP (ignoring the access control):
if (ob_get_level()) ob_end_clean();
error_log('FILETEST: '.$path.' : '.filesize($path));
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($path));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
The error log shows the file size fine
[Tue Apr 08 11:01:16 2014] [error] [client *.*.*.*] FILETEST: /downloads/file.name : 2251373807, referer: http://myurl/files/
But the access log has a negative size:
*.*.*.* - - [08/Apr/2014:11:01:16 +0100] "GET /files/file.name HTTP/1.1" 200 -2043593489 "http://myurl/files/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0"
And so browsers refuse to download the file. In fact, using wget, it's not sending anything:
$ wget -S -O - http://myurl/files/file.name
--2014-04-08 11:33:38-- http://myurl/files/file.name
HTTP request sent, awaiting response... No data received.
Retrying.
Try to read the file in chunks and expose them to the browser instead of filling your local memory with 2GB and flushing all at once.
Replace readfile($path);
by:
@ob_end_flush();
flush();
$fileDescriptor = fopen($file, 'rb');
while ($chunk = fread($fileDescriptor, 8192)) {
echo $chunk;
@ob_end_flush();
flush();
}
fclose($fileDescriptor);
exit;
8192 bytes is a critical point in some cases, refere to php.net/fread.
Adding some microtime variables (and comparing with the pointer position of the file descriptor) will also allow you to controll the maximum speed of the download.
*(Flushing the output buffer also slightly depends on the webserver, use those commands to be sure it at least tries to flush as much as possible.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With