php 在 SoapClient 中获取 http 标头时出错

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9403486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 06:44:15  来源:igfitidea点击:

Error fetching http headers in SoapClient

phpsoap-client

提问by Cris

I'm trying to invoke a WS over https on a remote host:remote port and I get:

我试图在远程主机上通过 https 调用 WS:remote 端口,我得到:

Error fetching http headers

获取 http 标头时出错

using the PHP5 SoapClient; I can get the list of functions by doing $client->__getFunctions()but when I call $client->myFunction(...)I always get this error.

使用 PHP5 SoapClient;我可以通过这样做来获取函数列表,$client->__getFunctions()但是当我打电话时,$client->myFunction(...)我总是得到这个错误。

I've googled and found that increasing default_socket_timeoutin php.ini should fix it, but it did not work.

我用谷歌搜索,发现增加default_socket_timeoutphp.ini 应该可以解决它,但它没有用。

Can anyone suggest me a solution?

谁能建议我一个解决方案?

EDIT: here is the code:

编辑:这是代码:

$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);
    }
}

always ends in the error.

总是以错误结束。

How do I solve the problem?

我该如何解决问题?

回答by cmbuckley

This error is often seen when the default_socket_timeoutvalue is exceeded for the SOAP response. (See this link.)

default_socket_timeout超出 SOAP 响应的值时,经常会出现此错误。(请参阅此链接。)

Note from the SoapClient constructor: the connection_timeoutoption is used for defining a timeout value for connecting to the service, not for the timeout for its response.

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

You can increase it like so:

你可以像这样增加它:

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

This should tell you if the timeout is the issue, or whether you have a different problem. Bear in mind that you should not use this as a permanent solution, but rather to see if it gets rid of the error before moving on to investigate why the SOAP service is responding so slowly. If the service is consistently this slow, you may have to consider offline/batch processing.

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

回答by Manachi

Just wanted to share the solution to this problem in my specific situation (I had identical symptoms). In my scenario it turned out to be that the ssl certificate provided by the web service was no longer trusted. It actually turned out to be due to a new firewall that the client had installed which was interfering with the SOAP request, but the end result was that the certificate was not being correctly served/trusted.

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

It was a bit difficult to track down because the SoapClient call (even with trace=1) doesn't give very helpful feedback.

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

I was able to prove the untrusted certificate by using:

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

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

I know this won't be the answer to everyone's problem, but hopefully it helps someone. Either way I think it's important to realise that the cause of this error (faultcode: "HTTP" faultstring: "Error Fetching http headers") is usually going to be a network/socket/protocol/communication issue rather than simply "not allowing enough time for the request". I can't imagine expanding the default_socket_timeout value is going to resolve this problem very often, and even if it does, surely it would be better to resolve the issue of WHY it is so slow in the first place.

我知道这不会是每个人问题的答案,但希望它可以帮助某人。无论哪种方式,我认为重要的是要意识到此错误的原因(错误代码:“HTTP”错误字符串:“获取 http 标头时出错”)通常是网络/套接字/协议/通信问题,而不仅仅是“不允许足够请求的时间”。我无法想象扩展 default_socket_timeout 值会经常解决这个问题,即使解决了,当然最好首先解决为什么它这么慢的问题。

回答by Jonathan Huet

I suppose it's too late, but I have the same problem. I try the socket timeout but it doesn't work. My problem was that the client and the server where in the same physical server. With the client code working in the same physical server , I get this error, but, with the same client code moved to my localhost, requesting the server, (client and server was executed in two differents mechines) all works fine.

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

Maybe that can help someone else!

也许这可以帮助别人!

回答by Thiago Sathler

Setting 'keep_alive'to false worked for me:

设置'keep_alive'为 false 对我有用:

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

回答by Sanjay Mohnani

I faced same problem and tried all the above solutions. Sadly nothing worked.

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

  1. Socket Timeout (Didn't work)
  2. User Agent (Didn't work)
  3. SoapClient configuration, cache_wsdland Keep-Aliveetc...
  1. 套接字超时(不起作用)
  2. 用户代理(无效)
  3. SoapClient 配置、cache_wsdlKeep-Alive等...

I solved my problem with adding the compressionheader property. This is actually required when you are expecting a response in gzipcompressed format.

我通过添加压缩标头属性解决了我的问题。当您期待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,
));

Hope it helps.

希望能帮助到你。

Good luck.

祝你好运。

回答by Marcelo Tonon Chiovatto

The configuration that has worked for me was defining at my php script the following parameters:

对我有用的配置在我的 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,
));

Please, comment.

请给出意见。

The most important parameter definition, as per my experience with this issue was

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

ini_set('default_socket_timeout', 5000);

During my tests I have defined the default_socket_timeout to 5 seconds and the error 'Error Fetching http headers' was raised instantaneously.

在我的测试中,我将 default_socket_timeout 定义为 5 秒,并且立即引发了错误“错误获取 http 标头”。

I hope it helps you!

我希望它能帮助你!

回答by humbads

None of the above techniques worked for me.

以上技术都不适合我。

When I analyzed the request header from __getLastRequestHeaders, I saw the following:

当我分析来自 __getLastRequestHeaders 的请求头时,我看到了以下内容:

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

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

The API URL I had been using was different, like www.ABC.com. I changed the API URL to www.XYZ.com/index.php/api?wsdl, and then it worked.

我一直使用的 API URL 是不同的,比如 www.ABC.com。我将 API URL 更改为 www.XYZ.com/index.php/api?wsdl,然后它就起作用了。

Both URLs returned the same WSDL from the same server, but only one allowed login.

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

回答by borq

I just wanted to add, for completeness sake, that similar to Manachi I received this message because the client certificate I was using required a passphrase and I accidentally had an extra character at the end of the passphrase. This post is just to offer up another suggestion for what to look into. If the host requires the use of a client certificate (via local_cert parameter) make sure you provide the correct path to the cert and the correct passphrase (if one is needed). If you don't, it is very likely you will see this same error message.

为了完整起见,我只想补充一点,类似于 Manachi 我收到此消息是因为我使用的客户端证书需要密码短语,而我不小心在密码短语的末尾有一个额外的字符。这篇文章只是为了提供另一个关于调查内容的建议。如果主机需要使用客户端证书(通过 local_cert 参数),请确保提供正确的证书路径和正确的密码(如果需要)。如果不这样做,您很可能会看到相同的错误消息。

回答by Mauro

I had this problem and I checked, and in my case, was the Firewall. The PHP not show the error correctly. To perform the request, the Firewall answered:

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

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

The SoapClient expects the SOAP envelope but receives a HTML code. That's why PHP responds with: "Error Fetching Http Headers" because it can not understand what he received in response. To resolve the problem, contact your network administrator to verify if there is any Firewall, NAT or proxy getting in the way and then ask them to make the necessary arrangements.

SoapClient 需要 SOAP 信封,但会收到一个 HTML 代码。这就是 PHP 响应为:“Error Fetching Http Headers”的原因,因为它无法理解他收到的响应。要解决此问题,请联系您的网络管理员以验证是否有任何防火墙、NAT 或代理妨碍,然后要求他们做出必要的安排。

回答by Matthias Kleine

Please check for the response HTTP-Header. In my case, the following header was set on the API-Site:

请检查响应 HTTP-Header。就我而言,API-Site 上设置了以下标头:

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

It seems like the PHP SoapClient can't deal with that option.As a result, the response body was empty, but content-length in the response-header has been set correctly.

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

Remove that line or change it to "close" solved my issue.

删除该行或将其更改为“关闭”解决了我的问题。