在SoapClient中获取http标头时出错

时间:2012-02-22 21:39:35

标签: php soap-client

我正在尝试在远程主机上调用WS over https:远程端口,我得到:

  

获取http标头时出错

使用PHP5 SoapClient;我可以通过$client->__getFunctions()获取函数列表,但是当我调用$client->myFunction(...)时,我总是会收到此错误。

我用Google搜索并发现在php.ini中增加了default_socket_timeout,但它没有用。

有人能建议我解决方案吗?

编辑:这是代码:

$wsdl="myWSDL";

$client = new SoapClient($wsdl,array('connection_timeout'=>5,'trace'=>true,'soap_version'=>SOAP_1_2));

var_dump($client->__getFunctions());

try {
    $response=$client->myFunction("1","2","3");
         } catch (SoapFault $fault) {
    var_dump($fault);
    }

}

......总是有错。

15 个答案:

答案 0 :(得分:54)

当SOAP响应超出default_socket_timeout值时,通常会出现此错误。 (See this link。)

来自SoapClient构造函数的注意事项:connection_timeout选项用于定义连接到服务的超时值,而不是用于响应的超时。

您可以像这样增加它:

ini_set('default_socket_timeout', 600); // or whatever new value you want

这应该告诉您超时是否是问题,或者您是否有其他问题。请记住,您不应该将此作为永久性解决方案,而是在继续调查为什么SOAP服务响应如此缓慢之前,先查看它是否消除了错误。如果服务一直很慢,则可能需要考虑离线/批处理。

答案 1 :(得分:10)

只是想在我的具体情况下分享这个问题的解决方案(我有相同的症状)。在我的场景中,结果证明Web服务提供的ssl证书不再受信任。它实际上是由于客户端安装的新防火墙干扰了SOAP请求,但最终结果是证书没有得到正确的服务/信任。

跟踪有点困难,因为SoapClient调用(即使trace = 1)也没有提供非常有用的反馈。

我能够使用以下方式证明不受信任的证书:

openssl s_client -connect <web service host>:<port>

我知道这不是每个人的问题的答案,但希望它可以帮助某人。无论哪种方式,我认为重要的是要意识到这个错误的原因(faultcode:“HTTP”faultstring:“Error Fetching http headers”)通常会成为网络/套接字/协议/通信问题,而不仅仅是“不允许”请求的时间“。我无法想象扩展default_socket_timeout值会经常解决这个问题,即使它确实如此,最好解决为什么它首先这么慢的问题。

答案 2 :(得分:8)

我认为为时已晚,但我遇到了同样的问题。我尝试套接字超时,但它不起作用。 我的问题是客户端和服务器在同一个物理服务器中。由于客户端代码在同一个物理服务器上工作,我收到此错误,但是,将相同的客户端代码移动到我的localhost,请求服务器(客户端和服务器在两个不同的机器中执行)一切正常。

也许这可以帮助别人!

答案 3 :(得分:4)

'keep_alive'为我工作:

new SoapClient($api_url, array('keep_alive' => false));

答案 4 :(得分:2)

对我有用的配置是在我的php脚本中定义以下参数:

ini_set('default_socket_timeout', 5000);
$client = new \SoapClient($url,array(
    'trace' =>true,
    'connection_timeout' => 5000,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'keep_alive' => false,
));

请评论。

根据我对此问题的经验,最重要的参数定义是

ini_set('default_socket_timeout', 5000);

在我的测试中,我将default_socket_timeout定义为5秒,并立即引发错误“Error Fetching http headers”。

我希望它可以帮到你!

答案 5 :(得分:2)

我遇到了同样的问题并尝试了以上所有解决方案。可悲的是没有任何工作。

  1. 套接字超时(未使用)
  2. 用户代理(未使用)
  3. SoapClient配置, cache_wsdl Keep-Alive 等。
  4. 我们传递的整个标题游戏。我通过添加压缩标头属性解决了我的问题。当您期望以 gzip 压缩格式进行响应时,这实际上需要。

    //set the Headers of Soap Client. 
    $client = new SoapClient($wsdlUrl, array(
        'trace' => true, 
        'keep_alive' => true,
        'connection_timeout' => 5000,
        'cache_wsdl' => WSDL_CACHE_NONE,
        'compression'   => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | SOAP_COMPRESSION_DEFLATE,
    ));
    

    希望它有所帮助。

    祝你好运。

答案 6 :(得分:1)

我只想添加,为了完整起见,类似于Manachi我收到此消息,因为我使用的客户端证书需要密码短语而且我在密码短语末尾意外地有一个额外的字符。这篇文章只是提供了另一个建议,以便了解什么。如果主机需要使用客户端证书(通过local_cert参数),请确保提供正确的证书路径和正确的密码(如果需要)。如果不这样做,很可能会看到同样的错误消息。

答案 7 :(得分:1)

上述技术都不适合我。

当我从__getLastRequestHeaders分析请求标头时,我看到了以下内容:

POST /index.php/api/index/index/?SID=012345 HTTP/1.1 Host: www.XYZ.com

我使用的API网址不同,例如www.ABC.com。我将API URL更改为www.XYZ.com/index.php/api?wsdl,然后就可以了。

两个URL都从同一服务器返回相同的WSDL,但只有一个允许登录。

答案 8 :(得分:0)

我遇到了这个问题,我查了一下,就我而言,是防火墙。 PHP没有正确显示错误。为了执行请求,防火墙回答:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
...
<html
...
<h1>Direct Access IP is not allowed</h1>
...
</html>

SoapClient需要SOAP信封,但会收到HTML代码。 这就是为什么PHP回应:“错误获取Http标头”,因为它无法理解他收到的响应。要解决此问题,请与您的网络管理员联系,以验证是否有任何防火墙,NAT或代理阻碍,然后让他们做出必要的安排。

答案 9 :(得分:0)

请检查HTTP-Header的响应。在我的例子中,API-Site上设置了以下标题:

<IfModule mod_headers.c>
    Header set Connection keep-alive
</IfModule>

似乎PHP SoapClient无法处理该选项。因此,响应正文为空,但响应标头中的内容长度已正确设置。

删除该行或将其更改为&#34;关闭&#34;解决了我的问题。

答案 10 :(得分:0)

我遇到了同样的问题,并通过停用keep_alive来尝试以下内容。

$api_proxy = new SoapClient($api_url, array('trace' => true, 'keep_alive' => false));

然而,这对我不起作用。对我有用的是禁用SOAP缓存。它似乎缓存了错误的请求,在禁用后我实际上注意到我的请求执行得更快。

在Linux服务器上,您可以在/etc/php.ini文件中找到它。

查找soap.wsdl_cache_enabled=1并将其更改为soap.wsdl_cache_enabled=0

不要忘记重新加载apache。 service httpd reload

答案 11 :(得分:0)

此错误的另一个可能原因可能是某些OpenSSL操作留下未清除的错误。将这段代码放在SOAP请求之前以清除它们:

while (openssl_error_string()) {}

答案 12 :(得分:0)

我遇到了同样的错误,在我的情况下,我向其发送请求的服务器正在答复 504网关超时错误。在我进入SOAP请求所要求的浏览器中的URL之前,我才意识到这一点:

例如 https://soap-request-domain-here.com/path/to/file.wsdl

答案 13 :(得分:0)

我们在每Error fetching http headers的第二次通话中遇到SoapClient::__soapCall(,)。但是,并不是每个肥皂端点/肥皂服务器都受到影响。

事实证明,切换到http可以在所有服务器上正常运行,但是通过https /安全HTTP的连接显示出上述症状。 suggested by Furgasopenssl_error_string()未返回任何错误。

事实证明,行为不当的肥皂服务器会在每个响应中发送一个HTTP标头,这会导致肥皂客户端在第二个肥皂调用中阻塞: Connection: Upgrade, close。行为良好的服务器未在连续响应中发送Upgrade

对我们有用的东西

  • keep_alive设置为false,例如mentioned by Thiago
  • 通过.htaccess文件取消升级和连接头

尽管状态良好的肥皂服务器不需要任何这些,但是行为异常一次既需要将keep_alive设置为false,也需要取消设置标头。

# .htaccess
Header unset Upgrade
Header unset Connection

根本原因尚不清楚,但是在使用HTTPS时,存在有关升级标头的bug report at Apache

答案 14 :(得分:0)

在Zend SOAP客户端的最新版本中,根本没有“ connection_timeout”和“ Keep_alive”参数。

enter image description here

您可以看到我作为图像所附的那段代码。解决此问题的唯一方法是增加php.ini中的默认套接字超时

default_socket_timeout = 1000

我希望它能解决您的问题。如果可行,请给个赞。