内容长度标头未正确设置

时间:2013-10-27 18:50:45

标签: php drupal http-headers content-length http-content-length

我有一个php脚本(实际上是https://drupal.org/project/file_force),它通过在响应中添加正确的标题来强制点击链接的用户下载该链接。

此链接在90%的时间内都能正常运行。有时会传递不正确的内容长度,因此用户显然会截断文件。错误在特定文件上一致地发生,但如果重新上载这些文件,则错误可能不会出现在新实例上,这使我认为这不是文件的问题,而是某个地方的缓存。所以我每次都运行clearstatcache()无济于事。奇怪的是,php正在传递正确的文件大小,或者说它是在我传递它插入日志文件的字符串时。

以下是相关代码:

  clearstatcache();
  return array(
    'Content-Type: ' . $mimeinfo,
    'Content-Disposition: ' . $disposition . '; filename="' . basename($filepath) . '";',
    // Content-Length is also a good header to send, as it allows the browser to
    // display a progress bar correctly.
    // There's a trick for determining the file size for files over 2 GB. Nobody
    // should be using this module with files that large, but… the sprintf()
    // trickery makes sure the value is correct for files larger than 2GB. See
    // note at http://php.net/filesize
    'Content-Length: ' . sprintf('%u', filesize($filepath)),
  );

sprintf('%u',filesize($ filepath))在无法正常工作的文件上输出的样本是2682059,当浏览器看到时,它会以某种方式转换为1740048

我尝试删除sprintf功能无济于事。 我也尝试过根本不包括Content-Length声明,但是无论如何,有人正在附加不正确的值。最后一条证据或许表明其他一些代码覆盖了我在这里设置的内容标题,但它似乎只留下我在上面的代码中更改的任何其他标题来测试该理论。

对于去哪儿看的任何想法?

2 个答案:

答案 0 :(得分:2)

我解决了这个问题。

事实证明,Drupal中的另一个模块正在添加自己的内容长度标头并从数据库而不是文件直接获取值(奇怪),并且它正在下游发生。通过颠倒模块在标题上的顺序,问题就消失了。我已经针对违规模块提交了一份错误报告。

答案 1 :(得分:1)

来源:PHP official documentation - "header" function

在实际页面加载之前,您希望在PHP中使用一个名为header的函数来设置标题:

这是函数的骨架:

void header ( string $string [, bool $replace = true [, int $http_response_code ]] )

说明:

<强> 参数:

  • 字符串
  

标题字符串。

     

有两种特殊情况的标题调用。第一个是标题   以字符串“HTTP /”(大小写不重要)开头,这将是   用于确定要发送的HTTP状态代码。例如,如果   您已将Apache配置为使用PHP脚本来处理请求   您可能想要丢失文件(使用ErrorDocument指令)   确保您的脚本生成正确的状态代码。

  • 替换
  

可选的replace参数指示是否标头   应该替换以前的类似标头,或者添加第二个标头   相同的类型。默认情况下它将替换,但如果传入FALSE为   第二个参数可以强制使用相同类型的多个标题。

  • http_response_code
  

强制HTTP响应代码为指定值。请注意这一点   参数仅在字符串不为空时才有效。

===

返回值:

没有返回任何值。


实施例

<?php
    header('Location: http://www.example.com/'); //redirect to www.example.com
?>

注意:在发送任何输出之前,即在任何HTML标记之前或任何 echo 调用之前,必须调用函数。

在你的情况下:

<?php
    header('Content-Length: ' . sprintf('%u', filesize($filepath)));
?>

默认情况下的替换参数 - true,会导致程序覆盖之前设置的所有'Content-Length'标题。

希望所有解释都值得...... :)