本文介绍了PHP文件服务脚本:不可靠的下载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这篇文章是关于ServerFault的一个问题(),但我确定我们的php脚本是罪魁祸首。所以我在这里发布一个关于我认为是实际问题的更新问题。



我正在使用php脚本来验证权限,然后为用户提供一个文件的我的网站下载。大多数情况下,这是有效的,但最近一个用户已经看到较大的下载的问题。对于大小为100MB的文件,他只下载了大约80%的下载量。此外,此脚本的所有下载都不能报告文件大小。此外,测试表明,如果给定直接链接(在此时报告文件大小),同一用户可以可靠地下载每个失败的文件。



以下是相关的代码段我们用于提供文件的代码:

 标题(Content-type:$ contenttype); 
$ len = filesize($ filename);
header(Content-Length:$ len);
header(Content-Disposition:attachment; filename =。$ title。。$ ext);
readfile($ filename);

请注意,$ contenttype,$ filename,$ title和$ ext都设置正确,才能得到这里。这些已被三重检查。没有一个是问题。此外,$ len确实提供了正确的文件大小。



在研究此问题的同时,我发现了这篇文章:



似乎我遇到同样的问题。当我使用脚本,我得到文件的分块编码,没有为content-length设置大小。我假设在大量下载中出现问题,导致他在文件结束之前获得零长度的块。



以下是直接请求的标题:

  http://www.grinderschool.com/videos/zfff5061b65ae00e8b21/KillsAids021.wmv 

GET /videos/zfff5061b65ae00e8b21/KillsAids021.wmv HTTP / 1.1
主机:www.grinderschool.com
用户代理:Mozilla / 5.0(Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3)Gecko / 20100401 Firefox / 3.6.3(.NET CLR 3.5.30729)
接受: text / html,application / xhtml + xml,application / xml; q = 0.9,* / *; q = 0.8
接受语言:en-us,en; q = 0.5
接受编码: gzip,deflate
Accept-Charset:ISO-8859-1,utf-8; q = 0.7,*; q = 0.7
Keep-Alive:115
连接:keep-alive
Referer:http://www.grinderschool.com/phpBB3/viewtopic.php?f=14&p=29468
Cookie:style_cookie = printonly; phpbb3_7c544_u = 2; phpbb3_7c544_k = 44b832912e5f887d; phpbb3_7c544_sid = e8852df42e08cc1b2250300c2897f78f; __utma = 174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz = 174624884.1264524375.411.12.utmcsr =谷歌| utmccn =(有机)| utmcmd =有机| utmctr =低%20stakes%20poker%20videos; phpbb3_cmviy_k =; phpbb3_cmviy_u = 2; phpbb3_cmviy_sid = d8df5c0943863004ca40ef9c392d371d; __utmb = 174624884.4.10.1270989003; __utmc = 174624884
Pragma:no-cache
缓存控制:无缓存

HTTP / 1.1 200 OK
日期:2010年4月11日12:57 :41 GMT
服务器:Apache / 2.2.14(Unix)mod_ssl / 2.2.14 OpenSSL / 0.9.8l DAV / 2 mod_auth_passthrough / 2.1 FrontPage / 5.0.2.2635
最后修改:Sun,04 Apr 2010 12:51:06 GMT
Etag:eb42d6-7d9b843-48368aa6dc280
接受范围:字节
内容长度:131708995
Keep-Alive:timeout = 10, max = 30
连接:Keep-Alive
内容类型:video / x-ms-wmv

下面是我的脚本回复的请求:

  http:// www。 grinderschool.com/download_video_test.php?t=KillsAids021&format=wmv 

GET /download_video_test.php?t=KillsAids021&format=wmv HTTP / 1.1
主机:www.grinderschool.com
用户代理:Mozilla / 5.0(Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3)Gecko / 20100401 Firefox / 3.6.3(.NET CLR 3.5.30729)
接受:text / html,application / xhtml + xml,a pplication / xml; q = 0.9,* / *; q = 0.8
接受语言:en-us,en; q = 0.5
接受编码:gzip,deflate
Accept-Charset :ISO-8859-1,utf-8; q = 0.7,*; q = 0.7
Keep-Alive:115
连接:keep-alive
Cookie:style_cookie = printonly; phpbb3_7c544_u = 2; phpbb3_7c544_k = 44b832912e5f887d; phpbb3_7c544_sid = e8852df42e08cc1b2250300c2897f78f; __utma = 174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz = 174624884.1264524375.411.12.utmcsr =谷歌| utmccn =(有机)| utmcmd =有机| utmctr =低%20stakes%20poker%20videos; phpbb3_cmviy_k =; phpbb3_cmviy_u = 2; phpbb3_cmviy_sid = d8df5c0943863004ca40ef9c392d371d; __utmb = 174624884.4.10.1270989003; __utmc = 174624884

HTTP / 1.1 200 OK
日期:2010年4月11日,星期日12:58:02 GMT
服务器:Apache / 2.2.14(Unix)mod_ssl / 2.2 .14 OpenSSL / 0.9.8l DAV / 2 mod_auth_passthrough / 2.1 FrontPage / 5.0.2.2635
X-Powered by:PHP / 5.2.11
Content-Disposition:attachment;文件名= KillsAids021.wmv
Vary:Accept-Encoding
内容编码:gzip
Keep-Alive:timeout = 10,max = 30
连接:Keep-Alive
转移编码:chunked
内容类型:video / x-ms-wmv

所以问题是...我可以做什么来从脚本下载正常工作?再次,对于99%的用户,它的工作原理(虽然我现在觉得很烦人,没有报告文件大小,因此没有时间估计可以计算下载)。

解决方案

这是你的GZIP压缩。当您指定内容长度但打开压缩时,会将所有内容都填满。这是发生在我身上的几次:尝试在你的脚本中关闭它。



一般来说,你会打开它:

  ob_start(ob_gzhandler); 

...所以只是评论该行。如果这不在你的代码中,你的php.ini文件有可能在某个地方或你的apache.conf / conf.d。



希望这有帮助! / p>

This post started as a question on ServerFault ( https://serverfault.com/questions/131156/user-receiving-partial-downloads ) but I determined that our php script was the culprit. So I'm issuing an updated question here about what I believe is the actual issue.

I am using a php script to verify permissions and then serve up a file for users of my website to download. Most of the time, this works, but recently one user has been seeing problems with larger downloads. He is only getting ~80% of downloads for files that are > 100MB in size. Also, all downloads from this script fail to report a filesize. Further, tests revealed that the same user COULD reliably download each of the failed files if given a direct link (at which point the filesize is reported).

Here's the relevant snippet of code that we are using to serve the file:

header("Content-type:$contenttype");
$len = filesize($filename);
header("Content-Length: $len");
header("Content-Disposition: attachment; filename=".$title.".".$ext);
readfile($filename);

Note that $contenttype, $filename, $title, and $ext are all set correctly before we get here. These have been triple-checked. None of them are the problem. Also, $len does provide the correct filesize.

While researching this issue, I came across this post: Content-Length header always zero

It seems that I am encountering the same issue. When I use the script, I get chunked encoding on the file and no size is set for content-length. I'm hypothesizing that something is going wrong on the large downloads, leading him to get a zero-length chunk before the end of the file.

Here's what the headers look like for a direct request:

http://www.grinderschool.com/videos/zfff5061b65ae00e8b21/KillsAids021.wmv

GET /videos/zfff5061b65ae00e8b21/KillsAids021.wmv HTTP/1.1
Host: www.grinderschool.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: http://www.grinderschool.com/phpBB3/viewtopic.php?f=14&p=29468
Cookie: style_cookie=printonly; phpbb3_7c544_u=2; phpbb3_7c544_k=44b832912e5f887d; phpbb3_7c544_sid=e8852df42e08cc1b2250300c2897f78f; __utma=174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz=174624884.1264524375.411.12.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=low%20stakes%20poker%20videos; phpbb3_cmviy_k=; phpbb3_cmviy_u=2; phpbb3_cmviy_sid=d8df5c0943863004ca40ef9c392d371d; __utmb=174624884.4.10.1270989003; __utmc=174624884
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Date: Sun, 11 Apr 2010 12:57:41 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635
Last-Modified: Sun, 04 Apr 2010 12:51:06 GMT
Etag: "eb42d6-7d9b843-48368aa6dc280"
Accept-Ranges: bytes
Content-Length: 131708995
Keep-Alive: timeout=10, max=30
Connection: Keep-Alive
Content-Type: video/x-ms-wmv

And here's what they look like for the request answered by my script:

http://www.grinderschool.com/download_video_test.php?t=KillsAids021&format=wmv

GET /download_video_test.php?t=KillsAids021&format=wmv HTTP/1.1
Host: www.grinderschool.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: style_cookie=printonly; phpbb3_7c544_u=2; phpbb3_7c544_k=44b832912e5f887d; phpbb3_7c544_sid=e8852df42e08cc1b2250300c2897f78f; __utma=174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz=174624884.1264524375.411.12.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=low%20stakes%20poker%20videos; phpbb3_cmviy_k=; phpbb3_cmviy_u=2; phpbb3_cmviy_sid=d8df5c0943863004ca40ef9c392d371d; __utmb=174624884.4.10.1270989003; __utmc=174624884

HTTP/1.1 200 OK
Date: Sun, 11 Apr 2010 12:58:02 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635
X-Powered-By: PHP/5.2.11
Content-Disposition: attachment; filename=KillsAids021.wmv
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=10, max=30
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: video/x-ms-wmv

So the question is...what can I do to make downloads from the script work properly? Again, for 99% of users, it works as is (though I find it annoying now that no filesize is reported and thus that no time estimate can be computed about the download).

解决方案

It's your GZIP compression. When you specify a content length but turn compression on, it gums everything up. It's happened to me a few times: try turning it off in your script.

Generally you'd turn it on with:

ob_start("ob_gzhandler");

...so just comment that line out. If that's not in your code, chances are there's a setting in either your php.ini file somewhere or your apache.conf/conf.d.

Hope this helps!

这篇关于PHP文件服务脚本:不可靠的下载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 18:25