idm中的区别在php Force中添加URL和浏览器下载

时间:2016-02-28 22:07:19

标签: php apache force-download

我写了一个php下载中心脚本,对每个用户组进行一些速度限制!

对于vip组我使用了xsendfile并且它工作得很好

但是在必须有速度限制的用户组中我使用了fread()并强制下载php:

<?php

类httpdownload {

public $data = null;
public $data_len = 0;
public $data_mod = 0;
public $data_type = 0;
public $data_section = 0; //section download
/**
 * @var ObjectHandler
 **/
public $handler = array('auth' => null);
public $use_resume = true;
public $use_autoexit = false;
public $use_auth = false;
public $filename = null;
public $mime = null;
public $bufsize = 2048;
public $seek_start = 0;
public $seek_end = -1;
public $newfile = null;

/**
 * Total bandwidth has been used for this download
 * @var int
 */
public $bandwidth = 0;
/**
 * Speed limit
 * @var float
 */
public $speed = 0;

/*-------------------
| Download Function |
-------------------*/
/**
 * Check authentication and get seek position
 * @return bool
 **/
private 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
 **/
private function header($size,$seek_start=null,$seek_end=null) {
    header('Content-type: ' . $this->mime);
    header('Content-Disposition: attachment; filename="' . $this->newfile . '"');
    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");
    }
}

private 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 ($seek) fseek($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 > 0 && ($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 , 0 , $bufsize);
            $this->data = substr($this->data , $bufsize);

            $size -= $bufsize;
            flush();

            if ($speed > 0 && ($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
}

}

&GT;

下载动作:

private function downloader($filename,$type,$name,$speed_limit)
{
    require_once(ROOT_PATCH . "bcore/HttpDownloader.class.php");
    $object = new httpdownload();
    $object->newfile = $name;

    switch ($type) {
        case 'resume_speed':
        case 'noresume_speed':
        case 'resume':
        case 'noresume':
            $object->set_byfile($filename);
            if ($type == 'noresume' || $type == 'noresume_speed') $object->use_resume = false;
            if ($type == 'resume_speed' || $type == 'noresume_speed' ) $object->speed = $speed_limit;
            $object->download();
            break;
        case 'data':
        case 'dataresume':
            $data = implode('' , file($filename));
            $object->set_bydata($data);
            if ($_SERVER['download'] != 'dataresume') $object->use_resume = false;
            $object->filename = basename($filename);
            $object->download(); 
            break;
        case 'auth':
            $object->set_byfile($filename);
            $object->use_auth = true;
            $object->handler['auth'] = "test_auth";
            $object->download();
            break;
        case 'url':
            $object->set_byurl('http://www.php.net/get/php_manual_chm.zip/from/cr.php.net/mirror');
            $object->download();
            break;
    }

}

$ type =“resume”;在上面的开关

但是有问题!

注意:我的最高互联网下载速度为60kb / s

当我将下载URL复制到IDM时添加Url文件下载速度非常快且很好:

screen shot for copy download url to IDM Add

但是当我点击url和idm从浏览器文件中自动获取链接下载时连接速度非常慢!!

并且在一些第二速度之后是0kb / s~4kb / s

这有什么问题?

idm get link automatically from browser

0 个答案:

没有答案