无法使用cURL连接到HTTPS站点。返回0长度内容。我能做什么?

时间:2008-11-25 01:23:45

标签: php curl https

我有一个使用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

我也尝试了不同的网站cURL,他们返回的内容很好。我认为问题可能与https连接有关。

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

是否有其他人遇到此错误并知道解决方法?我应该抛弃cURL并尝试使用fsockopen()吗?

谢谢。 :)

12 个答案:

答案 0 :(得分:98)

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

的HTTPS证书

从以下网址获取新内容:

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

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

并添加

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

对每个请求: - )

IGNORE关于禁用CURLOPT_VERIFYPEER和CURLOPT_VERIFYHOST的任何愚蠢的评论!!这使得你的代码在中间攻击时容易受到攻击!

2016年12月编辑:

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

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

2017年10月编辑:

现在有一个作曲家软件包可以帮助您管理ca证书,这样如果您的cacert.pem由于撤销证书而过时,您就不会受到攻击。

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

答案 1 :(得分:33)

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

http://www.php.net/curl_error

答案 2 :(得分:28)

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

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

只需添加它们即可。有用。

答案 3 :(得分:6)

刚出现一个非常相似的问题并通过添加

解决了这个问题
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

显然我正在抓取的网站重定向到另一个位置,并且php-curl默认不遵循重定向。

答案 4 :(得分:4)

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

curl_setopt($ch, CURLOPT_SSLVERSION, 3);

答案 5 :(得分:3)

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

答案 6 :(得分:2)

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

答案 7 :(得分:1)

我使用file_get_contents使用stream_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);

答案 8 :(得分:0)

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

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

或您的IP可能需要位于远程服务器的已批准IP列表中,以便启动通信。

答案 9 :(得分:0)

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

这可以在浏览器中正常工作,但是从命令行开始,即使将两个verify设置为false,我也会收到SSL错误。我必须做的是,

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

2)检查$ _SERVER ['COMPUTERNAME'],如果它与生产服务器匹配,请提供https URL。 ( “https://(servername)”)

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

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

怪异。

答案 10 :(得分:0)

使用https并避免安全问题的最佳方法是使用Firefox(或其他工具)并将证书下载到您的服务器。 This webpage helped me a lot,这些是对我有用的步骤:

1)在Firefox中打开您将与CURL一起使用的网址

2)在地址栏上点击padlock&gt; more information(FF版本可以有不同的菜单,只需找到它)。单击查看证书按钮&gt; Details标签。

3)突出显示&#34;右&#34; Certificate hierarchy中的证书。就我而言,它是三分之二,名为&#34; cPanel,Inc。Certification Authority&#34;。我刚刚通过&#34;试验和错误发现了正确的#34;方法

4)单击导出按钮。在我的情况下,工作的人是文件类型&#34; PEM with chains&#34; (再次通过反复试验法)。

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证书时。

答案 11 :(得分:-1)

您正在使用POST方法,但是您提供了一组数据吗? E.g。

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);