I think this is a easy one.
I have a simple website with a reserved area and some files to download from it.
I disabled direct file download with .htaccess, and I manage the download of file via this simple proxy.php file:
// ....
if ($filename === null || !file_exists($proxiedDirectory.$filename)) {
http_response_code(404);
exit;
}
if (!$site->is_logged_in()) {
http_response_code(403);
exit;
}
$fp = fopen($proxiedDirectory.$filename, 'rb');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
fpassthru($fp);
exit;
This code WORKS perfectly, but unfortunately I have a 1.2Gb file that users could download, and this script is too slow, and doesn't allow the full file download.
Any help would be appreciated,
Thanks in advance!
M.
You can use a combination of header()
, set_time_limit()
, fgets()
, ob_flush()
, flush()
. Here is my example, best using Php 64bit on OS 64bit because filesize()
has not limits in this architecture.
// Set force download headers
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . sprintf("%u", filesize($downloads_folder . $file)));
// Open and output file contents
set_time_limit(0);
$fh = fopen($downloads_folder . $file, "rb");
while (!feof($fh)) {
echo fgets($fh);
ob_flush();
flush();
}
fclose($fh);
exit;
Hope this helps.