Jump to content

Download with speed limit and resume


killuagdt

Recommended Posts

I am currently using PHP 5.3.2 on IIS 7 and I am wondering how can I write a download script with resume and speed limit. After looking for a while, I found this script that works on speed limit:

<?php
$local_file = 'file.zip';
$download_file = 'name.zip';

// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file))
{
    header('Cache-control: private');
    header('Content-Type: application/octet-stream');
    header('Content-Length: '.filesize($local_file));
    header('Content-Disposition: filename='.$download_file);

    flush();
    $file = fopen($local_file, "r");
    while(!feof($file))
    {
        // send the current file part to the browser
        print fread($file, round($download_rate * 1024));
        // flush the content to the browser
        flush();
        // sleep one second
        sleep(1);
    }
    fclose($file);}
else {
    die('Error: The file '.$local_file.' does not exist!');
}

?>

 

Though there is a big problem that the download file comes without extension. For example if the original file is file.ext then the client will receive it as file without any extension. I just want to use octet-stream since I have no interest in streaming or other things, but I really want the client to have the extension also.

 

So could you please tell me what is wrong with the above script, and please show me a way to do resume download. Thank you very much for your help.

Link to comment
https://forums.phpfreaks.com/topic/209529-download-with-speed-limit-and-resume/
Share on other sites

Found a shortlist on useful headers:

http://www.jonasjohn.de/snippets/php/headers.htm

 

Notice the quotations around the filename in the header.

 

Also, check this out for an example of what you want:

http://www.awesomephp.com/?Tutorials*16/Download-file-with-resume,-stream-and-speed-options.html

 

Take note of this part:

    if(isset($_SERVER['HTTP_RANGE'])) {
        list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
        str_replace($range, "-", $range);
        $size2=$size-1;
        $new_length=$size-$range;
        header("HTTP/1.1 206 Partial Content");
        header("Content-Length: $new_length");
        header("Content-Range: bytes $range$size2/$size");
    } else {
        $size2=$size-1;
        header("Content-Range: bytes 0-$size2/$size");
        header("Content-Length: ".$size);
    } 

 

Google is handy :P

 

-cb-

Thank you for your reply. I did get around the extension problem but the script at awesomephp doesn't work to me :D. I did find it before but I could not implement it :D. I did a little tweak to get this code:

<?php
    $maxspeed=100;
    $filename=$_GET['file'];
    $filelocation=$_GET['filelocation'];
    if (connection_status()!=0) return(false);
    $extension = strtolower(end(explode('.',$fileName)));    
    //echo filesize($filelocation);
    $contentType = 'application/octet-stream';
    header("Cache-Control: public");
    header("Content-Transfer-Encoding: binary\n");
    header('Content-Type: $contentType');
    $contentDisposition = 'attachment'; 
    if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
        $fileName= preg_replace('/\./', '%2e', $fileName,
substr_count($fileName, '.') - 1);
        header("Content-Disposition: $contentDisposition;
filename=\"$fileName\"");
    } else {
        header("Content-Disposition: $contentDisposition;
filename=\"$fileName\"");
    }
    
    header("Accept-Ranges: bytes");   
    $range = 0;
    $size = filesize($fileLocation);
    if(isset($_SERVER['HTTP_RANGE'])) {
        list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
        str_replace($range, "-", $range);
        $size2=$size-1;
        $new_length=$size-$range;
        header("HTTP/1.1 206 Partial Content");
        header("Content-Length: $new_length");
        header("Content-Range: bytes $range$size2/$size");
    } else {
        $size2=$size-1;
        header("Content-Range: bytes 0-$size2/$size");
        header("Content-Length: ".$size);
    }
     //echo $size;
    if ($size == 0 ) { die('Zero byte file! Aborting download');}
    set_magic_quotes_runtime(0); 
    $fp=fopen("$fileLocation","rb");
    
    fseek($fp,$range);
  
    while(!feof($fp) and (connection_status()==0))
    {
        set_time_limit(0);
        print(fread($fp,1024*$maxSpeed));
        flush();
        ob_flush();
        sleep(1);
    }
    fclose($fp);
         
?>

 

Zero byte file! Aborting download.

 

when I place an echo, it get the $size correctly at the first echo but the second echo has nothing generated :D. Could you please help me with this? :D. Thank you very much:D

I got the download window to pop up with this code

<?php
    $maxspeed=100;
chdir('leakchannel.com/download');
    $filename=$_GET['file'];
    $filelocation=$_GET['file'];
echo filesize($filelocation);
    if (connection_status()!=0) return(false);
    $extension = strtolower(end(explode('.',$filename)));    
    $contentType = 'application/octet-stream';
    header("Cache-Control: public");
    header("Content-Transfer-Encoding: binary\n");
    header('Content-Type: $contentType');
    $contentDisposition = 'attachment'; 
    if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
        $fileName= preg_replace('/\./', '%2e', $filename,
substr_count($filename, '.') - 1);
        header("Content-Disposition: $contentDisposition;filename=\"$fileName\"");
    } else {
        header("Content-Disposition: $contentDisposition;filename=\"$filename\"");
    }    
    header("Accept-Ranges: bytes");   
    $range = 0;
    $size = filesize($fileLocation);
echo $size;
    //echo $size
    if(isset($_SERVER['HTTP_RANGE'])) {
        list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
        str_replace($range, "-", $range);
        $size2=$size-1;
        $new_length=$size-$range;
        header("HTTP/1.1 206 Partial Content");
        header("Content-Length: $new_length");
        header("Content-Range: bytes $range$size2/$size");
    } else {
        $size2=$size-1;
        header("Content-Range: bytes 0-$size2/$size");
        header("Content-Length: ".$size);
    }
     //echo $size;
    if ($size == 0 ) { die('Zero byte file! Aborting download');}
    set_magic_quotes_runtime(0); 
    $fp=fopen("$fileLocation","rb");    
    fseek($fp,$range);  
    while(!feof($fp) and (connection_status()==0))
    {
        set_time_limit(0);
        print(fread($fp,1024*$maxSpeed));
        flush();
        ob_flush();
        sleep(1);
    }
    fclose($fp);
         
?>

but it only transfers 20.1Kb and nothing else. So could you please show me what is wrong with this and how to fix it? Thank you very much.

http://www.phpclasses.org/package/2221-PHP-Server-files-for-downloading-with-resume-support.html

You'll want to download both the class file and the test file.

 

The test file shows how to use the class:

include_once "class.httpdownload.php";
$object->set_byfile($FILENAME); // Tell the Object where the file is.
$object->use_resume = true; // Resume Ability
$object->speed = 100; // KB/s
$object->download(); // Start the download

 

This class works perfectly.

(You may need to change the PHP opening tags from <? to <?php)

 

You can also use an authentication system, but to test or use it you will need to edit line 313 to:

return $this->handler['auth']($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);

 

For some reason the author used an incorrect number of parameters with his function he used in test.php, the first argument isn't needed since we know it's an auth.

 

-cb-

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.