Login   Register  
PHP Classes
elePHPant
Icontem

File: class.httpdownload.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Bao Nguyen Quoc  >  HTTP Download  >  class.httpdownload.php  >  Download  
File: class.httpdownload.php
Role: Class source
Content type: text/plain
Description: Class
Class: HTTP Download
Server files for downloading with resume support
Author: By
Last change: Fix small problem with seek_start
Date: 8 years ago
Size: 7,905 bytes
 

Contents

Class file image Download
<?

/**
 @author Nguyen Quoc Bao <quocbao.coder@gmail.com>
 @version 1.3
 @desc A simple object for processing download operation , support section downloading
 Please send me an email if you find some bug or it doesn't work with download manager.
 I've tested it with
     - Reget
     - FDM
     - FlashGet
     - GetRight
     - DAP
     
 @copyright It's free as long as you keep this header .
 @example
 
 1: File Download
     $object = new downloader;
     $object->set_byfile($filename); //Download from a file
     $object->use_resume = true; //Enable Resume Mode
     $object->download(); //Download File
     
 2: Data Download
  $object = new downloader;
     $object->set_bydata($data); //Download from php data
     $object->use_resume = true; //Enable Resume Mode
     $object->set_filename($filename); //Set download name
     $object->set_mime($mime); //File MIME (Default: application/otect-stream)
     $object->download(); //Download File
     
     3: Manual Download
     $object = new downloader;
     $object->set_filename($filename);
    $object->download_ex($size);
    //output your data here , remember to use $this->seek_start and $this->seek_end value :)
    
**/

class httpdownload {

    var 
$data null;
    var 
$data_len 0;
    var 
$data_mod 0;
    var 
$data_type 0;
    var 
$data_section 0//section download
    /**
     * @var ObjectHandler
     **/
    
var $handler = array('auth' => null);
    var 
$use_resume true;
    var 
$use_autoexit false;
    var 
$use_auth false;
    var 
$filename null;
    var 
$mime null;
    var 
$bufsize 2048;
    var 
$seek_start 0;
    var 
$seek_end = -1;
    
    
/**
     * Total bandwidth has been used for this download
     * @var int
     */
    
var $bandwidth 0;
    
/**
     * Speed limit
     * @var float
     */
    
var $speed 0;
    
    
/*-------------------
    | Download Function |
    -------------------*/
    /**
     * Check authentication and get seek position
     * @return bool
     **/
    
function initialize() {
        global 
$HTTP_SERVER_VARS;
        
        if (
$this->use_auth//use authentication
        
{
            if (!
$this->_auth()) //no authentication
            
{
                
header('WWW-Authenticate: Basic realm="Please enter your username and password"');
            
header('HTTP/1.0 401 Unauthorized');
            
header('status: 401 Unauthorized');
            if (
$this->use_autoexit) exit();
                return 
false;
            }
        }
        if (
$this->mime == null$this->mime "application/octet-stream"//default mime
        
        
if (isset($_SERVER['HTTP_RANGE']) || isset($HTTP_SERVER_VARS['HTTP_RANGE']))
        {
            
            if (isset(
$HTTP_SERVER_VARS['HTTP_RANGE'])) $seek_range substr($HTTP_SERVER_VARS['HTTP_RANGE'] , strlen('bytes='));
            else 
$seek_range substr($_SERVER['HTTP_RANGE'] , strlen('bytes='));
            
            
$range explode('-',$seek_range);
            
            if (
$range[0] > 0)
            {
                
$this->seek_start intval($range[0]);
            }
            
            if (
$range[1] > 0$this->seek_end intval($range[1]);
            else 
$this->seek_end = -1;
            
            if (!
$this->use_resume)
            {
                
$this->seek_start 0;
                
                
//header("HTTP/1.0 404 Bad Request");
                //header("Status: 400 Bad Request");
                
                //exit;
                
                //return false;
            
}
            else
            {
                
$this->data_section 1;
            }
            
        }
        else
        {
            
$this->seek_start 0;
            
$this->seek_end = -1;
        }
        
        return 
true;
    }
    
/**
     * Send download information header
     **/
    
function header($size,$seek_start=null,$seek_end=null) {
        
header('Content-type: ' $this->mime);
        
header('Content-Disposition: attachment; filename="' $this->filename '"');
        
header('Last-Modified: ' date('D, d M Y H:i:s \G\M\T' $this->data_mod));
        
        if (
$this->data_section && $this->use_resume)
        {
            
header("HTTP/1.0 206 Partial Content");
            
header("Status: 206 Partial Content");
            
header('Accept-Ranges: bytes');
            
header("Content-Range: bytes $seek_start-$seek_end/$size");
            
header("Content-Length: " . ($seek_end $seek_start 1));
        }
        else
        {
            
header("Content-Length: $size");
        }
    }
    
    function 
download_ex($size)
    {
        if (!
$this->initialize()) return false;
        
ignore_user_abort(true);
        
//Use seek end here
        
if ($this->seek_start > ($size 1)) $this->seek_start 0;
        if (
$this->seek_end <= 0$this->seek_end $size 1;
        
$this->header($size,$seek,$this->seek_end);
        
$this->data_mod time();
        return 
true;
    }
    
    
/**
     * Start download
     * @return bool
     **/
    
function download() {
        if (!
$this->initialize()) return false;
        
        
$seek $this->seek_start;
        
$speed $this->speed;
        
$bufsize $this->bufsize;
        
$packet 1;
        
        
//do some clean up
        
@ob_end_clean();
        
$old_status ignore_user_abort(true);
        @
set_time_limit(0);
        
$this->bandwidth 0;
        
        
$size $this->data_len;
        
        if (
$this->data_type == 0//download from a file
        
{
            
            
$size filesize($this->data);
            if (
$seek > ($size 1)) $seek 0;
            if (
$this->filename == null$this->filename basename($this->data);
            
            
$res fopen($this->data,'rb');
            if (
$seekfseek($res $seek);
            if (
$this->seek_end $seek$this->seek_end $size 1;
            
            
$this->header($size,$seek,$this->seek_end); //always use the last seek
            
$size $this->seek_end $seek 1;
            
            while (!(
connection_aborted() || connection_status() == 1) && $size 0)
            {
                if (
$size $bufsize)
                {
                    echo 
fread($res $size);
                    
$this->bandwidth += $size;
                }
                else
                {
                    echo 
fread($res $bufsize);
                    
$this->bandwidth += $bufsize;
                }
                
                
$size -= $bufsize;
                
flush();
                
                if (
$speed && ($this->bandwidth $speed*$packet*1024))
                {
                    
sleep(1);
                    
$packet++;
                }
            }
            
fclose($res);
            
        }
        
        elseif (
$this->data_type == 1//download from a string
        
{
            if (
$seek > ($size 1)) $seek 0;
            if (
$this->seek_end $seek$this->seek_end $this->data_len 1;
            
$this->data substr($this->data $seek $this->seek_end $seek 1);
            if (
$this->filename == null$this->filename time();
            
$size strlen($this->data);
            
$this->header($this->data_len,$seek,$this->seek_end);
            while (!
connection_aborted() && $size 0) {
                if (
$size $bufsize)
                {
                    
$this->bandwidth += $size;
                }
                else
                {
                    
$this->bandwidth += $bufsize;
                }
                
                echo 
substr($this->data $bufsize);
                
$this->data substr($this->data $bufsize);
                
                
$size -= $bufsize;
                
flush();
                
                if (
$speed && ($this->bandwidth $speed*$packet*1024))
                {
                    
sleep(1);
                    
$packet++;
                }
            }
        } else if (
$this->data_type == 2) {
            
//just send a redirect header
            
header('location: ' $this->data);
        }
        
        if (
$this->use_autoexit) exit();
        
        
//restore old status
        
ignore_user_abort($old_status);
        
set_time_limit(ini_get("max_execution_time"));
        
        return 
true;
    }
    
    function 
set_byfile($dir) {
        if (
is_readable($dir) && is_file($dir)) {
            
$this->data_len 0;
            
$this->data $dir;
            
$this->data_type 0;
            
$this->data_mod filemtime($dir);
            return 
true;
        } else return 
false;
    }
    
    function 
set_bydata($data) {
        if (
$data == '') return false;
        
$this->data $data;
        
$this->data_len strlen($data);
        
$this->data_type 1;
        
$this->data_mod time();
        return 
true;
    }
    
    function 
set_byurl($data) {
        
$this->data $data;
        
$this->data_len 0;
        
$this->data_type 2;
        return 
true;
    }
    
    function 
set_lastmodtime($time) {
        
$time intval($time);
        if (
$time <= 0$time time();
        
$this->data_mod $time;
    }
    
    
/**
     * Check authentication
     * @return bool
     **/
    
function _auth() {
        if (!isset(
$_SERVER['PHP_AUTH_USER'])) return false;
        if (isset(
$this->handler['auth']) && function_exists($this->handler['auth']))
        {
            return 
$this->handler['auth']('auth' $_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
        }
        else return 
true//you must use a handler
    
}
    
}

?>