简体   繁体   English

PHP或Apache在HTML标头中限制Content-Length?

[英]PHP or Apache limiting Content-Length in HTML Header?

I have to distribute a huge file to some people (pictures of a prom) via my Apache2/PHP server which is giving me some headaches: Chrome and Firefox both show a filesize of 2GB but the file is actually >4GB, so I started to track things down. 我必须通过我的Apache2 / PHP服务器将一个巨大的文件分发给某些人(舞会的图片),这让我有些头疼:Chrome和Firefox都显示2GB的文件大小,但该文件实际上大于4GB,所以我开始追踪事物。 I am doing the following thing in my php script: 我在php脚本中正在执行以下操作:

header("Content-Length: ".filesize_large($fn));
header("Actual-File-Size: ".filesize_large($fn)); //Debug
readfile($fn);

filesize_large() is returning the correct filesize for >4gb files as a string (yes, even on 32-bit PHP). filesize_large()会以字符串形式返回4GB以上文件的正确文件大小(是的,即使在32位PHP上也是如此)。 Now the interesting part; 现在是有趣的部分; the actual HTTP header: 实际的HTTP标头:

Content-Length: 2147483647
Actual-File-Size: 4236525700

So the filesize_large() method is working totally fine, but PHP or Apache somehow limit the value of Content-Length?! 因此, filesize_large()方法完全可以正常工作,但是PHP或Apache某种程度上限制了Content-Length的值? Why that? 为什么?

Apache/2.2.22 x86, PHP 5.3.10 x86, I am using SSL over https Apache / 2.2.22 x86,PHP 5.3.10 x86,我通过https使用SSL

Just so you guys believe me when I say filesize_large() is correct: 就是这样,当我说filesize_large()是正确的时,你们相信我:

function filesize_large($filename)
{
    return trim(shell_exec('stat -c %s '.escapeshellarg($filename)));
}

Edit: 编辑:

Seems like PHP casts the content length to an integer when communicating with apache2 over the sapi interface on 32-bit systems. 似乎PHP在32位系统上通过sapi接口与apache2通信时,将内容长度转换为整数。 No workaround sadly except not including the Content-Size in case of files >2GB 可悲的是,没有解决方法,除非文件> 2GB,不包括Content-Size

Workaround (and actually a far better solution in the first place): Use mod_xsendfile 解决方法(实际上是一个更好的解决方案):使用mod_xsendfile

You have to use 64-bit operation system in order to support long integers for Content-length header. 您必须使用64位操作系统才能为Content-length标头支持长整数。 I would recommend to use Vagrant for development. 我建议使用Vagrant进行开发。

Header based on strings, but content length based on int . 标头基于字符串,但内容长度基于int If take a look here 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 you will see example of ap_set_content_length(); 如果在这里看看, 请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=-WthHSsXUU&en=p 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();示例ap_set_content_length(); function which was used to serve content-length response. 用于服务内容长度响应的功能。 It accepts file length from system function. 它从系统功能接受文件长度。 Try to call php filesize() and you'll probably see the same result. 尝试调用php filesize() ,您可能会看到相同的结果。

If you take a look into ap_set_content_length declaration http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga7ab393c56cf073ce7aadc3b7ca3db7b2 you will see that length declared as apr_off_t . 如果您查看ap_set_content_length声明http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga7ab393c56cf073ce7aadc3b7ca3db7b2,您将看到声明为apr_off_t长度。

And here http://svn.haxx.se/dev/archive-2004-01/0871.shtml you can read, that this type depends from compiler options which is 32bit in your case. 在这里您可以阅读http://svn.haxx.se/dev/archive-2004-01/0871.shtml ,该类型取决于您所用的32位编译器选项。

I would recommend you to read source code of Apache and PHP projects. 我建议您阅读Apache和PHP项目的源代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM