我真的很困惑。我做了一个函数如下(一个wp插件)。它处理下载请求。
下载网址格式如下:
http://mysite.com/?download=2f547re8w9qasd547g8tr52e15469879w
文件将像往常一样保存(在弹出的“另存为...”框中)在浏览器中。
问题在于:
1 - 像Orbit
这样的下载管理器试图下载页面!并IDM
只下载整个文件大小的低百分比(例如7%)然后停止&通过恢复,它从第一次开始下载。 (浏览器完全下载文件并恢复没有问题)
2 - 当下载.zip文件(通过浏览器)时,出现“意外的归档结束”错误。 ( CRC32的zip文件详细信息显示0个字符)
function save_file()
{
global $wpdb;
global $uid;
global $each_download;
$hash = @$_GET["download"];
if(preg_match('/^[a-z0-9]{32}$/i',$hash))
{
if($row = $wpdb->get_row("SELECT * FROM wp_dlurl WHERE hash = '{$hash}'",ARRAY_A))
{
if(is_user_logged_in())
{
if($row['price'] != 0)
$each_download = $row['price'];
if(get_user_meta($uid, 'revo_credits', true) >= $each_download)
{
$parts = pathinfo($row['url']);
$url = $parts['dirname'] . '/' . urlencode($parts['basename']);
$file = pathinfo($row['filename']);
$ext = $file['extension'];
/* List of File Types */
$fileTypes['swf'] = 'application/x-shockwave-flash';
$fileTypes['pdf'] = 'application/pdf';
$fileTypes['exe'] = 'application/octet-stream';
$fileTypes['zip'] = 'application/zip';
$fileTypes['doc'] = 'application/msword';
$fileTypes['xls'] = 'application/vnd.ms-excel';
$fileTypes['ppt'] = 'application/vnd.ms-powerpoint';
$fileTypes['gif'] = 'image/gif';
$fileTypes['png'] = 'image/png';
$fileTypes['jpeg'] = 'image/jpg';
$fileTypes['jpg'] = 'image/jpg';
$fileTypes['rar'] = 'application/rar';
$fileTypes['ra'] = 'audio/x-pn-realaudio';
$fileTypes['ram'] = 'audio/x-pn-realaudio';
$fileTypes['ogg'] = 'audio/x-pn-realaudio';
$fileTypes['wav'] = 'video/x-msvideo';
$fileTypes['wmv'] = 'video/x-msvideo';
$fileTypes['avi'] = 'video/x-msvideo';
$fileTypes['asf'] = 'video/x-msvideo';
$fileTypes['divx'] = 'video/x-msvideo';
$fileTypes['mp3'] = 'audio/mpeg';
$fileTypes['mp4'] = 'audio/mpeg';
$fileTypes['mpeg'] = 'video/mpeg';
$fileTypes['mpg'] = 'video/mpeg';
$fileTypes['mpe'] = 'video/mpeg';
$fileTypes['mov'] = 'video/quicktime';
$fileTypes['swf'] = 'video/quicktime';
$fileTypes['3gp'] = 'video/quicktime';
$fileTypes['m4a'] = 'video/quicktime';
$fileTypes['aac'] = 'video/quicktime';
$fileTypes['m3u'] = 'video/quicktime';
$contentType = $fileTypes[$ext];
//ob_end_clean();
header("Cache-Control: public");
header('Content-Type: $contentType');
header("Content-Transfer-Encoding: binary");
$new_name = $row['filename'];//rand(1000,999999).".".$ext;
$contentDisposition = 'attachment';
if(strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
$new_name = preg_replace('/\./', '%2e', $new_name, substr_count($new_name,'.') - 1);
}
$new_name = urlencode($new_name);
header("Content-Disposition: $contentDisposition; filename=\"$new_name\"");
header("Accept-Ranges: bytes");
$range = 0;
$size = $row['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
{
update_user_meta($uid, 'revo_credits', get_user_meta($uid, 'revo_credits', true)-$each_download);
$size2 = $size-1;
header("Content-Range: bytes 0-$size2/$size");
header("Content-Length: ".$size);
}
if ($size == 0)
{
showMessage('aborted. zero file size');
}
set_magic_quotes_runtime(0);
$maxSpeed = 200;
$fp = fopen($url,"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);
return((connection_status()==0) and !connection_aborted());
}
else
showMessage("not enough credit.");
}
else
showMessage("login to download.");
}
else
{
wp_redirect(get_bloginfo('url'));
exit;
}
}
else
{
wp_redirect(get_bloginfo('url'));
exit;
}
}
我认为标题是罪魁祸首!
使用Accept-ranges
和Content-length
标头的恢复方法已经完成,并且在浏览器下载文件时有效。
答案 0 :(得分:1)
我不确定其他下载是如何工作的但你的范围实现错误原因是什么?
你这样得到range
$_SERVER['HTTP_RANGE'] = "bytes=1-200"; //sample range
$size = 1000; //sample size
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']);
str_replace($range, "-", $range);
$size2 = $size - 1;
$new_length = $size - $range;
// Used Print Insted of headers
print("HTTP/1.1 206 Partial Content\n");
print("Content-Length: $new_length\n");
print("Content-Range: bytes $range$size2/$size\n");
输出
HTTP/1.1 206 Partial Content
Content-Length: 999
Content-Range: bytes 1-200999/1000 <------ This is an issue
我期待这样的事情
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']);
list($offset, $length) = explode("-", $range);
$length = $length - $offset;
// Used Print Insted of headers
print("HTTP/1.1 206 Partial Content\n");
print("Content-Length: $length\n");
printf('Content-Range: bytes %d-%d/%d', $offset, ($offset + $length), $size)
输出
HTTP/1.1 206 Partial Content
Content-Length: 199
Content-Range: bytes 1-200/1000 <---- Properly Displayed