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
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-

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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-

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.