PHP Download remote file to client with bandwidth counter - php

I have a code for download.php remote file:
function _downloadIt($url,$size,$filename,$user='',$pass='',$cookie='')
{
$filesize = $size;
$filename = $filename;
$directlink = $url;
$link = $directlink;
$link = str_replace(" ","%20",$link);
if(!$link) {
sleep(15);
header("HTTP/1.1 404 Link Error");
}
$range = '';
if (isset($_SERVER['HTTP_RANGE'])) {
$range = substr($_SERVER['HTTP_RANGE'], 6);
}
$port = 80;
$schema = parse_url(trim($link));
$host= $schema['host'];
$scheme = "http://";
$gach = explode("/", $link);
list($path1, $path) = explode($gach[2], $link);
if(isset($schema['port'])) $port = $schema['port'];
elseif ($schema['scheme'] == 'https') {
$scheme = "ssl://";
$port = 443;
}
if ($scheme != "ssl://") {
$scheme = "";
}
$hosts = $scheme . $host . ':' . $port;
$fp = #stream_socket_client ($hosts, $errno, $errstr, 120, STREAM_CLIENT_CONNECT );
if (!$fp) {
sleep(15);
header("HTTP/1.1 404 Not Found");
die ("FP Error");
}
$data = "GET {$path} HTTP/1.1\r\n";
$data .= "User-Agent: "."SiiWulyo/0.1"."\r\n";
$data .= "Host: {$host}\r\n";
$data .= "Accept: */*\r\n";
$data .= $cookie ? "Cookie: ".$cookie."\r\n" : '';
if ($user && $pass)
{
$data .= "Authorization: Basic " . base64_encode("{$user}:{$pass}") . "\r\n";
}
if (!empty($range)) $data .= "Range: bytes={$range}\r\n";
$data .= "Connection: Close\r\n\r\n";
#stream_set_timeout($fp, 2);
fputs($fp, $data);
fflush($fp);
$header = '';
do {
$header .= stream_get_line($fp, 512);
}
while (strpos($header, "\r\n\r\n" ) === false);
// Must be fresh start
if( headers_sent() )
die('Headers Sent');
// Required for some browsers
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header("Content-Transfer-Encoding: binary");
header("Accept-Ranges: bytes");
if(stristr($header,"TTP/1.0 200 OK") || stristr($header,"TTP/1.1 200 OK")) {
$filesize = trim (cut_str ($header, "Content-Length:", "\n" ));
if(stristr($header,"filename")) {
$filename = trim (cut_str ( $header, "filename", "\n" ) );
$filename = preg_replace("/(\"\;\?\=|\"|=|\*|UTF-8|\')/","",$filename);
}
//die($filesize);
header("HTTP/1.1 200 OK");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=".$filename);
header("Content-Length: {$filesize}");
}
elseif(stristr($header,"TTP/1.1 206") || stristr($header,"TTP/1.0 206")) {
sleep(1);
$new_length = trim (cut_str ($header, "Content-Length:", "\n" ));
$new_range = trim (cut_str ($header, "Content-Range:", "\n" ));
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: $new_range");
}
elseif(stristr($header,"TTP/1.1 302 Moved")){
return _downloadIt(trim(cut_str ( $header, "Location:", "\n" ) ),$size, $filename, $user, $pass,$cookie);
//kembali lagi gan
}
else {
sleep(10);
header("HTTP/1.1 404 Not Found header");
die ($header);
}
$tmp = explode("\r\n\r\n", $header);
if ($tmp[1]) {
print $tmp[1];
}
while (!feof($fp) && (connection_status()==0)) {
$recv = #stream_get_line($fp, 512);
#print $recv;
#flush();
#ob_flush();
}
fclose($fp);
exit;
}
That's the code, it work perfectly for remote direct link. What I want to know is: How can I make that code count the bytes or bandwidth already download to client?
I mean like this, a file downloaded by several client/user. ex. 10 client. The filesize is 50mb. And only 4 client/user download completed 100% and another just 50% or 40%. That's it.
I want to know how to count that how many bytes transferred to the client? Just like counter how many times downloaded. But the problem now is how many bytes / bw already used for that files. My final purpose is making limit of how many bandwidth can used. For example at 1000MB, if it reach it. Downloads can't be done anymore than.

Related

How create and open a zip file which is building straight away?

I need to be able to open the zip file straight away when we hit the page for download even if the zip file is not created in the server yet.
Is there any way to do this? Because for the moment it takes a lot of time to get the page the start of the download of the zip file.
I'm also getting timeout issue because it takes too much time to build the zip.
$this->loadModel('JobFiles');
$this->loadComponent('Images');
$job_nbr = '40819-o';
$purpose = 'client';
if (isset($this->request->data['type']) && $this->request->data['type'] != '') {
$type = $this->request->data['type'];
$my_files = $this->JobFiles
->find()
->where([
'JobFiles.job_number' => $job_nbr,
'JobFiles.type' => $type,
'JobFiles.purpose' => $purpose
]);
} else {
$my_files = $this->JobFiles
->find()
->where([
'JobFiles.job_number' => $job_nbr,
'JobFiles.purpose' => $purpose
]);
}
$files = array();
$key = 0;
foreach( $my_files as $file ){
// If photo and extension are jpg we provide other files type
if ($file->type == 'photos' && $file->extension == 'jpg' || $file->extension == 'JPG'):
$c = $file->ObjectURL;
$file_headers = #get_headers($c);
if(!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}
else {
$files['photos'][$key]['original_file'] = $file->ObjectURL;
$files['photos'][$key]['name'] = $file->filename;
$files['photos'][$key]['type'] = $file->type;
$files['photos'][$key]['id'] = $file->id;
$key++;
}
endif;
if ($file->type == 'floorplan'):
$files['floorplan'][$key]['original_file'] = $file->ObjectURL;
$key++;
endif;
if ($file->type == 'video'):
$files['video'][$key]['original_file'] = $file->ObjectURL;
$key++;
endif;
}
$zipname = "watherver.zip";
$zip = new ZipArchive();
$zip_full_path_name = \Cake\Core\Configure::read('pathTo') . '/webroot/img/tmp/zip/' . $zipname;
$zip->open($zip_full_path_name, ZIPARCHIVE::CREATE);
foreach ($files['photos'] as $file) {
$context = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
$parsed_file = $file['original_file'];
$download_file = file_get_contents($parsed_file, false,$context);
$zip->addFromString('photos/original/' . basename($parsed_file), $download_file);
}
$zip->close();
//Set headers
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-type: application/octet-stream");
header("Content-Disposition: attachment; filename='" . $zipName . "'");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($zipName));
Cheers,

Read MP4 files from a URL using PHP

I am using the below code snippet to read mp4 files using PHP and play it in the video tag. This code works when I call the video as file(test.mp4) in the localhost allowing to move the seeker back and forth. But when I use Video Source as URL(http://techslides.com/demos/sample-videos/small.mp4) the video is playing but cannot move the seeker back and front.
$filename = 'http://techslides.com/demos/sample-videos/small.mp4';
$mimeType = 'video/mp4';
$ch = curl_init($filename);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE);
$data = curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
// echo $size = filesize($filename);die;
$time = date('r', filemtime($filename));
$fm = #fopen($filename, 'rb');
if (!$fm)
{
header ("HTTP/1.1 505 Internal server error");
return;
}
$begin = 0;
$end = $size - 1;
if (isset($_SERVER['HTTP_RANGE']))
{
if (preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches))
{
$begin = intval($matches[1]);
if (!empty($matches[2]))
{
$end = intval($matches[2]);
}
}
}
if (isset($_SERVER['HTTP_RANGE']))
{
header('GET HTTP/1.1 206 Partial Content');
}
else
{
header('HTTP/1.1 200 OK');
}
header("Content-Type: video/mp4");
header('Accept-Ranges: bytes');
header("Content-Disposition: inline;");
header("Content-Range: bytes $begin-$end/$size");
header("Content-Transfer-Encoding: binary\n");
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Content-Length:' . (($end - $begin) + 1));
if (isset($_SERVER['HTTP_RANGE']))
{
header("Content-Range: bytes $begin-$end/$size");
}
header('Connection: close');
$cur = $begin;
fseek($fm, $begin, 0);
while(!feof($fm) && $cur <= $end && (connection_status() == 0))
{
print fread($fm, min(1024 * 16, ($end - $cur) + 1));
$cur += 1024 * 16;
usleep(1000);
}
i have tried do that before ,
it's not working because fseek() do not support http,
the file must be 'seekable' that mean you must get file from path
check this answer https://stackoverflow.com/a/21722576/5380308

Large files failing to download using readfile()

I have the following code to force download an IPA file (after codesigning it with a script). It works fine with smaller files but with larger files, my web server starts returning a 500 Internal Server Error. Would someone be able to help me tweak my existing code to overcome this issue?
$time = md5(time());
// Runs code signing script here
// And then attempts to initiate download
$path = "done/$time/";
$latest_ctime = 0;
$latest_filename = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_filename = $entry;
}
}
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$time.ipa");
header("Content-Type: application/ipa");
header("Content-Transfer-Encoding: binary");
// Read the file from disk
readfile("done/$time/".$latest_filename);
// header('location: dashboard.php');
} else {
// Throwback
die("Failed. Contact support. // <p>$sign</p>");
}
Here is an example:
$filepath = "done/{$time}/{$latest_filename}";
$size = filesize($filepath);
$mimetype = 'application/ipa';
// Turn off buffering
if (ob_get_level()) {
ob_end_clean();
}
$handle = fopen($filepath, 'rb');
if ($handle !== false && $size > 0) {
#flock($handle, LOCK_SH);
$filename = rawurldecode($filepath);
$old_max_execution_time = ini_get('max_execution_time');
$old_cache_limiter = session_cache_limiter();
ini_set('max_execution_time', 0);
session_cache_limiter(false);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header('Content-Type: ' . $mimetype);
header('Content-Transfer-Encoding: binary');
header('Content-disposition: attachment; filename="'. $filename .'"');
// or your variant
// header("Content-Disposition: attachment; filename=" . md5(time()));
header("Content-Length: $size");
$start = 0;
$end = $size - 1;
$chunk = 8 * 1024;
$requested = (float)$end - (float)$start + 1;
while (! $error) {
if ($chunk >= $requested) {
$chunk = (integer)$requested;
}
set_time_limit(0);
while (! feof($handle) && (connection_status() === 0)) {
if (! $buffer = #fread($handle, $chunk)) {
$error = true;
break 2;
}
print($buffer);
flush();
}
#flock($handle, LOCK_UN);
#fclose($handle);
ini_set('max_execution_time', $old_max_execution_time);
session_cache_limiter($old_cache_limiter);
break;
}
if ($error) {
// 500 - Internal server error
exit;
}
} else {
// Can't open file
exit;
}
Maybe problem in script time execution.
Try to set ini_set('max_execution_time', 0);
Also try to read and send file by chunks.

How to download large file from a link by php?

I am trying to download a large file from an external link using php, I don't have a big idea about this subject, I tried to use the code below, but it always giving me file does not exist!.
I changed the if(file_exists($filePath)) to if(true), but I end with a downloaded file of 0 byte size, where is the error in my code?
$filePath = "http://down.egyu.net/Movies/The.Gambler.2014.720p.BluRay.x264.EGFire.CoM.mp4"; // set your download file path here.
download($filePath); // calls download function
function download($filePath)
{
if(!empty($filePath))
{
$fileInfo = pathinfo($filePath);
$fileName = $fileInfo['basename'];
$fileExtnesion = $fileInfo['extension'];
$default_contentType = "application/octet-stream";
$content_types_list = mimeTypes();
// to find and use specific content type, check out this IANA page : http://www.iana.org/assignments/media-types/media-types.xhtml
if (array_key_exists($fileExtnesion, $content_types_list))
{
$contentType = $content_types_list[$fileExtnesion];
}
else
{
$contentType = $default_contentType;
}
if(file_exists($filePath))
{
$size = filesize($filePath);
$offset = 0;
$length = $size;
//HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
if(isset($_SERVER['HTTP_RANGE']))
{
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = intval($matches[2]) - $offset;
$fhandle = fopen($filePath, 'r');
fseek($fhandle, $offset); // seek to the requested offset, this is 0 if it's not a partial content request
$data = fread($fhandle, $length);
fclose($fhandle);
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
}//HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
//USUAL HEADERS FOR DOWNLOAD
header("Content-Disposition: attachment;filename=".$fileName);
header('Content-Type: '.$contentType);
header("Accept-Ranges: bytes");
header("Pragma: public");
header("Expires: -1");
header("Cache-Control: no-cache");
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
header("Content-Length: ".filesize($filePath));
$chunksize = 8 * (1024 * 1024); //8MB (highest possible fread length)
if ($size > $chunksize)
{
$handle = fopen($_FILES["file"]["tmp_name"], 'rb');
$buffer = '';
while (!feof($handle) && (connection_status() === CONNECTION_NORMAL))
{
$buffer = fread($handle, $chunksize);
print $buffer;
ob_flush();
flush();
}
if(connection_status() !== CONNECTION_NORMAL)
{
echo "Connection aborted";
}
fclose($handle);
}
else
{
ob_clean();
flush();
readfile($filePath);
}
}
else
{
echo 'File does not exist!';
}
}
else
{
echo 'There is no file to download!';
}
}
I found the answer myself, I used a function to get the status of url if it exist and to get the file size:
/* You may need these ini settings too */
set_time_limit(0);
ini_set('memory_limit', '512M');
//THE DOWNLOAD SCRIPT
$filePath = "http://down.egyu.net/Movies/The.Gambler.2014.720p.BluRay.x264.EGFire.CoM.mp4"; // set your download file path here.
download($filePath); // calls download function
function download($filePath)
{
if(!empty($filePath))
{
$fileInfo = pathinfo($filePath);
$fileName = $fileInfo['basename'];
$fileExtnesion = $fileInfo['extension'];
$default_contentType = "application/octet-stream";
$content_types_list = mimeTypes();
// to find and use specific content type, check out this IANA page : http://www.iana.org/assignments/media-types/media-types.xhtml
if (array_key_exists($fileExtnesion, $content_types_list))
{
$contentType = $content_types_list[$fileExtnesion];
}
else
{
$contentType = $default_contentType;
}
$exist = is_url_exist($fileInfo['dirname']."/".$fileInfo['basename']);
if($exist['response'])
{
$size = $exist['size'];
$offset = 0;
$length = $size;
//HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
if(isset($_SERVER['HTTP_RANGE']))
{
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = intval($matches[2]) - $offset;
$fhandle = fopen($filePath, 'r');
fseek($fhandle, $offset); // seek to the requested offset, this is 0 if it's not a partial content request
$data = fread($fhandle, $length);
fclose($fhandle);
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
}//HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
//USUAL HEADERS FOR DOWNLOAD
header("Content-Disposition: attachment;filename=".$fileName);
header('Content-Type: '.$contentType);
header("Accept-Ranges: bytes");
header("Pragma: public");
header("Expires: -1");
header("Cache-Control: no-cache");
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
header("Content-Length: ".$size);
$chunksize = 8 * (1024 * 1024); //8MB (highest possible fread length)
if ($size > $chunksize)
{
$handle = fopen($_FILES["file"]["tmp_name"], 'rb');
$buffer = '';
while (!feof($handle) && (connection_status() === CONNECTION_NORMAL))
{
$buffer = fread($handle, $chunksize);
print $buffer;
ob_flush();
flush();
}
if(connection_status() !== CONNECTION_NORMAL)
{
echo "Connection aborted";
}
fclose($handle);
}
else
{
ob_clean();
flush();
readfile($filePath);
}
}
else
{
echo 'File does not exist!';
}
}
else
{
echo 'There is no file to download!';
}
}
function is_url_exist($url){
$array = array();
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
if($code == 200){
$array['response'] = true;
}else{
$array['response'] = false;
}
$array['size'] = $size;
curl_close($ch);
return $array;
}

PHP - File Streaming problem

I have a website that has a downloads section. I need for the files not to be accessed directly by an annonymous user, so I am putting them in a directory not accessable to users, but is accessible to the web server. When the user clicks the link to download the file, I need it to redirect to a download page that will stream the file to the user without him knowing the location of the directory or the file and it will ask him to save it to his computer. I found the following code on a previous post, but I can't get it to work correctly. Could be that I don't know the correct names of the variables that it wants to be passed to it. Please include an explanation of how to use your code.
$filename='Firefox%20Setup%203.6.13.exe';
$file_path='http://ftp.byfly.by/pub/mozilla.org/firefox/releases/3.6.13/win32/fr';
$file= $file_path."/".$filename;
$len=filesize($file);
header("content-type: application/save");
header("content-length: $len");
header("content-disposition: attachment; filename=$filename");
$fp=fopen($file, "r");
fpassthru($fp);
This is how I would do it.
<?php
function getFile($file_location) {
header('Content-Description: File Transfer');
header('Content-type: application/exe');
header('Content-Disposition: attachment; filename="supercoolFF.exe"');
header('Content-Transfer-Encoding: binary');
ob_end_clean();
$url_info = parse_url($file_location);
if (!isset($url_info['query'])) $url_info['query'] = '';
$http = fsockopen($url_info['host'],$url_info['port']);
$req = "GET " . $url_info['path'] . "?" . $url_info['query'] . " HTTP/1.1\r\n";
$req .= "Host: " . $url_info['host'] . ":" . $url_info['port'] . "\r\n";
$req .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$req .= "User-Agent Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8\r\n";
$req .= "Accept-Language: en-us,en;q=0.5\r\n";
$req .= "Accept-Encoding: gzip,deflate\r\n";
$req .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
if ($len = strlen($url_info['query']) {
$req .= 'Content-Length: ' . $len . "\r\n";
$req .= "Connection: Close\r\n\r\n";
$req .= $query . "\r\n\r\n";
} else {
$req .= "Connection: Keep-Alive\r\n\r\n";
}
fputs($http, $req);
$content = "";
$content_encountered = FALSE;
ob_end_clean();
while(strlen($part = fgets($http, 4096))) {
if ($content_encountered) {
echo $part;
$content .= $part;
}
if ($part == "\r\n") {
$content_encountered = TRUE;
}
}
fclose($http);
exit;
}
$filename='Firefox%20Setup%203.6.13.exe?';
$file_path='http://ftp.byfly.by:80/pub/mozilla.org/firefox/releases/3.6.13/win32/fr';
getFile($file_path . '/' . $filename);
Of course, it would be better to do a HEAD request first to get the filesize and include a Content-Length header in the response so the user can have some idea about how long it is going to take. Or, you can hardcode that number, if you are always going to be serving up the same file.
Let's say you have a file in a directory called "hiddenaccess" and the file name is "test.mp3" you can load the path in php variable and let it for download
<?php
$file = "./hiddenaccess/test.mp3";
header("Content-Disposition: attachment; filename=" . urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file));
#readfile($file);
?>
Note: Do NOT have any other echo or print statements in this file.
Here's a function I (Apparently Others?!!?) developed to do just that, it's a meaty function but it checks and does everything. To call it is simple though, the important part. I have this inside a class but you can just make it a php function as there is no other class functions it depends on. Hope this helps you.
public static function output_file($path, $filename, $mime_type='') {
$err = 'Sorry, the file you are requesting is unavailable.';
$filename = rawurldecode($filename);
// check that file exists and is readable
if (file_exists($path) && is_readable($path)) {
/* Figure out the MIME type (if not specified) */
$known_mime_types=array(
"pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg"=> "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
if($mime_type==''){
$file_extension = strtolower(substr(strrchr($filename,"."),1));
if(array_key_exists($file_extension, $known_mime_types)){
$mime_type=$known_mime_types[$file_extension];
} else {
$mime_type="application/force-download";
};
};
#ob_end_clean(); //turn off output buffering to decrease cpu usage
if(ini_get('zlib.output_compression')) { //otherwise the filesize is way off
ini_set('zlib.output_compression', 'Off');
}
// get the file size and send the http headers
$size = filesize($path);
header("Content-Type: $mime_type");
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE'])) {
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2);
list($range) = explode(",", $range, 2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) {
$range_end = $size-1;
} else {
$range_end = intval($range_end);
}
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length = $size;
header("Content-Length: " . $size);
}
/* output the file itself */
$chunksize = 1*(1024*1024); //may want to change this
$bytes_send = 0;
if ($file = fopen($path, 'r')) {
if(isset($_SERVER['HTTP_RANGE'])) {
fseek($file, $range);
}
while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length)) {
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else {
die($err);
}
} else {
die($err);
}
die();
}
To use it would be something like this.
$path = '/var/www/site/httpdocs/upload/private/myfile.txt';
$dl_filename = 'NDA_'.time();
$mime_type = 'doc';
output_file($path,$dl_filename,$mime_type);

Categories