想做一个认证后下载的模块,支持断点续传功能,写好后发现在老的虚拟主机Apache+php4 跑没有问题,用迅雷下可以多线程+断点续传!可是放到IIS+php5就出错了,用IE直接下载没问题,用迅雷或者其他下载工具就不行了,不支持多线程,而且下几秒钟就失败了。求高手帮助!下面是测试代码:
<?php
$fname = 'PDF.rar';  
$fp = fopen($fname,'rb');  
$fsize = filesize($fname);  
if (isset($_SERVER['HTTP_RANGE'])) {
    list($start) = explode('-',(str_replace('bytes=', '', $_SERVER['HTTP_RANGE'])));
} else {
    $start = 0; 

header('Cache-control: public');
header("Content-Type: application/octet-stream");  
header("Content-Disposition: attachment; filename=PDF.rar");  
if ($start> 0) {  
    fseek($fp, $start);  
    header("HTTP/1.1 206 Partial Content");  
    header('Accept-Ranges: bytes');
    header("Content-Length: " . ($fsize - $start));  
    header("Content-Range: bytes " . $start . "-" . ($fsize - 1) . "/" . $fsize);  
} else {  
    header("Content-Length: $fsize");  
    header("Accept-Ranges: bytes");  
}  
fpassthru($fp);
?>
在测试的时候 我加入了一段记录请求 $_SERVER['HTTP_RANGE'] 和返回header Content-Range: bytes 的值,
发现如果Content-Range: bytes 不是以0开头的话,下载工具就会出错,但是一模一样的代码放到Apache+php4一点问题都没有! 郁闷死我了!

解决方案 »

  1.   

    呃..着急改东西没顾上贴..测试后发现是 PHP 运行在fastcgi模式下 发送header的问题在Apache下发header("HTTP/1.1 206 Partial Content");  没有问题
    IIS+fastcgi下改成 header("Status: 206 Partial Content");  就没问题了可能是我的php设置cgi.rfc2616_headers为0最好吧ETag和Last-Modified也发送最后代码在几个支持断点续传的下载工具都测试没有问题。
    <?php
    $fname = ‘PDF.rar';  
    $fp = fopen($fname,'rb');  
    $fsize = filesize($fname);  
    if (isset($_SERVER['HTTP_RANGE'])) {
        list($start) = explode('-',(str_replace('bytes=', '', $_SERVER['HTTP_RANGE'])));
    } else {
        $start = 0; 

    header("Content-Type: application/x-msdownload");  //这里用application/octet-stream在某些情况下续传会出错,没找到原因。
    header("Content-Disposition: attachment; filename=PDF.rar");  
    header("ETag: ".md5(filemtime($fname))); 
    header("Last-Modified: ".gmdate("D, d M Y H:i:s", filemtime($fname))." GMT"); 
    header('Content-transfer-encoding: binary');
    if ($start> 0) {  
        fseek($fp, $start);  
        header("HTTP/1.1 206 Partial Content");  
        header("Status: 206 Partial Content");
        header('Accept-Ranges: bytes');
        header("Content-Length: " . ($fsize - $start));  
        header("Content-Range: bytes " . $start . "-" . ($fsize - 1) . "/" . $fsize);  
    } else {  
        header("Content-Length: $fsize");  
        header("Accept-Ranges: bytes");  
    }  
    fpassthru($fp);
    ?>
      

  2.   

    本帖最后由 xuzuning 于 2011-06-10 14:11:17 编辑