Reputation: 51
I have problem with a php managed file download where the browser do no show progress of a file download. In fact, the browser appears to be waiting and waiting and waiting, until the file is completely downloaded. The file will then appear in the download list (with chrome and firefox). I cannot even download the file with IE8. I would like the browser to show the actual file size and the progress of the download.
Strangely the download is not even visible in firebug (no line appear in the network tab if you paste the download url).
I suspected problem with compression/zlib so I disabled both: no change. I disabled output buffering with the same result.
Live example can be found here: http://vps-1108994-11856.manage.myhosting.com/download.php Phpinfo: http://vps-1108994-11856.manage.myhosting.com/phpinfo.php
The code is below, your help is appreciated.
<?php
$name = "bac.epub";
$publicname = "bac.epub";
@apache_setenv('no-gzip', 1);
ini_set("zlib.output_compression", "Off");
header("Content-Type: application/epub+zip");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($name));
header("Content-disposition: attachment; filename=" . $publicname) );
ob_end_flush();
flush();
// dump the file and stop the script
$chunksize = 1 * (128 * 1024); // how many bytes per chunk
$size = filesize($name);
if ($size > $chunksize) {
$handle = fopen($name, 'rb');
$buffer = '';
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
sleep(1);
}
fclose($handle);
} else {
readfile($name);
}
exit;
The sleep in the code was to ensure that the download is long enough to see the progress.
Upvotes: 2
Views: 1159
Reputation: 426
This is likely caused by a firewall or some sort of proxy between you and the remote site. I was wrestling with the same problem - disabling gzip, flushing buffers etc. until I tried it under a web VPN and the progress indicator re-appeared.
I don't think that the progress indicator is buggy - it's just that the content is being embargoed before it gets to you, which appears as a waiting state in the download. Then when the content is scanned or approved, it may come down very quickly relative to the normal download speed of your site. For large enough files, maybe you could see a progress indicator at this stage.
Nothing you can do about it except to determine if this is the real reason for this behaviour.
Upvotes: 0
Reputation: 1735
header("Content-Type: application/epub+zip");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($file_path));
header("Content-disposition: attachment; filename=" . $local_file_name);
// dump the file and stop the script
$chunksize = 128 * 1024; // how many bytes per chunk (128 KB)
$size = filesize($file_path);
if ($size > $chunksize)
{
$handle = fopen($file_path, 'rb');
$buffer = '';
while (!feof($handle))
{
$buffer = fread($handle, $chunksize);
echo $buffer;
flush();
sleep(1);
}
fclose($handle);
}
else
{
readfile($file_path);
}
I have modified your code Francis. And now it works ... :)
Upvotes: 1
Reputation: 133
Keep it, really, really, simple.
<?php
header("Content-Type: application/epub+zip");
header("Content-disposition: attachment; filename=" . $publicname) );
if(!readfile($name))
echo 'Error!';
?>
It is all you really need.
Upvotes: 1