简体   繁体   English

在 SoapClient 中获取 http 标头时出错

[英]Error fetching http headers in SoapClient

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;使用 PHP5 SoapClient; I can get the list of functions by doing $client->__getFunctions() but when I call $client->myFunction(...) I always get this error.我可以通过执行$client->__getFunctions()来获取函数列表,但是当我调用$client->myFunction(...)我总是收到此错误。

I've googled and found that increasing default_socket_timeout in php.ini should fix it, but it did not work.我用谷歌搜索,发现在 php.ini 中增加default_socket_timeout应该可以解决它,但它没有用。

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?我该如何解决问题?

This error is often seen when the default_socket_timeout value is exceeded for the SOAP response.当超过 SOAP 响应的default_socket_timeout值时,经常会出现此错误。 ( See this link .) 请参阅此链接。)

Note from the SoapClient constructor: the connection_timeout option 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.请记住,您不应将其用作永久解决方案,而应在继续调查 SOAP 服务响应如此缓慢的原因之前查看它是否消除了错误。 If the service is consistently this slow, you may have to consider offline/batch processing.如果服务一直这么慢,您可能需要考虑离线/批处理。

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.在我的场景中,事实证明 Web 服务提供的 ssl 证书不再受信任。 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.事实证明,这是由于客户端安装的新防火墙干扰了 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".无论哪种方式,我认为重要的是要意识到此错误的原因(错误代码:“HTTP”错误字符串:“获取 http 标头时出错”)通常是网络/套接字/协议/通信问题,而不仅仅是“不允许足够请求的时间”。 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.我无法想象扩展 default_socket_timeout 值会经常解决这个问题,即使解决了,当然最好首先解决为什么它这么慢的问题。

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!也许这可以帮助别人!

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_wsdl and Keep-Alive etc... SoapClient 配置、 cache_wsdlKeep-Alive等...

I solved my problem with adding the compression header property.我通过添加压缩标头属性解决了我的问题。 This is actually required when you are expecting a response in gzip compressed 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.祝你好运。

'keep_alive'设置为 false 对我'keep_alive'

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

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!我希望它能帮助你!

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.为了完整起见,我只是想补充一点,类似于 Manachi 我收到此消息是因为我使用的客户端证书需要一个密码短语,而我不小心在密码短语的末尾有一个额外的字符。 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).如果主机需要使用客户端证书(通过 local_cert 参数),请确保提供正确的证书路径和正确的密码(如果需要)。 If you don't, it is very likely you will see this same error message.如果不这样做,您很可能会看到相同的错误消息。

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

The API URL I had been using was different, like www.ABC.com.我一直使用的 API URL 是不同的,比如 www.ABC.com。 I changed the API URL to www.XYZ.com/index.php/api?wsdl, and then it worked.我将 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,但只允许登录一个。

I had this problem and I checked, and in my case, was the Firewall.我遇到了这个问题,我检查了,就我而言,是防火墙。 The PHP not show the error correctly. PHP 没有正确显示错误。 To perform the request, the Firewall answered:为了执行请求,防火墙回答:

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. SoapClient 需要 SOAP 信封,但会收到一个 HTML 代码。 That's why PHP responds with: "Error Fetching Http Headers" because it can not understand what he received in response.这就是 PHP 响应为:“Error Fetching Http Headers”的原因,因为它无法理解他收到的响应。 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.要解决此问题,请联系您的网络管理员以验证是否有任何防火墙、NAT 或代理妨碍,然后要求他们做出必要的安排。

Please check for the response HTTP-Header.请检查响应 HTTP-Header。 In my case, the following header was set on the API-Site:就我而言,API-Site 上设置了以下标头:

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

It seems like the PHP SoapClient can't deal with that option.似乎 PHP SoapClient 无法处理该选项。 As a result, the response body was empty, but content-length in the response-header has been set correctly.结果,响应正文为空,但响应标头中的内容长度已正确设置。

Remove that line or change it to "close" solved my issue.删除该行或将其更改为“关闭”解决了我的问题。

I had the same issue and tried the following by disabling keep_alive .我遇到了同样的问题,并通过禁用keep_alive尝试了以下keep_alive

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

However, that didn't work for me.然而,这对我不起作用。 What worked worked for me was disabling the SOAP cache.对我有用的是禁用 SOAP 缓存。 It appears to have been caching the wrong requests and after disabling I actually noticed my requests were executing faster.它似乎缓存了错误的请求,在禁用后我实际上注意到我的请求执行得更快。

On a linux server you can find this in your /etc/php.ini file.在 Linux 服务器上,您可以在/etc/php.ini文件中找到它。

Look for soap.wsdl_cache_enabled=1 and change it to soap.wsdl_cache_enabled=0 .查找soap.wsdl_cache_enabled=1并将其更改为soap.wsdl_cache_enabled=0

Don't forget to reload apache.不要忘记重新加载apache。 service httpd reload

Another possible cause of this error could be some OpenSSL operations leaving not cleared errors.此错误的另一个可能原因可能是某些 OpenSSL 操作留下未清除的错误。 Put this piece of code before the SOAP request to clear them:将这段代码放在 SOAP 请求之前以清除它们:

while (openssl_error_string()) {}

I got this same error and in my case the server I was sending the request to was replying with a 504 Gateway Time-out error.我遇到了同样的错误,在我的情况下,我向其发送请求的服务器正在回复504 网关超时错误。 I didn't realize this until I went to the URL in a browser that was being requested by the SOAP request:直到我转到 SOAP 请求所请求的浏览器中的 URL 时,我才意识到这一点:

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

We encountered Error fetching http headers on every second call of SoapClient::__soapCall(,) .我们在每第二次调用SoapClient::__soapCall(,)遇到Error fetching http headers However, not every soap endpoint/soap server was affected.但是,并非每个soap 端点/soap 服务器都受到影响。

It turned out that switching to http was working reliably for all servers, but connections via https /secure HTTP showed above symptoms.事实证明,所有服务器都可以可靠地切换到http ,但是通过https /secure HTTP 的连接显示出上述症状。 The openssl_error_string() as suggested by Furgas did not return any errors. openssl_error_string()建议openssl_error_string()没有返回任何错误。

It turned out that the misbehaving soap servers sent a HTTP-header with every response which lead to the soap client choking on the second soap call: Connection: Upgrade, close .事实证明,行为不端的soap服务器在每个响应中都发送了一个HTTP头,这导致soap客户端在第二次soap调用时窒息: Connection: Upgrade, close The well-behaving servers did not send a Upgrade on successive responses.行为良好的服务器不会对连续响应发送升级

What worked for us:什么对我们有用:

  • setting keep_alive to false, as mentioned by Thiago正如蒂亚戈所说,keep_alive设置为 false
  • unsetting the Upgrade- and Connection-headers via .htaccess files通过 .htaccess 文件取消设置升级和连接头

Although the well-behaving soap servers did not need any of this, the misbehaving once needed both the keep_alive set to false and the unsetting of the headers.尽管行为良好的肥皂服务器不需要任何这些,但行为不端曾经需要将 keep_alive 设置为 false 并取消设置标头。

# .htaccess
Header unset Upgrade
Header unset Connection

The root-cause is still unclear, but there is a bug report at Apache regarding Upgrade headers when using HTTPS.根本原因尚不清楚,但Apache 上有一个关于使用 HTTPS 时升级标头的错误报告

In recent releases from Zend SOAP client not having "connection_timeout" and "Keep_alive" parameters at all.在 Zend SOAP 客户端的最新版本中,根本没有“connection_timeout”和“Keep_alive”参数。

在此处输入图片说明

You can see the piece of code I have attached as an image.您可以看到我作为图像附加的代码段。 The only way to solve this issue to increase your default socket timeout in php.ini解决此问题的唯一方法是增加 php.ini 中的默认套接字超时

default_socket_timeout = 1000

I hope it will solve your issue.我希望它能解决你的问题。 Give an upvote if it works.如果有效就给个赞吧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM