修复curl_exec挂在Windows 8 apache [英] fixing curl_exec hangs in Windows 8 apache

查看:101
本文介绍了修复curl_exec挂在Windows 8 apache的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究和实验这个问题一段时间,还没有找到一个可行的解决方案,所以我想是时候呼吁帮助。



我有一个问题curl_exec,但只在一个特定的服务器。这里有一些背景,第一:




  • CPU:Intel Core I7

  • RAM:64GB

  • 操作系统:Windows 8.0

  • 服务器:Apache 2.4.4 x86 TS

  • PHP版本:5.5.1 x86 TS w / xDebug 2.2.3

  • cURL版本:7.30.0



<问题:

  $ input_vars =(!empty($ _ POST))? filter_input_array(INPUT_POST):array(); 
$ url ='http://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php';
$ qs ='?';
foreach($ input_vars as $ key => $ value)
{
$ qs。=$ key = $ value&;
}
$ qs = rtrim($ qs,'&');
$ url。= $ qs;
$ bot_id = $ input_vars ['bot_id'];
$ options = array(
CURLOPT_USERAGENT =>'Program O XML API',
CURLOPT_RETURNTRANSFER => true,
// CURLOPT_POST => 1,
CURLOPT_MAXREDIRS => 5,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 5,
);
$ ch = curl_init($ url);
curl_setopt_array($ ch,$ options);
// curl_setopt($ ch,CURLOPT_POSTFIELDS,$ input_vars);
$ data = curl_exec($ ch);
$ debug = curl_getinfo($ ch);
curl_close($ ch);
echo'< pre> Data =',htmlentities($ data),'< / pre>< br>';
var_dump($ debug);






与GET和POST,两者给出相同的结果。上面列出的超时选项存在,以便脚本不会无限运行。我已经挂了3个多小时,我停止Apache服务停止挂断(只是取消在浏览器不会这样做)。脚本的输出如下:

  array(size = 26)
'url'=> string'ht tp://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php?say = hello& bot_id = 1& convo_id = 78a9s39gut34lurq055in5s6r4& format = xml'(length = 141)
'content_type'= > null
'http_code'=> int 0
'header_size'=> int 0
'request_size'=> int 203
'filetime'=> int -1
'ssl_verify_result'=> int 0
'redirect_count'=> int 0
'total_time'=> float 5
'namelookup_time'=> float 0
'connect_time'=> float 0
'pretransfer_time'=> float 0
'size_upload'=> float 0
'size_download'=> float 0
'speed_download'=> float 0
'speed_upload'=> float 0
'download_content_length'=> float -1
'upload_content_length'=> float 0
'starttransfer_time'=> float 0
'redirect_time'=> float 0
'redirect_url'=> string''(length = 0)
'primary_ip'=> string'192.168.1.100'(length = 13)
'certinfo'=>
array(size = 0)
empty
'primary_port'=> int 80
'local_ip'=> string'192.168.1.100'(length = 13)
'local_port'=> int 2546

Data =






(无法找出更好的格式化方法,对不起)



在同一台计算机上也有几个虚拟机,每个都有不同的操作系统/服务器/ PHP版本,以及所有具有完全相同的物理文档根目录,位于主机上。这些机器从Windows 7 / IIS到CentOS / Apache 2.2和其他组合,并且所有这些机器无一例外地运行这个相同的脚本,没有麻烦,并输出期望的XML文档。如果我只是在网络浏览器中运行的URL,输出如下:

 <?xml version =1.0 ?> 
< program_o>
< version> 2.3.0< / version>
< status>< success> 1< / success>< / status>
< bot_id> 1< / bot_id>
< bot_name> Morti< / bot_name>
< user_id> 1< / user_id>
< user_name> Seeker< / user_name>
< chat>
< line>
< input> hello< / input>
< response>一个好的失败了,未定义。你好吗?< / response>
< / line>
< / chat>
< / program_o>






将其保存到一个文件,并且问题脚本对保存的XML文件的URL执行cURL调用,脚本在此时没有问题,所以我还创建了一个模拟脚本,只创建一个SimpleXMLElement对象,填充几个新的标签,然后echo的asXML()输出从创建的对象(本质上是conversation_start.php,但不是很复杂),我得到相同的问题。模拟脚本的代码如下:

  $ xml = new SimpleXMLElement('< program_o>< / program_o> ;'); 
$ xml-> addChild('version','2.3.0');
$ status = $ xml-> addChild('status');
$ status-> addChild('success','1');
$ xml-> addChild('bot_id','1');
$ xml-> addChild('bot_name','Morti');
$ xml-> addChild ('user_id','1');
$ xml-> addChild('user_name','Seeker');
$ chat = $ xml-> addChild('chat');
$ line = $ chat-> addChild('line');
$ line-> addChild('input','hello');
$ line-> addChild('response','and a good failed to you,undefined。How are you?
$ output = $ xml-> asXML();
header('Content-type:text / xml');
exit($ output);






。我改变了PHP版本,Apache版本,尝试了无数的建议,我在这里找到的其他问题与cURL冻结,发现在这里此处此处



现在我已经写了一本书来介绍我的问题,我不得不问:如何让cURL保持挂在Windows 8平台上?

解决方案

好吧,我似乎终于成了问题的根源。看起来当你执行cURL调用到与正在执行调用的脚本相同的服务器,如果caller和callee脚本尝试使用相同的会话id ,会发生死锁,导致两个脚本等待,直到另一个释放会话。我最后添加了一个测试,看看是否已经有一个会话ID在使用,如果是,调用脚本不启动会话。如果没有会话id,则呼叫者开始会话,获得会话id,然后销毁会话,这允许被呼叫者脚本不受约束地访问所述会话,从而消除死锁情况。下面是我用来做这个的代码:

  $ convo_id =(isset($ request_vars ['convo_id' $ request_vars ['convo_id']:get_convo_id(); 
// do stuff here
function get_convo_id()
{
session_name('Program O XML GUI');
session_start();
$ convo_id = session_id();
session_destroy();
return $ convo_id;
}






按预期工作。我真诚希望这将证明对未来的其他人有用。


I've been researching and experimenting with this problem for a while now, and have yet to find a workable solution, so I think it's time to call for help.

I've got a problem with curl_exec, but only on a specific server. Here's some background, first:

  • CPU: Intel Core I7
  • RAM: 64GB
  • OS: Windows 8.0
  • Server: Apache 2.4.4 x86 TS
  • PHP version: 5.5.1 x86 TS w/xDebug 2.2.3
  • cURL version: 7.30.0

PHP code that exhibits the problem:

$input_vars = (!empty($_POST)) ? filter_input_array(INPUT_POST) : array();
$url = 'http://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php';
$qs = '?';
foreach ($input_vars as $key => $value)
{
  $qs .= "$key=$value&";
}
$qs= rtrim($qs, '&');
$url .= $qs;
$bot_id = $input_vars['bot_id'];
$options = array(
    CURLOPT_USERAGENT => 'Program O XML API',
    CURLOPT_RETURNTRANSFER => true,
    //CURLOPT_POST => 1,
    CURLOPT_MAXREDIRS => 5,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 5,
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
//curl_setopt($ch, CURLOPT_POSTFIELDS, $input_vars);
$data = curl_exec($ch);
$debug = curl_getinfo($ch);
curl_close($ch);
echo '<pre>Data = ', htmlentities($data), '</pre><br>';
var_dump($debug);


As can be seen, I've tried this with both GET and POST, and both give the same results. The timeout options listed above are there so that the script won't run indefinately. I've had it hang for over 3 hours before I would stop the Apache service to stop the hangup (just canceling in the browser won't do it). The output from the script is as follows:

array (size=26)
  'url' => string 'ht tp://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php?say=hello&bot_id=1&convo_id=78a9s39gut34lurq055in5s6r4&format=xml' (length=141)
  'content_type' => null
  'http_code' => int 0
  'header_size' => int 0
  'request_size' => int 203
  'filetime' => int -1
  'ssl_verify_result' => int 0
  'redirect_count' => int 0
  'total_time' => float 5
  'namelookup_time' => float 0
  'connect_time' => float 0
  'pretransfer_time' => float 0
  'size_upload' => float 0
  'size_download' => float 0
  'speed_download' => float 0
  'speed_upload' => float 0
  'download_content_length' => float -1
  'upload_content_length' => float 0
  'starttransfer_time' => float 0
  'redirect_time' => float 0
  'redirect_url' => string '' (length=0)
  'primary_ip' => string '192.168.1.100' (length=13)
  'certinfo' => 
    array (size=0)
      empty
  'primary_port' => int 80
  'local_ip' => string '192.168.1.100' (length=13)
  'local_port' => int 2546

Data = 


(couldn't figure out a better way of formatting that, sorry)

Also on this same computer are several Virtual Machines, each with different OS/Server/PHP versions, and all with exactly the same physical document root, which is located on the host machine. These machines range from Windows 7/IIS to CentOS/Apache 2.2, and other combinations, and all of them, without exception, run this same script without trouble, and output the expected XML document. If I run the URL in just a web browser, the output is as follows:

<?xml version="1.0"?>
<program_o>
  <version>2.3.0</version>
  <status><success>1</success></status>
  <bot_id>1</bot_id>
  <bot_name>Morti</bot_name>
  <user_id>1</user_id>
  <user_name>Seeker</user_name>
  <chat>
    <line>
      <input>hello</input>
      <response>And a good failed to you, undefined. How are you?</response>
    </line>
  </chat>
</program_o>


I've also taken the above XML output and saved it to a file, and had the problem script perform the cURL call on the URL for that saved XML file, and the script works without a problem at that point, so I also created a mock-up script that only creates a SimpleXMLElement object, populates a few new tags, and then echo's the asXML() output from the created object (essentially what conversation_start.php does, but far less complex), and I get the same problem. The code for the mock-up script is below:

$xml = new SimpleXMLElement('<program_o></program_o>');
$xml->addChild('version', '2.3.0');
$status = $xml->addChild('status');
$status->addChild('success', '1');
$xml->addChild('bot_id', '1');
$xml->addChild('bot_name', 'Morti');
$xml->addChild('user_id', '1');
$xml->addChild('user_name', 'Seeker');
$chat = $xml->addChild('chat');
$line = $chat->addChild('line');
$line->addChild('input', 'hello');
$line->addChild('response', 'And a good failed to you, undefined. How are you?');
$output = $xml->asXML();
header('Content-type: text/xml');
exit($output);


I'm pretty much at my wits end here. I've changed PHP versions, Apache versions, tried countless suggestions that I've found here on SO to other issues with cURL freezing, as found here, here and here, among a double dozen or more others.

And now that I've written a book to present my problem, I have to ask: How can I get cURL to keep from hanging on a Windows 8 platform?

解决方案

Well, I seem to have finally gotten to the root of the problem. It seems that when you execute a cURL call to the same server as the script that is doing the calling, and if both the "caller" and the "callee" scripts are trying to use the same session id, a deadlock occurs, causing both scripts to wait till the other releases the session. I ended up adding a test to see if there's already a session id in use, and if so, the calling script doesn't start a session. If there is no session id, then the caller starts a session, obtains the session id, then destroys the session, which allows the "callee" script unfettered access to said session, thus removing the deadlock situation. Below is the code I used to do this:

$convo_id = (isset ($request_vars['convo_id'])) ? $request_vars['convo_id'] : get_convo_id();
// do stuff here
function get_convo_id()
{
  session_name('Program O XML GUI');
  session_start();
  $convo_id = session_id();
  session_destroy();
  return $convo_id;
}


Using this method, everything works as expected. I sincerely hope that this proves useful to others in the future.

这篇关于修复curl_exec挂在Windows 8 apache的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆