64

我有一个使用 cURL(最新版本)连接到安全网关进行支付的站点。

问题是 cURL 总是返回 0 长度的内容。我只得到标题。并且仅当我将 cURL 设置为返回标头时。我有以下标志。

curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $gatewayURI);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_POST, 1);

返回的标头是

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 01:08:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 0
Content-Type: text/html
Set-Cookie: ASPSESSIONIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/
Cache-control: private

我也尝试过卷曲不同的网站,它们返回的内容很好。我认为这个问题可能与 https 连接有关。

我已经和公司谈过了,他们没有帮助。

有没有其他人遇到过这个错误并且知道解决方法?我应该放弃 cURL 并尝试使用fsockopen()吗?

谢谢你。:)

4

12 回答 12

100

我今天遇到了同样的问题。Curl 带有一个过时的文件来验证 HTTPS 证书。

从以下位置获取新的:

http://curl.haxx.se/ca/cacert.pem

将其保存到您网站上的某个目录中

并添加

curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem"); 

对于每个请求:-)

忽略任何关于禁用 CURLOPT_VERIFYPEER 和 CURLOPT_VERIFYHOST 的愚蠢评论!这会使您的代码容易受到中间人攻击!

2016 年 12 月编辑:

使用下面提到的 Jasen 方法正确解决此问题。

添加curl.cainfo=/etc/ssl/certs/ca-certificates.crt到你 php.ini

2017 年 10 月编辑:

现在有一个 composer 包可以帮助您管理 ca 证书,这样如果您的 cacert.pem 由于吊销证书而变得过时,您就不会受到攻击。

https://github.com/paragonie/certainty ->composer require paragonie/certainty:dev-master

于 2008-11-25T08:52:55.563 回答
35

您还应该尝试检查 curl_error() 中的错误消息。您可能需要在每个 curl_* 函数之后执行一次。

http://www.php.net/curl_error

于 2008-12-03T00:47:48.770 回答
28

注意:这严格不是生产用途。如果您想快速调试,这可能很有用。否则,请使用上面@SchizoDuckie 的答案。

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);     
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 

只需添加它们。有用。

于 2010-07-21T22:43:28.173 回答
6

刚刚有一个非常相似的问题并通过添加解决了它

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

显然,我正在获取的站点重定向到另一个位置,而 php-curl 默认情况下不遵循重定向。

于 2012-10-19T20:12:14.300 回答
4

我遇到过这样的情况:(Windows 上的 PHP 5.4.16)

curl_setopt($ch, CURLOPT_SSLVERSION, 3);
于 2013-06-12T00:13:00.297 回答
3

每当我使用 PHP/Curl 进行测试时,我都会先从命令行尝试,找出可行的方法,然后将我的选项移植到 PHP。

于 2008-11-25T02:48:38.420 回答
2

有时您必须将您的 Curl 证书升级到最新版本,以免出现 https 错误。

于 2010-02-05T11:24:27.030 回答
1

我使用file_get_contentsusingstream_create_context并且效果很好:

$postdataStr = http_build_query($postdataArr);

$context_options = array (
        'http' => array (    <blink> // this will allways be http!!!</blink>
            'method' => 'POST',
            'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
                . "Content-Length: " . strlen($postdataArr) . "\r\n"
                . "Cookie: " . $cookies."\r\n"
            'content' => $postdataStr
            )
        );

$context = stream_context_create($context_options);
$HTTPSReq = file_get_contents('https://www.example.com/', false, $context);
于 2009-05-05T08:07:52.543 回答
0

您正在测试网关安全通信的网络托管公司可能存在问题,他们可能不允许您这样做。

在连接到远程主机之前,可能还必须提供用户名、密码。

或者您的 IP 可能需要在远程服务器的批准 IP 列表中才能启动通信。

于 2008-11-25T03:36:32.643 回答
0

我在最近的一个应用程序项目中发现了这个错误。我正在写从命令行或浏览器窗口运行,所以我使用服务器检测来获取我要求的文档的相对 URL。问题是,该站点是 https,每次我尝试访问http://(同一服务器)时,cURL 都会将其更改为 https。

这在浏览器中运行良好,但在命令行中,即使两者都将验证设置为 false,我也会收到 SSL 错误。我必须做的是,

1) 检查 $_SERVER['HTTP_HOST']。如果存在,请使用 ($_SERVER['HTTPS'] ? "https://" : "http://").$_SERVER['HTTP_HOST']

2) 检查$_SERVER['COMPUTERNAME'],如果匹配生产服务器,提供https URL。(" https://(服务器名) ")

3)如果两个条件都没有通过,这意味着我在不同的服务器上运行命令行,并使用“ http://localhost ”。

现在,这行得通,但它是一个黑客。此外,我从来没有弄清楚为什么在一台服务器(https)上 cURL 更改了我的 URL,而在另一台服务器(也是 https)上,它只留下了我的 URL。

奇怪的。

于 2009-10-06T17:32:04.450 回答
0

使用 https 并避免安全问题的最佳方法是使用 Firefox(或其他工具)并将证书下载到您的服务器。这个网页对我帮助很大,这些是对我有用的步骤:

1) 在 Firefox 中打开您要与 CURL 一起使用的 URL

2)在地址栏点击padlock> more information(FF版本可以有不同的菜单,找到它就行了)。单击View certificate按钮 >Details选项卡。

3) 突出显示中的“正确”证书Certificate hierarchy。就我而言,它是三个中的第二个,称为“cPanel, Inc. 证书颁发机构”。我刚刚通过“反复试验”方法找到了正确的方法。

4) 单击Export按钮。在我的情况下,工作的是文件类型“带链的 PEM”(同样通过试错法)。

5) 然后在你的 PHP 脚本中添加:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);    
curl_setopt($ch, CURLOPT_CAINFO, [PATH_TO_CRT_FILE]);

另外我要说的是,我们必须注意这些步骤可能需要每年重做一次,或者每当更换或更新 URL 证书时。

于 2017-09-10T08:50:54.067 回答
-1

您正在使用 POST 方法,但您是否提供了一组数据?例如

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
于 2008-11-25T02:33:13.410 回答