Fix curl_exec freeze on Windows 8 apache

I've been researching and experimenting with this problem for a while now and haven't found a workable solution yet, so I think it's time to ask for help.

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

  • Processor: Intel Core I7
  • RAM: 64 GB
  • 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 detects 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 you can see, I've tried this with both GET and POST and both give the same results. The timeout options listed above exist so the script will not run indefinitely. I had this hang for over 3 hours before I stopped the Apache service to stop the hang (just canceling in the browser won't do it). The exit from the script looks like this:

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 find a better way to format, sorry)

Also there are several virtual machines on this same machine, each with different OS / Server / PHP versions, and they all have exactly the same physical document root that is on the host machine. These machines range from Windows 7 / IIS to CentOS / Apache 2.2 and other combinations, and they all, without exception, run the same script without issue and output the expected XML document. If I only run the url in a web browser, the output looks like this:

<?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 also took the aforementioned XML output and saved it to a file, and the problem script was making a cURL call on the url for that saved XML file, and the script runs without problem at that point, so I also created a layout script that only creates a SimpleXMLElement object. fills in a few new tags and then outputs the result asXML () from the created object (essentially what chat_start.php does, but much less complicated) and I get the same problem. The layout script code is given 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 am pretty much here. I changed PHP versions, Apache versions, tried countless suggestions I found here on SO for other cURL freezing problems as found here , here and here , among two 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 not to interfere with the Windows 8 platform?

+2


source to share


1 answer


Well, it looks like I finally got to the root of the problem. It looks like when you make a cURL call to the same server as the script that is making the call, and if both the "caller" and "callee" scripts try to use the same session id, a deadlock occurs, causing both scripts to wait. until another releases the session. I ended up adding a test to see if the session id is already in use, and if so, the calling script does not start the session. If there is no session id, then the caller starts a session, gets the session id, and then crashes the session, which allows unrestricted access to the callee script, thereby eliminating 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 this will be helpful to others in the future.

+1


source







All Articles