我们正在尝试使用mod_xsendfile和Apache来有效地处理大文件下载(> 1 GB)。安装后的配置是这样的:mod_xsendfile Firefox恢复问题
<IfModule mod_xsendfile.c>
<Directory "/abs_path/to/dl">
XSendFile on
XSendFilePath /abs_path/to/files_dir
</Directory>
</IfModule>
下载脚本确实没有什么花哨,只检查文件是否存在,下载并设置标题为每文档,像这样:
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header("X-Sendfile: " . $file);
不间断下载工作使用我们测试过的任何用户代理都可以,并且HTTP-Range对除Firefox以外的所有用户(测试版本27和28)都可以正常工作。 Firefox可以暂停下载,但每次恢复失败。
这些是活HTTP头扩展捕获的HTTP标头:
初始下载:
http://www.oursite.com/dl/test-xs.php?ID=TestFileID
GET /dl/test-xs.php?ID=TestFileID HTTP/1.1
Host: www.oursite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: some cookie string...
Connection: keep-alive
HTTP/1.1 200 OK
Date: Tue, 25 Mar 2014 10:22:46 GMT
Server: Apache
X-Powered-By: PHP/5.3.28
Content-Disposition: attachment; filename="TestFile.ext"
Last-Modified: Sun, 02 Mar 2014 18:20:36 GMT
Content-Length: 84406272
Connection: close
Content-Type: application/octet-stream
...当Firefox的尝试恢复:
http://www.oursite.com/dl/test-xs.php?ID=TestFileID
GET /dl/test-xs.php?ID=TestFileID HTTP/1.1
Host: www.oursite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: same cookie string...
Connection: keep-alive
Range: bytes=11238434-
If-Unmodified-Since: Sun, 02 Mar 2014 18:20:36 GMT
...服务器返回404
HTTP/1.1 404 Not Found
Date: Tue, 25 Mar 2014 10:23:03 GMT
Server: Apache
X-Powered-By: PHP/5.3.28, PHP/5.3.28
Content-Disposition: attachment; filename="TestFile.ext"
X-Sendfile: /abs_path/to/files_dir/TestFile.ext
X-Pingback: http://www.oursite.com/xmlrpc.php
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
......这明显会导致Firefox无法恢复下载(现在只能从开始取消并重新启动)。
考虑一切正常在其他浏览器和下载管理器,我们已经试过:
- 有没有人遇到过类似的行为?
- 任何人都可以在我们的 下载脚本或配置代码中解释或指出它的潜在原因吗?
编辑:
做更多的一些测试结果证明,问题是下降到恢复下载时If-Unmodified-Since
头被火狐发送之后。即使此标头正确设置为从Apache接收到的Last-Modified
响应标头的值,服务器也不会因为某种原因而喜欢它,并以404
作出响应。通过改变从的.htaccess要求剥离If-Unmodified-Since
头之后:
<Files test-xs.php>
RequestHeader unset If-Unmodified-Since
</Files>
...恢复正常工作无处不在,包括Firefox浏览器。
如果要下载的文件同时被修改,但这种方法当然是不正确的,但它为我们完成了这项工作,因为我们使用不同的约定来提供同一文件的较新版本。
这显然更像是一个黑客而不是一个正确的实现,所以不能确定这是否应该被标记为答案,我将它作为原始问题的补充。
新的问题出现明显:
- 有没有更好的办法来解决这个问题?
- 这是mod_xsendfile中的错误吗?