class MultiHttpClient implements LoggerAwareInterface {
/** @var resource */
protected $multiHandle = null; // curl_multi handle
- /** @var string|null SSL certificates path */
+ /** @var string|null SSL certificates path */
protected $caBundlePath;
/** @var int */
protected $connTimeout = 10;
* - error : Any cURL error string
* The map also stores integer-indexed copies of these values. This lets callers do:
* @code
- * list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $http->run( $req );
+ * list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $http->run( $req );
* @endcode
* @param array $req HTTP request array
* @param array $opts
throw new Exception( "Request has no 'url' field set." );
}
$this->logger->debug( "{$req['method']}: {$req['url']}" );
- $req['query'] = isset( $req['query'] ) ? $req['query'] : [];
+ $req['query'] = $req['query'] ?? [];
$headers = []; // normalized headers
if ( isset( $req['headers'] ) ) {
foreach ( $req['headers'] as $name => $value ) {
$req['body'] = '';
$req['headers']['content-length'] = 0;
}
- $req['flags'] = isset( $req['flags'] ) ? $req['flags'] : [];
+ $req['flags'] = $req['flags'] ?? [];
$handles[$index] = $this->getCurlHandle( $req, $opts );
if ( count( $reqs ) > 1 ) {
// https://github.com/guzzle/guzzle/issues/349
$ch = curl_init();
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT,
- isset( $opts['connTimeout'] ) ? $opts['connTimeout'] : $this->connTimeout );
- curl_setopt( $ch, CURLOPT_PROXY, isset( $req['proxy'] ) ? $req['proxy'] : $this->proxy );
+ $opts['connTimeout'] ?? $this->connTimeout );
+ curl_setopt( $ch, CURLOPT_PROXY, $req['proxy'] ?? $this->proxy );
curl_setopt( $ch, CURLOPT_TIMEOUT,
- isset( $opts['reqTimeout'] ) ? $opts['reqTimeout'] : $this->reqTimeout );
+ $opts['reqTimeout'] ?? $this->reqTimeout );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt( $ch, CURLOPT_MAXREDIRS, 4 );
curl_setopt( $ch, CURLOPT_HEADER, 0 );
// Don't interpret POST parameters starting with '@' as file uploads, because this
// makes it impossible to POST plain values starting with '@' (and causes security
// issues potentially exposing the contents of local files).
- // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
- // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
- if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
- curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
- } elseif ( is_array( $req['body'] ) ) {
- // 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'] = http_build_query( $req['body'] );
- }
+ curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $req['body'] );
} else {
if ( is_resource( $req['body'] ) || $req['body'] !== '' ) {
/**
* @return resource
+ * @throws Exception
*/
protected function getCurlMulti() {
if ( !$this->multiHandle ) {
+ if ( !function_exists( 'curl_multi_init' ) ) {
+ throw new Exception( "PHP cURL extension missing. " .
+ "Check https://www.mediawiki.org/wiki/Manual:CURL" );
+ }
$cmh = curl_multi_init();
curl_multi_setopt( $cmh, CURLMOPT_PIPELINING, (int)$this->usePipelining );
curl_multi_setopt( $cmh, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );