I have a PHP site on which the user can download file. Here is the code:
if (isset($_SERVER['HTTP_RANGE']))
{
$partialContent = true;
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = (isset($matches[2]) ? intval($matches[2]) : $filesize) - $offset;
}
else
$partialContent = false;
if (ob_get_level())
ob_end_clean();
header('Pragma: public');
header('Expires: -1');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Type: application/octet-stream');
if ($partialContent)
{
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes '.$offset.'-'.($offset + $length - 1).'/'.$filesize);
}
header('Content-Length: '.$length);
header('Accept-Ranges: bytes');
if ($fd = fopen($file, 'rb'))
{
fseek($fd, $offset);
$chunk = 1024 * 1024;
while (!feof($fd))
{
print fread($fd, $chunk);
$length -= $chunk;
if (ob_get_level() > 0)
ob_flush();
flush();
if (connection_status() != 0)
{
@fclose($fd);
return;
}
}
fclose($fd);
}
The file is being downloaded but the problem is that the downloading is being interrupted many times (for example, on my computer on the 2 GB file - ~30-50 times but it is a floating value), and every time one needs to press "Resume" in the browser menu. Where can be the ground of this problem?
Thanks to @KIKOSoftware, the problem has now been fixed. One needs using set_time_limit()
. Here is the working version of the code:
if (isset($_SERVER['HTTP_RANGE']))
{
$partialContent = true;
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = (isset($matches[2]) ? intval($matches[2]) : $filesize) - $offset;
}
else
$partialContent = false;
if (ob_get_level())
ob_end_clean();
header('Pragma: public');
header('Expires: -1');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Type: application/octet-stream');
if ($partialContent)
{
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes '.$offset.'-'.($offset + $length - 1).'/'.$filesize);
}
header('Content-Length: '.$length);
header('Accept-Ranges: bytes');
if ($fd = fopen($file, 'rb'))
{
fseek($fd, $offset);
$chunk = 1024 * 1024;
while (!feof($fd))
{
set_time_limit(60);
print fread($fd, $chunk);
$length -= $chunk;
if (ob_get_level() > 0)
ob_flush();
flush();
if (connection_status() != 0)
{
@fclose($fd);
return;
}
}
fclose($fd);
}