} else {
$errors = $status->getErrorsByType( 'error' );
$logger = LoggerFactory::getInstance( 'http' );
- $logger->warning( $status->getWikiText(), array( 'caller' => $caller ) );
+ $logger->warning( $status->getWikiText(),
+ array( 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ) );
return false;
}
}
* @param string $caller The method making this request, for profiling
* @param Profiler $profiler An instance of the profiler for profiling, or null
*/
- protected function __construct( $url, $options = array(), $caller = __METHOD__, $profiler = null ) {
+ protected function __construct(
+ $url, $options = array(), $caller = __METHOD__, $profiler = null
+ ) {
global $wgHTTPTimeout, $wgHTTPConnectTimeout;
$this->url = wfExpandUrl( $url, PROTO_HTTP );
$this->curlOptions[CURLOPT_HEADER] = true;
} elseif ( $this->method == 'POST' ) {
$this->curlOptions[CURLOPT_POST] = true;
- $this->curlOptions[CURLOPT_POSTFIELDS] = $this->postData;
+ $postData = $this->postData;
+ // 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' ) ) {
+ $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
+ } elseif ( is_array( $postData ) ) {
+ // 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.
+ $postData = wfArrayToCgi( $postData );
+ }
+ $this->curlOptions[CURLOPT_POSTFIELDS] = $postData;
+
// Suppress 'Expect: 100-continue' header, as some servers
// will reject it with a 417 and Curl won't auto retry
// with HTTP 1.0 fallback
}
/**
- * Returns an array with a 'capath' or 'cafile' key that is suitable to be merged into the 'ssl' sub-array of a
- * stream context options array. Uses the 'caInfo' option of the class if it is provided, otherwise uses the system
+ * Returns an array with a 'capath' or 'cafile' key
+ * that is suitable to be merged into the 'ssl' sub-array of
+ * a stream context options array.
+ * Uses the 'caInfo' option of the class if it is provided, otherwise uses the system
* default CA bundle if PHP supports that, or searches a few standard locations.
* @return array
* @throws DomainException
if ( $this->caInfo ) {
$certLocations = array( 'manual' => $this->caInfo );
} elseif ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
+ // @codingStandardsIgnoreStart Generic.Files.LineLength
// Default locations, based on
// https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
- // PHP 5.5 and older doesn't have any defaults, so we try to guess ourselves. PHP 5.6+ gets the CA location
- // from OpenSSL as long as it is not set manually, so we should leave capath/cafile empty there.
+ // PHP 5.5 and older doesn't have any defaults, so we try to guess ourselves.
+ // PHP 5.6+ gets the CA location from OpenSSL as long as it is not set manually,
+ // so we should leave capath/cafile empty there.
+ // @codingStandardsIgnoreEnd
$certLocations = array_filter( array(
getenv( 'SSL_CERT_DIR' ),
getenv( 'SSL_CERT_PATH' ),
}
/**
- * Custom error handler for dealing with fopen() errors. fopen() tends to fire multiple errors in succession, and the last one
- * is completely useless (something like "fopen: failed to open stream") so normal methods of handling errors programmatically
+ * Custom error handler for dealing with fopen() errors.
+ * fopen() tends to fire multiple errors in succession, and the last one
+ * is completely useless (something like "fopen: failed to open stream")
+ * so normal methods of handling errors programmatically
* like get_last_error() don't work.
*/
public function errorHandler( $errno, $errstr ) {
'ssl' => array(
'verify_peer' => $this->sslVerifyCert,
'SNI_enabled' => true,
+ 'ciphers' => 'HIGH:!SSLv2:!SSLv3:-ADH:-kDH:-kECDH:-DSS',
+ 'disable_compression' => true,
),
);