【问题标题】:PHP or Apache limiting Content-Length in HTML Header?PHP 或 Apache 限制 HTML 标头中的内容长度?
【发布时间】:2015-05-29 13:20:36
【问题描述】:

我必须通过我的 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 的情况下不包括 Content-Size

解决方法(实际上是一个更好的解决方案):使用 mod_xsendfile

【问题讨论】:

  • 你能发布你的完整代码吗?尤其。 filesize_large()的代码
  • “即使在 32 位 PHP 上”也是你的问题。这仍然会是一个问题。您是否尝试过不发送标头?
  • 当我不发送标题时,Chrome 和 Firefox 没有关于文件大小的信息,他们只是开始愉快地下载。
  • 是的,我认为这是您唯一真正的解决方案,除非您可以更改为 64 位或拆分文件。
  • 找到这个,好像很像stackoverflow.com/q/6748471/1301076

标签: php apache


【解决方案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 项目的源代码。

【讨论】:

  • 但是header()不应该是基于字符串的吗?
  • 标头基于字符串,但内容长度基于int,请查看更新后的答案。
  • 感谢您挖掘 apache 源代码,非常感谢您付出的努力。接受的答案,因为它回答了我的初始问题(“为什么要修改标头”),尽管我现在使用 mod_xsendfile 作为解决方案(请参阅更新的问题)。
猜你喜欢
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 2016-11-25
  • 2013-02-15
  • 2014-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多