我必须通过我的Apache2 / PHP服务器向一些人(舞会图片)分发一个巨大的文件,这给我一些麻烦:Chrome和Firefox都显示2GB的文件大小但文件实际上大于4GB,所以我开始追踪事情。 我在我的php脚本中做了以下事情:
header("Content-Length: ".filesize_large($fn));
header("Actual-File-Size: ".filesize_large($fn)); //Debug
readfile($fn);
filesize_large()
将> 4gb文件的正确文件大小作为字符串返回(是的,甚至在32位PHP上)。
现在有趣的部分;实际的HTTP标头:
Content-Length: 2147483647
Actual-File-Size: 4236525700
所以filesize_large()
方法工作得很好,但PHP或Apache在某种程度上限制了Content-Length的值?!为什么?
Apache / 2.2.22 x86,PHP 5.3.10 x86,我在https上使用SSL
当我说filesize_large()
是正确的时候,你们就相信我了:
function filesize_large($filename)
{
return trim(shell_exec('stat -c %s '.escapeshellarg($filename)));
}
似乎PHP在通过32位系统上的sapi接口与apache2通信时将内容长度转换为整数。遗憾的是没有解决方法,除了在文件> 2GB
的情况下不包括内容大小解决方法(实际上是一个更好的解决方案):使用mod_xsendfile
答案 0 :(得分:1)
您必须使用64位操作系统才能支持Content-length标头的长整数。 我建议使用Vagrant进行开发。
基于字符串的标头,但内容长度基于int
。如果看看这里https://books.google.com/books?id=HTo_AmTpQPMC&pg=PA130&lpg=PA130&dq=ap_set_content_length%28r,+r-%3Efinfo.size%29;&source=bl&ots=uNqmcTbKYy&sig=-Wth33sukeEiSnUUwVJPtyHSpXU&hl=en&sa=X&ei=GP0SVdSlFM_jsATWvoGwBQ&ved=0CDEQ6AEwAw#v=onepage&q=ap_set_content_length%28r%2C%20r-%3Efinfo.size%29%3B&f=false
您将看到ap_set_content_length();
函数的示例,该函数用于提供内容长度响应。它接受来自系统功能的文件长度。尝试调用php filesize()
,你可能会看到相同的结果。
如果您查看ap_set_content_length
声明http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga7ab393c56cf073ce7aadc3b7ca3db7b2
您将看到该长度声明为apr_off_t
。
在这里http://svn.haxx.se/dev/archive-2004-01/0871.shtml你可以读到,这种类型取决于你的情况下32位的编译器选项。
我建议你阅读Apache和PHP项目的源代码。