【问题标题】:cURL GET method fails in php, but browser and console complete it successfullycURL GET方法在php中失败,但浏览器和控制台成功完成
【发布时间】:2016-11-25 10:43:39
【问题描述】:

如果标题不当,我深表歉意,但我想不出更好的定义。

我正在为这个问题发疯。在过去 5 年多的时间里,我一直致力于通过 cURL 收集提要和数据,但从未遇到过这种情况。我有一个大的 json 可以通过 HTTPS 从远程服务器的 GET 方法从看起来像这样的地址收集 https://private.example.com/thisDotNetEndPoint?token=bla-bla-trutj&someParam=1

someParam 是可变的,对于一些数据量较低的值,一切正常,与浏览器的速度几乎相同,但在某些情况下,cURL 总是进入 tiomeout 集,而在浏览器和控制台中一切正常

PHP

我的cURL如下:

$ch = curl_init();
$url = 'https://private.example.com/thisDotNetEndPoint?token=bla-bla-trutj&someParam=1';
curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_HEADER, 0);
// I've added this user agent as it is the same as the one Chrome uses
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36');

curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
// I have tried removing the SSL part below, but no difference
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, "HIGH:!SSLv3s");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // tried this with true, but no difference
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 1200); // what ever the timeout I set the cURL always goes to timeout
curl_setopt($ch, CURLOPT_VERBOSE, true);

$response = curl_exec($ch);
if (curl_errno($ch)) {
    print("cURL error: " . curl_error($ch));
    print_r(curl_getinfo($ch));
} else {
    print_r(json_decode($response));
}
curl_close($ch);

这是详细的输出:

* Hostname was NOT found in DNS cache
*   Trying 12.34.567.89...
* Connected to private.example.com (12.34.567.89) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSL connection using ECDHE-RSA-AES256-SHA384
* Server certificate:
*    subject: OU=Domain Control Validated; CN=*.example.com
*    start date: 2016-03-03 09:41:38 GMT
*    expire date: 2018-03-04 09:52:18 GMT
*    subjectAltName: private.example.com matched
*    issuer: C=US; ST=Arizona; L=Scottsdale; O=Starfield Technologies, Inc.; OU=http://certs.starfieldtech.com/repository/; CN=Starfield Secure Certificate Authority - G2
*    SSL certificate verify ok.
> GET /thisDotNetEndPoint?token=bla-bla-trutj&someParam=1 HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Host: private.example.com
Accept: */*                                                                              */
* Operation timed out after 1200001 milliseconds with 0 bytes received
* Closing connection 0

无论我设置什么超时,它总是会超时,甚至尝试将其设置为 2 小时。

我什至尝试添加这些但没有区别:

curl_setopt($ch, CURLOPT_NOSIGNAL, 1);

curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 1);
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 1200);

浏览器

当我在浏览器中输入相同的网址时,响应会在 6-9 分钟内返回

来自控制台的 cURL

我使用了最简单的命令,它与浏览器同时工作:

$ curl -X GET -v 'https://private.example.com/thisDotNetEndPoint?token=bla-bla-trutj&someParam=1'

详细输出:

* Hostname was NOT found in DNS cache
*   Trying 12.34.567.89...
* Connected to private.example.com (12.34.567.89) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-RSA-AES256-SHA384
* Server certificate:
*    subject: OU=Domain Control Validated; CN=*.example.com
*    start date: 2016-03-03 09:41:38 GMT
*    expire date: 2018-03-04 09:52:18 GMT
*    subjectAltName: private.example.com matched
*    issuer: C=US; ST=Arizona; L=Scottsdale; O=Starfield Technologies, Inc.; OU=http://certs.starfieldtech.com/repository/; CN=Starfield Secure Certificate Authority - G2
*    SSL certificate verify ok.
> GET /thisDotNetEndPoint?token=bla-bla-trutj&someParam=1 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: private.example.com
> Accept: */*                                                                              */
>
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: application/json; charset=utf-8
< Server: Microsoft-IIS/8.5
< X-StackifyID: V1|b8b10c35-2649-4f67-ba6a-b5ad15ef553b|C56050|CD18|
< Set-Cookie: .ASPXANONYMOUS=looI88UVBp6Cg5tLkzVejO4CNRilhyKjMY4hFqhuO48vdVT19U8h5oisC9khFv1rOmH6Ii_lEec-9XhipEvh1UkewhufqfmlTGFsyQCaML06NVa-5-Vr_OikZb07R6pdHCeRtn9liBVJfamJmXiElA2; expires=Thu, 02-Feb-2017 20:54:18 GMT; path=/; HttpOnly
< X-AspNetMvc-Version: 5.2
< Rx-CID: ae9907d6fc394b24b6599e74ab5a668f
< Rx_RequestId: f3fff82c4de04bba90b2bbc5704ac787
< X-Powered-By: ASP.NET
< Strict-Transport-Security: max-age=31536000
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: rx-cid
< Date: Fri, 25 Nov 2016 10:25:00 GMT
< Content-Length: 2231472
<
[and the response is printed here]

有什么想法吗?

提前致谢。

【问题讨论】:

    标签: php curl https


    【解决方案1】:

    您注意到控制台和您的 php 详细输出之间的区别了吗?您的 php 代码中缺少用户代理。 curl 命令行默认添加这个用户代理,而 php-curl 没有。

    User-Agent: curl/7.35.0
    

    使用选项CURLOPT_USERAGENT

    curl_setopt($ch, CURLOPT_USERAGENT, "Opera 11.0");
    

    【讨论】:

    • 这应该与它没有任何关系。无论如何我已经尝试添加用户代理,结果是一样的(编辑问题)。
    猜你喜欢
    • 2019-05-23
    • 2012-02-21
    • 1970-01-01
    • 2018-07-29
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2018-11-05
    相关资源
    最近更新 更多