有没有办法配置 php 始终设置 $_SERVER['CONTENT_LENGTH']?
我正在研究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。那么这是一个戴维的错误吗?
//编辑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
I'm working on carddav client. As server i use davical v. 0.9.9.6. I don't understand why i'm getting invalid content-type error when http headers contains correct value. I look into source code and found this condition:
if ( isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 7) {...
After little research I found php set $_SERVER['CONTENT_LENGTH']
only with POST method and uploading file. Is there any way to configure php to always set $_SERVER['CONTENT_LENGTH']
?
I'm asking generally, not only for this case...
//EDIT
I'm doing HTTP PUT request to davical server (using 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
...
On davical side is condition testing CONTENT_LENGTH which is not set. So it's a davical bug?
//EDIT 2
Finally I figure it out!
PUT request with calback readfunc requires set INFILE_SIZE via curl_setopt(...)
There is none auto value and put Content-Length field manualy into header is also wrong.
Example (incorrect):
// 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
Second (correct) example
// 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尽管我从未使用过 CONTENT_LENGHT,但我可以告诉您为什么可能会发生这种情况:
在请求中,您不必设置 Content-Lenght 标头...这不是强制性的。特殊情况除外。如果您发布的内容的类型为“multipart/form-data”,则有必要为每个部分使用内容长度,因为每个部分都由边界分隔,并且每个部分都有自己的标题...
例如:
所以这里是是多部分请求工作原理的一个粗略示例,您会看到第二部分具有内容长度。这就是为什么有时设置内容长度有时不设置的原因,因为在找到另一个边界并提取正确的数据之前需要读取 X 字节。
这并不意味着您的服务器在其他情况下永远不会发送它,但我的 2 美分是现在的情况。这是因为你不是处于POST,而是处于其他一些模式。
Although i have never used CONTENT_LENGHT i can tell you why this is probably happening:
In a request, you don't have to set the Content-Lenght header... IT IS NOT MANDATORY. Except for specific situations. If your POSTed content is of type "multipart/form-data" it becomes necessary to use content-lenght for each part because each part is seperated by a boundary and each part will have its own headers...
For example:
So here this is a crude example of what a multi part request works, you see that the second part has a content-lenght. This is why sometimes the content-lenght is set and sometimes not, because you need to read X bytes before finding another boundary and extract the correct data.
It doesn't mean your server will never send it in in other cases, but my 2 cents are this is the case right now. Its because you are not in POST, but in some other modes.
只有具有请求正文的请求才具有内容长度请求标头(或者至少只有这样才有意义),因此会设置
$_SERVER
变量。如果您需要始终设置它(我认为这是假的),您可以在脚本的一开始就自己执行此操作:
假设如果未设置它,则它的长度为零。另请参阅改进了 PHP 中 HTTP 请求的处理。
Only requests that have a request body have a content length request header (or at least only then it makes sense) and so therefore the
$_SERVER
variable is set.If you need it to be always set (which I think is bogus), you can do this yourself on the very beginning of your script:
Assuming that if it is not set, it's of zero length. See as well Improved handling of HTTP requests in PHP.
您也许可以自己设置它们。为什么需要设置这个值?他们应该设置什么?
-> http://www.php.net/manual/en/reserved .variables.server.php#86495
You could probably set them by yourself. Why do you need that this values are set? And what should they set to?
-> http://www.php.net/manual/en/reserved.variables.server.php#86495