有没有办法配置php总是设置$ _SERVER ['CONTENT_LENGTH']?

时间:2011-10-01 10:50:45

标签: php http-headers content-length

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

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

经过一番研究后,我发现只有POST方法和上传文件才能设置php $_SERVER['CONTENT_LENGTH']。有没有办法配置php来始终设置$_SERVER['CONTENT_LENGTH']? 我一般都会问,不仅仅是因为这个案子......

// EDIT 我正在向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。所以这是一个狂野的错误?

//编辑2

最后我明白了! 使用calback readfunc的PUT请求需要通过curl_setopt(...)设置INFILE_SIZE 没有自动值,并将内容长度字段手动放入标题也是错误的。 示例(不正确):

// 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

3 个答案:

答案 0 :(得分:1)

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

在请求中,您不必设置Content-Lenght标头......这不是强制性的。除特定情况外。如果您的POSTed内容是“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==

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

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

答案 1 :(得分:1)

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

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

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

假设如果未设置,则长度为零。另见Improved handling of HTTP requests in PHP

答案 2 :(得分:0)

你可以自己设置它们。为什么需要设置这个值?那应该是什么?

  

也许你错过了关于$ _SERVER ['CONTENT_TYPE']的信息   $ _SERVER ['CONTENT_LENGTH']和我一样。在POST请求上这些是   除上面列出的那些之外还有。

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