【发布时间】: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