php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61886 cURL returns error 209
Submitted: 2012-05-01 07:36 UTC Modified: 2012-09-30 14:49 UTC
From: develop1983 at gmail dot com Assigned:
Status: Not a bug Package: cURL related
PHP Version: 5.3.11 OS: win7 x86
Private report: No CVE-ID: None
 [2012-05-01 07:36 UTC] develop1983 at gmail dot com
Description:
------------
I get these warnings:

Warning: (null)(): 209 is not a valid cURL handle resource in Unknown on line 0
Warning: (null)(): 211 is not a valid cURL handle resource in Unknown on line 0

After it the script stoped by "max_execution_time" (=300).

Test script:
---------------
// Simple script to do multiple queries
// It works in PHP 5.3.9
// It doesn't work in PHP 5.3.11, 5.4.0
// I didn't tested in 5.4.1, but I think it still exists there (because it exists in PHP 5.3.11)
// Requested URL is valid and I can get the content using the browser and with PHP 5.3.9 (i mean the cURL in PHP 5.3.9 package)

$mh = curl_multi_init();
$ch_array = array ();
// $links - Zend_Db_Table_Rowset
// $link - Zend_Db_Table_Row
foreach ($links as $key => $link) {
  $url = $link->getUrl();
  $cookies = $link->getCookies();
  $cookiejar = $this->_config->search->cookie->path . DS . $key;
  $headers = $link->getHeaders();
  $ch = curl_init($url);
  if (substr($url, 0, 8) == 'https://') {
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  }
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $link->getTimeout());
  if (!file_exists($cookiejar)) {
    if (!empty($cookies)) {
      curl_setopt($ch, CURLOPT_COOKIE, $cookies);
    }
  } else {
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiejar);
  }
  curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiejar);
  if (!empty($headers)) {
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  }
  curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  curl_setopt($ch, CURLOPT_HEADER, false);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_TIMEOUT_MS, $link->getTimeout());
  curl_setopt($ch, CURLOPT_USERAGENT, $user_agent_string);
  curl_multi_add_handle($mh, $ch);
  $ch_array[$key] = $ch;
}

do {
  $execReturnValue = curl_multi_exec($mh, $runningHandles);
} while ($execReturnValue == CURLM_CALL_MULTI_PERFORM);

while ($runningHandles && $execReturnValue == CURLM_OK) {
  if (curl_multi_select($mh) != -1) {
    do {
      $execReturnValue = curl_multi_exec($mh, $runningHandles);
      $info = curl_multi_info_read($mh);
      if ($info['msg'] == CURLMSG_DONE) {
        $ch = $info['handle'];
        if ($info['result'] == CURLM_OK) {
          // process data
        } else {
          // error
        }
        curl_multi_remove_handle($mh, $ch);
        curl_close($ch);
      }
    } while ($execReturnValue == CURLM_CALL_MULTI_PERFORM);
  }
}
curl_multi_close($mh);



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-05-01 09:23 UTC] develop1983 at gmail dot com
PHP 5.3.9 cURL version - 7.21.7
PHP 5.3.11 cURL version - 7.24.0
 [2012-05-01 09:26 UTC] pajoye@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2012-05-01 09:26 UTC] pajoye@php.net
-Status: Open +Status: Feedback
 [2012-05-01 10:50 UTC] develop1983 at gmail dot com
Test script:
-------------------------
<?php
$mh = curl_multi_init();
$ch_array = array ();
$links = array (
  'url1' => 'http://www.php.net/releases.atom',
  'url2' => 'http://www.php.net/feed.atom'
);
$user_agent_string = getenv('HTTP_USER_AGENT');
foreach ($links as $key => $url) {
  $cookies = '';
  $cookiejar = dirname(__FILE__) . '/' . $key;
  $headers = '';
  $ch = curl_init($url);
  if (substr($url, 0, 8) == 'https://') {
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  }
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 5000);
  if (!file_exists($cookiejar)) {
    if (!empty($cookies)) {
      curl_setopt($ch, CURLOPT_COOKIE, $cookies);
    }
  } else {
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiejar);
  }
  curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiejar);
  if (!empty($headers)) {
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  }
  curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  curl_setopt($ch, CURLOPT_HEADER, false);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
  curl_setopt($ch, CURLOPT_USERAGENT, $user_agent_string);
  curl_multi_add_handle($mh, $ch);
  $ch_array[$key] = $ch;
}

do {
  $execReturnValue = curl_multi_exec($mh, $runningHandles);
} while ($execReturnValue == CURLM_CALL_MULTI_PERFORM);

while ($runningHandles && $execReturnValue == CURLM_OK) {
  if (curl_multi_select($mh) != -1) {
    do {
      $execReturnValue = curl_multi_exec($mh, $runningHandles);
      $info = curl_multi_info_read($mh);
      if ($info['msg'] == CURLMSG_DONE) {
        $ch = $info['handle'];
        if ($info['result'] == CURLM_OK) {
          // process data
           echo 'process data<br />' . PHP_EOL;
        } else {
          // error
          echo 'error<br />' . PHP_EOL;
        }
        curl_multi_remove_handle($mh, $ch);
        curl_close($ch);
      }
    } while ($execReturnValue == CURLM_CALL_MULTI_PERFORM);
  }
}
curl_multi_close($mh);
?>
 [2012-05-01 10:50 UTC] develop1983 at gmail dot com
-Status: Feedback +Status: Open
 [2012-05-03 06:09 UTC] laruence@php.net
I can not reproduce it with php5.3-trunk and libcurl/7.21.6 

and I think it should not a issue of libcurl's version. 

did you use APC or Eacc? thanks
 [2012-05-03 17:17 UTC] develop1983 at gmail dot com
> I can not reproduce it with php5.3-trunk and libcurl/7.21.6 
It should work with libcurl/7.21.6 (I think), because it works with v7.21.7 (as I mentioned).
It doesn't work with cURL v7.24.0 (in PHP 5.3.11)

> and I think it should not a issue of libcurl's version. 
Hmmm... It notices cURL warnings...
And I don't think it is an issue of PHP.

> did you use APC or Eacc? thanks
I don't know. I downloaded the MSI file of PHP 5.3.11 and install the software (as I did with PHP 5.3.9 ago).
I don't use any additional softwares. Just PHP "as is" as it installed with MSI file.

Thanks.
 [2012-05-09 19:13 UTC] develop1983 at gmail dot com
Any advancements?
Have you reproduced this issue?
Or you have question?
 [2012-09-28 17:03 UTC] pierrick@php.net
I think this bug is related to Bug #61141 could you confirm ?
 [2012-09-28 17:03 UTC] pierrick@php.net
-Status: Open +Status: Feedback
 [2012-09-29 18:23 UTC] develop1983 at gmail dot com
> I think this bug is related to Bug #61141 could you confirm ?

I think you're right. The issue is the same: works with curl from the php 5.3.9 package and earlier versions and fails with later versions.

I've tested it with curl from the php 5.4.5 package. The bug slill exists.
 [2012-09-29 18:23 UTC] develop1983 at gmail dot com
-Status: Feedback +Status: Open
 [2012-09-29 23:08 UTC] pierrick@php.net
-Status: Open +Status: Not a bug
 [2012-09-29 23:08 UTC] pierrick@php.net
As mentionned in the comments of Bug #61141 this is not a bug :

Internally php curl_multi_select uses libcurl curl_multi_fdset function to set 
all the fd_set and the maxfd value. The libcurl curl_multi_fdset documentation 
says :

When libcurl returns -1 in max_fd, it is because libcurl currently does 
something that isn't possible for your application to monitor with a socket and 
unfortunately you can then not know exactly when the current action is completed 
using select(). When max_fd returns with -1, you need to wait a while and then 
proceed and call curl_multi_perform anyway. How long to wait? I would suggest 
100 milliseconds at least, but you may want to test it out in your own 
particular conditions to find a suitable value.

If you modify the script to wait some time if the curl_multi_select return -1 
and then do the curl_multi_exec it should work (it worked on my setup with both 
curl versions).
 [2012-09-30 14:49 UTC] develop1983 at gmail dot com
Thank you for your clarification. I'll try this way.
But how it works on the previos versions? Without any timeouts. And can I be sure that I wouldn't set another (bigger) timeout related with this issue (also using newer versions)?
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Wed Nov 13 15:01:28 2019 UTC