* 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
$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
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)
// 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
}
}
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;
}
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";
}
// 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 {
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 ) ) {
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;