【问题标题】:Is there any way to configure php to always set $_SERVER['CONTENT_LENGTH']?有什么方法可以将 php 配置为始终设置 $_SERVER['CONTENT_LENGTH']?
【发布时间】:2011-10-01 10:50:45
【问题描述】:

我正在开发 carddav 客户端。作为服务器,我使用 davical v. 0.9.9.6。我不明白为什么当 http 标头包含正确的值时我会收到无效的内容类型错误。我查看了源代码,发现了这种情况:

if ( isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 7) {...

经过一番研究,我发现 php set $_SERVER['CONTENT_LENGTH'] 仅使用 POST 方法和上传文件。有什么办法可以将 php 配置为始终设置$_SERVER['CONTENT_LENGTH']? 我问的是一般情况,不仅针对这种情况...

//编辑 我正在向 davical 服务器发出 HTTP PUT 请求(使用 php curl)。

PUT /caldav.php/testuser/contacts/newc.vcf HTTP/1.1
Host: davical  
Content-Type: text/vcard;

BEGIN:VCARD
VERSION:3.0
FN:ME
...

在 davical 方面是条件测试 CONTENT_LENGTH 未设置。所以这是一个davical bug?

//编辑2

我终于明白了! 带有回调 readfunc 的 PUT 请求需要通过 curl_setopt(...) 设置 INFILE_SIZE 没有自动值并将 Content-Length 字段手动放入标题中也是错误的。 示例(不正确):

// PUT REQUEST
curl_setopt($ch,CURLOPT_HTTPHEADER,"Content-Length: $length");  //mistake
curl_setopt($ch,CURLOPT_PUT,true);
curl_setopt($ch,CURLOPT_READFUNCTION,array($this,'readfunc'));
....
--------------------------------------------------------------
// WIRESHARK TCP STREAM DUMP
PUT /caldav.php/testuser/contacts/novy.vcf HTTP/1.1
Authorization: Basic xxxxxxxxxxxxxxx
Host: davical
Accept: */*
Content-Type: text/vcard
Content-Length: xxx
Expect: 100-continue

HTTP/1.1 100 Continue

155
BEGIN:VCARD
VERSION:3.0
...
END:VCARD

0

HTTP/1.1 200 OK
----------------------------------------------------------------
// On server side
isset($_SERVER['CONTENT_LENGTH'])==false

第二个(正确的)例子

// PUT REQUEST
curl_setopt($ch,CURLOPT_INFILESIZE,$length);
curl_setopt($ch,CURLOPT_PUT,true);
curl_setopt($ch,CURLOPT_READFUNCTION,array($this,'readfunc'));
....
--------------------------------------------------------------
// WIRESHARK TCP STREAM DUMP
PUT /caldav.php/testuser/contacts/novy.vcf HTTP/1.1
Authorization: Basic xxxxxxxxxxxxxxx
Host: davical
Accept: */*
Content-Type: text/vcard
Content-Length: xxx
Expect: 100-continue

HTTP/1.1 100 Continue

BEGIN:VCARD
VERSION:3.0
...
END:VCARD
HTTP/1.1 200 OK
----------------------------------------------------------------
// On server side
isset($_SERVER['CONTENT_LENGTH'])==true

【问题讨论】:

  • 如果问题出在内容类型上,那么内容长度与它有什么关系?
  • content_legth 测试失败导致内容类型出现错误消息。该条件封装了重要的代码。这不是我的代码。这是 davical(开源)项目。我正在写客户端,发现了这个问题。
  • 存在一个 DAViCal 错误,该错误已被修复。

标签: php http-headers content-length


【解决方案1】:

虽然我从未使用过 CONTENT_LENGHT,但我可以告诉你为什么会发生这种情况:

在请求中,您不必设置 Content-Lenght 标头...这不是强制性的。特殊情况除外。如果您发布的内容是“multipart/form-data”类型,则有必要对每个部分使用 content-lenght,因为每个部分都由边界分隔,并且每个部分都有自己的标题...

例如:

Content-Type: MultiPart/Form-Data
Boundary: @FGJ4823024562DGGRT3455

MyData=1&Username=Blabla&Password=Blue


@FGJ4823024562DGGRT3455==
Content-Type: image/jpef:base64
Content-Lenght: 256

HNSIFRTGNOHVDFNSIAH$5346twSADVni56hntgsIGHFNR$Iasdf==

所以这是一个多部分请求工作原理的粗略示例,您会看到第二部分具有内容长度。这就是为什么有时设置了 content-lenght 有时不设置的原因,因为您需要在找到另一个边界并提取正确的数据之前读取 X 个字节。

这并不意味着您的服务器在其他情况下永远不会发送它,但我的 2 美分现在就是这种情况。那是因为你不是在POST,而是在其他一些模式。

【讨论】:

  • Content-Length 在发送多部分请求时也不需要。
  • 不是吗?我总是不得不把它放进去,但也许我读错了文档,无论如何,你不能依赖它,因为在大多数情况下它不会在那里......
  • 实际上,它大部分时间都在那里。 Content-Length 通常与 Connection: close 标头一起发送。一旦服务器接收到Content-Length 标头中定义的数据量,它将自动关闭连接。当它没有发送时,大多数服务器仍然会接受请求,但客户端将负责关闭连接。但在所有情况下,Content-Length 被服务器忽略,因此通常不会发送,当提供 Transfer-Encoding 时(例如:分块),就像客户端正在流式传输数据时一样。
【解决方案2】:

只有具有 请求正文 的请求才具有内容长度请求标头(或至少只有这样才有意义),因此设置了 $_SERVER 变量。

如果您需要始终设置它(我认为这是虚假的),您可以在脚本的最开始自己执行此操作:

isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] = 0;

假设如果没有设置,它的长度为零。另见Improved handling of HTTP requests in PHP

【讨论】:

  • 我有请求正文。我使用 vcard 内容(客户端)进行 PUT 请求。在服务器端,它也是 php,并且没有设置条件测试 CONTENT_LENGTH。服务器端不是我的代码,所以如果可能的话,我想在那里避免更改
  • 如果服务器端不是您的代码,并且它包含错误,因为它需要一个真正可选的标头,您应该提交错误报告。您使用的是哪个库?
【解决方案3】:

您可以自己设置它们。为什么需要设置这些值?他们应该设置什么?

也许您缺少有关 $_SERVER['CONTENT_TYPE'] 的信息或 $_SERVER['CONTENT_LENGTH'] 和我一样。在 POST 请求中,这些是 除了上面列出的之外,还可以使用。

->http://www.php.net/manual/en/reserved.variables.server.php#86495

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-21
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    相关资源
    最近更新 更多