2

似乎 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

在此先感谢,并为文字墙感到抱歉。

4

0 回答 0