After searching all over, I can't understand why cURL requests issued to a remote SSL-enabled host are successful only 50% or so of the time in my case. Here's the situation: I have a sequence of cURL requests, all of them issued to a HTTPS remote host, within a single PHP script that I run using the PHP CLI. Occasionally when I run the script the requests execute successfully, but for some reason most of the times I run it I get the following error from cURL:
在搜索了一遍之后,我无法理解为什么向支持ssl的远程主机发出的cURL请求只有50%的成功。情况是这样的:我有一个cURL请求序列,所有这些请求都在我使用PHP CLI运行的一个PHP脚本中发送给HTTPS远程主机。有时,当我运行脚本时,请求会成功执行,但是出于某种原因,大多数时候我运行脚本时,都会从cURL获得以下错误:
* About to connect() to www.virginia.edu port 443 (#0)
* Trying 128.143.22.36... * connected
* Connected to www.virginia.edu (128.143.22.36) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* error:140943FC:SSL routines:SSL3_READ_BYTES:sslv3 alert bad record mac
* Closing connection #0
If I try again a few times I get the same result, but then after a few tries the requests will go through successfully. Running the script after that again results in an error, and the pattern continues. Researching the error 'alert bad record mac' didn't give me anything helpful, and I hesitate to blame it on an SSL issue since the script still runs occasionally.
如果我再试几次,就会得到相同的结果,但在尝试几次之后,请求就会成功地完成。在再次运行脚本之后,会导致错误,并且模式会继续。研究错误“警报坏记录mac”并没有给我任何帮助,而且我不愿将它归咎于SSL问题,因为脚本仍然偶尔运行。
I'm on Ubuntu Server 10.04, with php5 and php5-curl installed, as well as the latest version of openssl. In terms of cURL specific options, CURLOPT_SSL_VERIFYPEER is set to false, and both CURLOPT_TIMEOUT and CURLOPT_CONNECTTIMEOUT are set to 4 seconds. Further illustrating this problem is the fact that the same exact situation occurs on my Mac OS X dev machine - the requests only go through ~50% of the time.
我使用的是Ubuntu服务器10.04,安装了php5和php5-curl,以及最新版本的openssl。对于特定于cURL的选项,CURLOPT_SSL_VERIFYPEER设置为false, CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT都设置为4秒。进一步说明这个问题的是,同样的情况发生在我的Mac OS X dev机器上——请求只有大约50%的时间经过。
3 个解决方案
#1
3
The remote host is maybe not a real unique host. Maybe it's some sort of load balancing solution with several servers taking the incoming requests. What make me think it could be that is the 'mac error' in the error message. This could mean the remote host mac address as changed while the SSL negociation was still running. And this could explain that sometimes you do not have any problem.
远程主机可能不是真正唯一的主机。也许它是某种负载平衡解决方案,有几个服务器接收传入的请求。让我觉得可能是错误信息中的“mac错误”。这可能意味着远程主机mac地址在SSL negociation仍在运行时发生了更改。这可以解释为什么有时候你没有任何问题。
But maybe not :-) SSL problems are quite hard to find.
但也许不是:-)SSL问题很难找到。
I do not understand your answer on prefork MPM vs Worker MPM, if you run PHP in cli mode your apache MPM is not used, you're not even using apache.
我不理解你在prefork MPM和Worker MPM上的答案,如果你在cli模式下运行PHP,你就不会使用apache MPM,你甚至都不会使用apache。
#2
1
You may need this option:
您可能需要这个选项:
CURLOPT_FORBID_REUSE
CURLOPT_FORBID_REUSE
Pass a long. Set to 1 to make the next transfer explicitly close the connection when done. Normally, libcurl keeps all connections alive when done with one transfer in case a succeeding one follows that can re-use them. This option should be used with caution and only if you understand what it does. Set to 0 to have libcurl keep the connection open for possible later re-use (default behavior).
通过一个长。设置为1以使下一个传输在完成时显式关闭连接。通常,libcurl在完成一个传输时保持所有连接都是活动的,以防止后续的传输可以重用它们。这个选项应该谨慎使用,并且只有当您理解它的作用时才可以使用。将libcurl设置为0以使连接保持打开状态,以便以后可以重用(默认行为)。
#3
0
Had you tried? curl_setopt($handle, CURLOPT_SSLVERSION, 3);
你试过了吗?curl_setopt(美元处理CURLOPT_SSLVERSION 3);
#1
3
The remote host is maybe not a real unique host. Maybe it's some sort of load balancing solution with several servers taking the incoming requests. What make me think it could be that is the 'mac error' in the error message. This could mean the remote host mac address as changed while the SSL negociation was still running. And this could explain that sometimes you do not have any problem.
远程主机可能不是真正唯一的主机。也许它是某种负载平衡解决方案,有几个服务器接收传入的请求。让我觉得可能是错误信息中的“mac错误”。这可能意味着远程主机mac地址在SSL negociation仍在运行时发生了更改。这可以解释为什么有时候你没有任何问题。
But maybe not :-) SSL problems are quite hard to find.
但也许不是:-)SSL问题很难找到。
I do not understand your answer on prefork MPM vs Worker MPM, if you run PHP in cli mode your apache MPM is not used, you're not even using apache.
我不理解你在prefork MPM和Worker MPM上的答案,如果你在cli模式下运行PHP,你就不会使用apache MPM,你甚至都不会使用apache。
#2
1
You may need this option:
您可能需要这个选项:
CURLOPT_FORBID_REUSE
CURLOPT_FORBID_REUSE
Pass a long. Set to 1 to make the next transfer explicitly close the connection when done. Normally, libcurl keeps all connections alive when done with one transfer in case a succeeding one follows that can re-use them. This option should be used with caution and only if you understand what it does. Set to 0 to have libcurl keep the connection open for possible later re-use (default behavior).
通过一个长。设置为1以使下一个传输在完成时显式关闭连接。通常,libcurl在完成一个传输时保持所有连接都是活动的,以防止后续的传输可以重用它们。这个选项应该谨慎使用,并且只有当您理解它的作用时才可以使用。将libcurl设置为0以使连接保持打开状态,以便以后可以重用(默认行为)。
#3
0
Had you tried? curl_setopt($handle, CURLOPT_SSLVERSION, 3);
你试过了吗?curl_setopt(美元处理CURLOPT_SSLVERSION 3);