相同的cURL脚本在dev中工作。不能弄清楚为什么不在生产 [英] Same cURL script works in dev. Can't figure out why not in production
问题描述
这是脚本,在我的dev机器上工作:
This is the script, working on my dev machine:
$certPath = SITE_ROOT.'/certs/GoDaddyRootCertificateAuthority-G2.crt';
$options = [
CURLOPT_POST => 1,
CURLOPT_URL => 'https://uat.dwolla.com/oauth/rest/offsitegateway/checkouts',
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POSTFIELDS => json_encode(['name'=>'value']),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CAINFO => $certPath,
];
$ch = curl_init();
curl_setopt_array($ch, $options);
if( ! $result = curl_exec($ch)) $err = curl_error($ch);
curl_close($ch);
if(!$result) echo $err;
else print_r(json_decode($result,true));
echo '<br/><br/>';
readfile($certPath); //output cert on screen
echo '<br/><br/>';
没有问题。一旦我将其移动到我的生产环境,cURL连接失败,出现此错误:
No issues. Once I move it to my production environment, the cURL connection fails with this error:
SSL证书问题:无法获取本地颁发者证书
SSL certificate problem: unable to get local issuer certificate
- 打印相同的
.crt
所以我知道证书的路径不是问题。 - 两个环境都使用
PHP 5.6.23 在
Apache 2.4
- 开发机器
Win 7 x64
,prod machine isLinux CentOS 7
- The same
.crt
contents are printed, so I know the path to the certificate is not the problem. - Both environments use
PHP 5.6.23
onApache 2.4
- Dev machine is
Win 7 x64
, prod machine isLinux CentOS 7
- 在DNS缓存中找不到主机名
- 试用104.20.47.245 ...
- 已连接到uat.dwolla.com(104.20.47.245)埠443(#0)
- 已成功设置证书验证位置:
- CAfile:/path/to/GoDaddyRootCertificateAuthority-G2.crt CApath:none
- SSL证书问题:无法获取本地颁发者证书
- 关闭连接0
- Hostname was NOT found in DNS cache
- Trying 104.20.47.245...
- Connected to uat.dwolla.com (104.20.47.245) port 443 (#0)
- successfully set certificate verify locations:
- CAfile: /path/to/GoDaddyRootCertificateAuthority-G2.crt CApath: none
- SSL certificate problem: unable to get local issuer certificate
- Closing connection 0
- DNS中的主机名
- 已连接到uat.dwolla.com(104.20.48.245)端口443(# 0)
- 密码选择:ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
- 设置证书验证位置:
- CAfile:/path/to/GoDaddyRootCertificateAuthority-G2.crt
CApath:none - NPN
- SSL连接使用TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
- ...(证书详情)
- SSL证书验证确定。
- ...(更多POST细节)
- Hostname in DNS cache was stale, zapped
- Trying 104.20.48.245...
- Connected to uat.dwolla.com (104.20.48.245) port 443 (#0)
- Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
- successfully set certificate verify locations:
- CAfile: /path/to/GoDaddyRootCertificateAuthority-G2.crt
CApath: none - NPN, negotiated HTTP1.1
- SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
- Server certificate:
- ...(cert details)
- SSL certificate verify ok.
- ... (more POST details)
我不知道从哪里开始寻找原因。为什么脚本在生产中无法运行?
I don't know where to start looking for the cause. Why is the script not working in production?
更新:
感谢@ blackpen在评论中的精彩提示, CURLOPT_VERBOSE
选项用于生成连接的日志。下面是损坏的生产环境中的输出:
UPDATE:
Thanks to @blackpen's great tip in comments, I learned about the CURLOPT_VERBOSE
option used to generate a log of the connection. Here is the output in the broken production environment:
这是来自同一脚本但来自正常工作的开发环境的日志:
Here is the log from the same script, but from the working development environment:
推荐答案
我能够让脚本在两种环境下工作,只需在开发环境中使用文件替换 .crt
命名为 cacert.pem
从这里取出
I was able to get the script to work in both environments by replacing the .crt
that worked only in the dev environments with a file named cacert.pem
taken from here
我仍然不知道到底发生了什么,但我怀疑它可能与证书的格式有关。也许PHP在Windows上可以处理 .crt
,但在Linux上的PHP不能。我从最高评价的回答中获得了另一个问题的想法。
I still don't know what exactly was going on but I suspect that it may have something to do with the formatting of the certificate. Perhaps PHP on Windows could deal with the .crt
, but PHP on Linux couldn't. I got the idea from the highest rated answer on another question.
这篇关于相同的cURL脚本在dev中工作。不能弄清楚为什么不在生产的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!