protected $maxConnsPerHost = 50;
/** @var string|null proxy */
protected $proxy;
+ /** @var string */
+ protected $userAgent = 'wikimedia/multi-http-client v1.0';
/**
* @param array $options
* - proxy : HTTP proxy to use
* - usePipelining : whether to use HTTP pipelining if possible (for all hosts)
* - maxConnsPerHost : maximum number of concurrent connections (per host)
+ * - userAgent : The User-Agent header value to send
* @throws Exception
*/
public function __construct( array $options ) {
}
}
static $opts = array(
- 'connTimeout', 'reqTimeout', 'usePipelining', 'maxConnsPerHost', 'proxy'
+ 'connTimeout', 'reqTimeout', 'usePipelining', 'maxConnsPerHost', 'proxy', 'userAgent'
);
foreach ( $opts as $key ) {
if ( isset( $options[$key] ) ) {
);
} elseif ( $req['method'] === 'POST' ) {
curl_setopt( $ch, CURLOPT_POST, 1 );
+ // 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'] = wfArrayToCgi( $req['body'] );
+ }
curl_setopt( $ch, CURLOPT_POSTFIELDS, $req['body'] );
} else {
if ( is_resource( $req['body'] ) || $req['body'] !== '' ) {
$req['headers']['content-length'] = 0;
}
+ if ( !isset( $req['headers']['user-agent'] ) ) {
+ $req['headers']['user-agent'] = $this->userAgent;
+ }
+
$headers = array();
foreach ( $req['headers'] as $name => $value ) {
if ( strpos( $name, ': ' ) ) {