似乎 PHP 的内置 cURL 模块在发送标题字段之前会更改它们。
我开发了一个小类来通过 HTTP 请求与编码器设备进行通信,使用 cURL 来完成任务。该代码在 Windows 下运行良好,但是,当我在 Debian 下运行它时,设备响应 HTTP 406 错误。
错误代码表示服务器无法以请求的格式响应。(更多信息)
这很奇怪,因为响应类型是由 URL 的扩展名决定的(可能的模式是 xml 和 json),而我没有Accept
在 header 中明确设置参数。
使用该CURLOPT_VERBOSE
参数,它会转储以下数据:
* Hostname was NOT found in DNS cache
* Trying 172.19.0.9...
* Connected to 172.19.0.9 (172.19.0.9) port 1080 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
* subject: C=US; ST=Illinois; L=Lake Forest; O=Haivision Network Video, Inc.; OU=PRODUCT DEVELOPMENT; CN=localhost.localdomai n; emailAddress=support@haivision.com
* start date: 2016-01-22 14:40:48 GMT
* expire date: 2026-01-19 14:40:48 GMT
* issuer: C=US; ST=Illinois; L=Lake Forest; O=Haivision Network Video, Inc.; OU=PRODUCT DEVELOPMENT; CN=localhost.localdomain ; emailAddress=support@haivision.com
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> POST /ecs/auth.xml HTTP/1.1
Host: 172.19.0.9:1080
Accept: */*
Content-Length: 86
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 86 out of 86 bytes
< HTTP/1.1 406 Not Acceptable
* Server nginx is not blacklisted
< Server: nginx
< Date: Fri, 01 Apr 2016 08:45:30 GMT
< Content-Type: application/xml
< Content-Length: 135
< Connection: keep-alive
<
* Connection #0 to host 172.19.0.9 left intact
看起来Content-Type: application/xml
改成了application/x-www-form-urlencoded
,我认为这是请求失败如此悲惨的主要原因。
传递给curl_setopts()
函数的数组如下所示:
array(11) {
[19913]=>
bool(true)
[64]=>
bool(false)
[52]=>
bool(false)
[68]=>
int(10)
[10023]=>
array(5) {
["Authorization"]=>
string(10) "Basic ==Og"
["Cache-Control"]=>
string(8) "no-cache"
["Content-Type"]=>
string(15) "application/xml"
["Connection"]=>
string(10) "keep-alive"
["Content-Length"]=>
int(86)
}
[20079]=>
array(2) {
[0]=>
object(Pest)#43 (6) {
["curl_opts"]=>
array(9) {
[19913]=>
bool(true)
[64]=>
bool(false)
[52]=>
bool(false)
[68]=>
int(10)
[10023]=>
array(0) {
}
[20079]=>
*RECURSION*
[81]=>
int(0)
[84]=>
int(2)
[41]=>
bool(true)
}
["base_url"]=>
string(23) "https://172.19.0.9:1080"
["last_response"]=>
NULL
["last_request"]=>
NULL
["last_headers"]=>
NULL
["throw_exceptions"]=>
bool(true)
}
[1]=>
string(13) "handle_header"
}
[81]=>
int(0)
[84]=>
int(2)
[41]=>
bool(true)
[10036]=>
string(4) "POST"
[10015]=>
string(86) "<?xml version="1.0" encoding="UTF-8"?>
<user username="#########" password="########"/>
"
如您所见,没有Accept
标签,并且内容类型设置为application/xml
.
所以这是我的问题:为什么 curl 会更改请求的标头?如果问题的根源是其他问题,那么它在 Win10 上运行而不在 Debian Jessie 上运行的原因是什么?
更新(16. 04. 04.):
有趣的是,相同版本的 cURL 库在 PHP 中不起作用,但在 cli 中起作用:
curl -X POST -H "Authorization: Basic aGFpYWRtaW46bWFuYWdlcg==" -H "Content-Type: application/xml" -H "Cache-Control: no-cache" -H "Postman-Token: 760f1aac-619f-4b64-ec06-0146554fcecf" -d '<?xml version="1.0"?><user username="########" password="#######" />' "https://172.19.0.9:1080/ecs/auth.xml"
<?xml version="1.0"?>
<sessionid value="fd7b8fd0-ac5e-4f72-a01c-142082de24f1"/>
linux 机器上的 CURL 版本是7.26.0 (x86_64-pc-linux-gnu) libcurl/7.26.0。
在此先感谢,并为文字墙感到抱歉。