Merge "Revert "Use display name in category page subheadings if provided""
[lhc/web/wiklou.git] / includes / libs / MultiHttpClient.php
index 0371f24..f0b44a5 100644 (file)
@@ -35,6 +35,8 @@
  *                use application/x-www-form-urlencoded (headers sent automatically)
  *   - stream   : resource to stream the HTTP response body to
  *   - proxy    : HTTP proxy to use
+ *   - flags    : map of boolean flags which supports:
+ *                  - relayResponseHeaders : write out header via header()
  * Request maps can use integer index 0 instead of 'method' and 1 instead of 'url'.
  *
  * @author Aaron Schulz
@@ -172,6 +174,7 @@ class MultiHttpClient {
                                $req['body'] = '';
                                $req['headers']['content-length'] = 0;
                        }
+                       $req['flags'] = isset( $req['flags'] ) ? $req['flags'] : [];
                        $handles[$index] = $this->getCurlHandle( $req, $opts );
                        if ( count( $reqs ) > 1 ) {
                                // https://github.com/guzzle/guzzle/issues/349
@@ -181,14 +184,12 @@ class MultiHttpClient {
                unset( $req ); // don't assign over this by accident
 
                $indexes = array_keys( $reqs );
-               if ( function_exists( 'curl_multi_setopt' ) ) { // PHP 5.5
-                       if ( isset( $opts['usePipelining'] ) ) {
-                               curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$opts['usePipelining'] );
-                       }
-                       if ( isset( $opts['maxConnsPerHost'] ) ) {
-                               // Keep these sockets around as they may be needed later in the request
-                               curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$opts['maxConnsPerHost'] );
-                       }
+               if ( isset( $opts['usePipelining'] ) ) {
+                       curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$opts['usePipelining'] );
+               }
+               if ( isset( $opts['maxConnsPerHost'] ) ) {
+                       // Keep these sockets around as they may be needed later in the request
+                       curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$opts['maxConnsPerHost'] );
                }
 
                // @TODO: use a per-host rolling handle window (e.g. CURLMOPT_MAX_HOST_CONNECTIONS)
@@ -214,7 +215,7 @@ class MultiHttpClient {
                                // Wait (if possible) for available work...
                                if ( $active > 0 && $mrc == CURLM_OK ) {
                                        if ( curl_multi_select( $chm, 10 ) == -1 ) {
-                                               // PHP bug 63411; http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
+                                               // PHP bug 63411; https://curl.haxx.se/libcurl/c/curl_multi_fdset.html
                                                usleep( 5000 ); // 5ms
                                        }
                                }
@@ -255,10 +256,8 @@ class MultiHttpClient {
                unset( $req ); // don't assign over this by accident
 
                // Restore the default settings
-               if ( function_exists( 'curl_multi_setopt' ) ) { // PHP 5.5
-                       curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$this->usePipelining );
-                       curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
-               }
+               curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$this->usePipelining );
+               curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
 
                return $reqs;
        }
@@ -289,12 +288,7 @@ class MultiHttpClient {
                curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
 
                $url = $req['url'];
-               // PHP_QUERY_RFC3986 is PHP 5.4+ only
-               $query = str_replace(
-                       [ '+', '%7E' ],
-                       [ '%20', '~' ],
-                       http_build_query( $req['query'], '', '&' )
-               );
+               $query = http_build_query( $req['query'], '', '&', PHP_QUERY_RFC3986 );
                if ( $query != '' ) {
                        $url .= strpos( $req['url'], '?' ) === false ? "?$query" : "&$query";
                }
@@ -348,7 +342,7 @@ class MultiHttpClient {
                                // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
                                // is an array, but not if it's a string. So convert $req['body'] to a string
                                // for safety.
-                               $req['body'] = wfArrayToCgi( $req['body'] );
+                               $req['body'] = http_build_query( $req['body'] );
                        }
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, $req['body'] );
                } else {
@@ -373,6 +367,9 @@ class MultiHttpClient {
 
                curl_setopt( $ch, CURLOPT_HEADERFUNCTION,
                        function ( $ch, $header ) use ( &$req ) {
+                               if ( !empty( $req['flags']['relayResponseHeaders'] ) ) {
+                                       header( $header );
+                               }
                                $length = strlen( $header );
                                $matches = [];
                                if ( preg_match( "/^(HTTP\/1\.[01]) (\d{3}) (.*)/", $header, $matches ) ) {
@@ -416,10 +413,8 @@ class MultiHttpClient {
        protected function getCurlMulti() {
                if ( !$this->multiHandle ) {
                        $cmh = curl_multi_init();
-                       if ( function_exists( 'curl_multi_setopt' ) ) { // PHP 5.5
-                               curl_multi_setopt( $cmh, CURLMOPT_PIPELINING, (int)$this->usePipelining );
-                               curl_multi_setopt( $cmh, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
-                       }
+                       curl_multi_setopt( $cmh, CURLMOPT_PIPELINING, (int)$this->usePipelining );
+                       curl_multi_setopt( $cmh, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
                        $this->multiHandle = $cmh;
                }
                return $this->multiHandle;