我正在开发carddav客户端。作为服务器,我使用 davical v. 0.9.9.6。我不明白为什么当 http 标头包含正确的值时我会收到无效的内容类型错误。我查看了源代码并发现了这种情况:
if ( isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 7) {...
经过一番研究,我发现 php$_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