Fix MultiHttpClient to return correct errors
[lhc/web/wiklou.git] / includes / libs / MultiHttpClient.php
index 8e5c17d..f5d6fe4 100644 (file)
@@ -90,9 +90,9 @@ class MultiHttpClient {
         *   - body    : HTTP response body or resource (if "stream" was set)
         *   - error     : Any cURL error string
         * The map also stores integer-indexed copies of these values. This lets callers do:
-        *      <code>
+        * @code
         *              list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $http->run( $req );
-        *  </code>
+        * @endcode
         * @param array $req HTTP request array
         * @param array $opts
         *   - connTimeout    : connection timeout per request (seconds)
@@ -114,9 +114,9 @@ class MultiHttpClient {
         *   - body    : HTTP response body or resource (if "stream" was set)
         *   - error   : Any cURL error string
         * The map also stores integer-indexed copies of these values. This lets callers do:
-        *    <code>
+        * @code
         *        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $req['response'];
-        *  </code>
+        * @endcode
         * All headers in the 'headers' field are normalized to use lower case names.
         * This is true for the request headers and the response headers. Integer-indexed
         * method/URL entries will also be changed to use the corresponding string keys.
@@ -189,6 +189,7 @@ class MultiHttpClient {
 
                // @TODO: use a per-host rolling handle window (e.g. CURLMOPT_MAX_HOST_CONNECTIONS)
                $batches = array_chunk( $indexes, $this->maxConnsPerHost );
+               $infos = array();
 
                foreach ( $batches as $batch ) {
                        // Attach all cURL handles for this batch
@@ -201,6 +202,10 @@ class MultiHttpClient {
                                // Do any available work...
                                do {
                                        $mrc = curl_multi_exec( $chm, $active );
+                                       $info = curl_multi_info_read( $chm );
+                                       if ( $info !== false ) {
+                                               $infos[(int)$info['handle']] = $info;
+                                       }
                                } while ( $mrc == CURLM_CALL_MULTI_PERFORM );
                                // Wait (if possible) for available work...
                                if ( $active > 0 && $mrc == CURLM_OK ) {
@@ -216,10 +221,18 @@ class MultiHttpClient {
                foreach ( $reqs as $index => &$req ) {
                        $ch = $handles[$index];
                        curl_multi_remove_handle( $chm, $ch );
-                       if ( curl_errno( $ch ) !== 0 ) {
-                               $req['response']['error'] = "(curl error: " .
-                                       curl_errno( $ch ) . ") " . curl_error( $ch );
+
+                       $info = $infos[(int)$ch];
+
+                       $errno = $info['result'];
+                       if ( $errno !== 0 ) {
+                               $req['response']['error'] = "(curl error: $errno)";
+
+                               if ( version_compare( PHP_VERSION, '5.5.0' ) >= 0 ) {
+                                       $req['response']['error'] .= " " . curl_strerror( $errno );
+                               }
                        }
+
                        // For convenience with the list() operator
                        $req['response'][0] = $req['response']['code'];
                        $req['response'][1] = $req['response']['reason'];