【问题标题】:PHP_curl loose content-length on redirectPHP_curl 重定向时的内容长度松散
【发布时间】:2020-07-13 14:50:56
【问题描述】:

我正在尝试向付款处理页面发出请求。这需要授权,这通过一组重定向进行。在第二步中,我收到“411 Length Required”错误,这意味着内容长度在此过程中丢失了。确实,我在日志中看不到它。在这里可以做什么?更换工具(编程语言)?

CURLOPT_VERBOSE:

*   Trying xxx.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.dev.example.com
*  start date: Apr 27 00:00:00 2019 GMT
*  expire date: Apr 26 23:59:59 2021 GMT
*  subjectAltName: host "api.dev.example.com" matched cert's "*.dev.example.com"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
*  SSL certificate verify ok.
> POST /p2p/v2/payer HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Content-Length: 224

* upload completely sent off: 224 out of 224 bytes
< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 213
< Connection: keep-alive
< Keep-Alive: timeout=20
< Cache-Control: private
< Location: /api/payer/auth?sessionToken=e744a95992fa405ba10662bbc6908d6bedd48a73cc0d45d589f4ef2f7d7a0b88
< Set-Cookie: returnUrl=http://example.com/returnurl.php; path=/
< 
* Ignoring the response-body
* Connection #0 to host api.dev.walletone.com left intact
* Issue another request to this URL: 'https://api.dev.example.com/auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88'
* Switch from POST to GET
* Found bundle for host api.dev.example.com: 0x5649fd243480 [can pipeline]
* Re-using existing connection! (#0) with host api.dev.example.com
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
> POST /auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88 HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

< HTTP/1.1 411 Length Required
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=us-ascii
< Content-Length: 344
< Connection: keep-alive
< Keep-Alive: timeout=20
< 
* Connection #0 to host api.dev.example.com left intact

我的代码是:

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $path);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, Array (
            "Content-Type: application/x-www-form-urlencoded",
            "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
        ));
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $order_data);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        curl_setopt($ch, CURLOPT_STDERR, $verbose);
        $response = curl_exec($ch);
        curl_close($ch);

【问题讨论】:

    标签: php http-headers php-curl


    【解决方案1】:

    在header中设置content-length,设置为$order_data的字符串长度strlen()

    curl_setopt($ch, CURLOPT_HTTPHEADER, Array (
      "Content-Type: application/x-www-form-urlencoded",
      "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 
      "Content-Length: ". strlen($order_data)  
     ));  
    

    您也可以通过检查curl_setopt($ch, CURLINFO_HEADER_OUT, true); 来调试它,这使得curl_getinfo() 在其输出中包含请求的标头。

    【讨论】:

    • Alice,正如您在附加日志中所见,第一个请求中的 Content-Length 存在。它在请求中不存在,php_curl 自动生成并且我无法修改标头。无论如何,我尝试了你的建议。服务器完全没有响应)
    • 嗯,这似乎很奇怪。它只是一个像其他所有东西一样的标题。哦,对不起,我意识到我添加了第二种内容类型。稍微编辑了我的答案
    • 另一件事可能是身份验证的工作方式。内容长度在第一个请求中发送,但不是第二个。
    • 如果我删除“accept”,那么服务器会返回另一个错误。我从我的 Firefox 中获取了这个接受标头。我用普通的形式实现了这个方法,它就像一个魅力。
    • 另一个版本是302“redirect temporary”的问题。我发现一篇文章(俄语)表明不同的 http 客户端(邮递员等)通过这种类型的重定向丢失了内容长度。解决方案是在 307 上更改 302,但它不能解决我的情况。无论如何,丢失普通的 http 标头看起来像一个错误。
    【解决方案2】:

    问题在于使用 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method)。 Curl 尝试像大多数浏览器一样切换到 GET,但不能。使用 curl_setopt($ch, CURLOPT_POST, 1);确实。

    【讨论】:

      猜你喜欢
      • 2012-01-31
      • 2019-05-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      相关资源
      最近更新 更多