X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fhttp%2FMWHttpRequest.php;h=70691b4cff5c6ce96ff2dcd6300386e29ee34dca;hb=899f475d0dad8ea0a24f706fc8ac07e3097d6191;hp=fac052fffc1d40481aa9b12df06a0494cf4d42ea;hpb=25f2262a077c0baba12b00f18e5f4d366344b774;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/http/MWHttpRequest.php b/includes/http/MWHttpRequest.php index fac052fffc..70691b4cff 100644 --- a/includes/http/MWHttpRequest.php +++ b/includes/http/MWHttpRequest.php @@ -18,7 +18,6 @@ * @file */ -use MediaWiki\Logger\LoggerFactory; use Psr\Log\LoggerInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\NullLogger; @@ -30,11 +29,15 @@ use Psr\Log\NullLogger; * Renamed from HttpRequest to MWHttpRequest to avoid conflict with * PHP's HTTP extension. */ -class MWHttpRequest implements LoggerAwareInterface { +abstract class MWHttpRequest implements LoggerAwareInterface { const SUPPORTS_FILE_POSTS = false; - protected $content; + /** + * @var int|string + */ protected $timeout = 'default'; + + protected $content; protected $headersOnly = null; protected $postData = null; protected $proxy = null; @@ -46,7 +49,7 @@ class MWHttpRequest implements LoggerAwareInterface { protected $reqHeaders = []; protected $url; protected $parsedUrl; - /** @var callable */ + /** @var callable */ protected $callback; protected $maxRedirects = 5; protected $followRedirects = false; @@ -76,7 +79,7 @@ class MWHttpRequest implements LoggerAwareInterface { protected $profileName; /** - * @var LoggerInterface; + * @var LoggerInterface */ protected $logger; @@ -86,8 +89,8 @@ class MWHttpRequest implements LoggerAwareInterface { * @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 = [], $caller = __METHOD__, $profiler = null + public function __construct( + $url, array $options = [], $caller = __METHOD__, $profiler = null ) { global $wgHTTPTimeout, $wgHTTPConnectTimeout; @@ -125,6 +128,9 @@ class MWHttpRequest implements LoggerAwareInterface { 'Basic ' . base64_encode( $options['username'] . ':' . $options['password'] ) ); } + if ( isset( $options['originalRequest'] ) ) { + $this->setOriginalRequest( $options['originalRequest'] ); + } $members = [ "postData", "proxy", "noProxy", "sslVerifyHost", "caInfo", "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback" ]; @@ -132,7 +138,7 @@ class MWHttpRequest implements LoggerAwareInterface { foreach ( $members as $o ) { if ( isset( $options[$o] ) ) { // ensure that MWHttpRequest::method is always - // uppercased. Bug 36137 + // uppercased. T38137 if ( $o == 'method' ) { $options[$o] = strtoupper( $options[$o] ); } @@ -167,44 +173,21 @@ class MWHttpRequest implements LoggerAwareInterface { /** * Generate a new request object + * Deprecated: @see HttpRequestFactory::create * @param string $url Url to use - * @param array $options (optional) extra params to pass (see Http::request()) + * @param array|null $options (optional) extra params to pass (see Http::request()) * @param string $caller The method making this request, for profiling * @throws DomainException - * @return CurlHttpRequest|PhpHttpRequest + * @return MWHttpRequest * @see MWHttpRequest::__construct */ - public static function factory( $url, $options = null, $caller = __METHOD__ ) { - if ( !Http::$httpEngine ) { - Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php'; - } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) { - throw new DomainException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' . - ' Http::$httpEngine is set to "curl"' ); - } - - if ( !is_array( $options ) ) { + public static function factory( $url, array $options = null, $caller = __METHOD__ ) { + if ( $options === null ) { $options = []; } - - if ( !isset( $options['logger'] ) ) { - $options['logger'] = LoggerFactory::getInstance( 'http' ); - } - - switch ( Http::$httpEngine ) { - case 'curl': - return new CurlHttpRequest( $url, $options, $caller, Profiler::instance() ); - case 'php': - if ( !wfIniGetBool( 'allow_url_fopen' ) ) { - throw new DomainException( __METHOD__ . ': allow_url_fopen ' . - 'needs to be enabled for pure PHP http requests to ' . - 'work. If possible, curl should be used instead. See ' . - 'http://php.net/curl.' - ); - } - return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() ); - default: - throw new DomainException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' ); - } + return \MediaWiki\MediaWikiServices::getInstance() + ->getHttpRequestFactory() + ->create( $url, $options, $caller ); } /** @@ -580,7 +563,7 @@ class MWHttpRequest implements LoggerAwareInterface { * * Note that the multiple Location: headers are an artifact of * CURL -- they shouldn't actually get returned this way. Rewrite - * this when bug 29232 is taken care of (high-level redirect + * this when T31232 is taken care of (high-level redirect * handling rewrite). * * @return string @@ -606,19 +589,17 @@ class MWHttpRequest implements LoggerAwareInterface { } } - if ( $foundRelativeURI ) { - if ( $domain ) { - return $domain . $locations[$countLocations - 1]; - } else { - $url = parse_url( $this->url ); - if ( isset( $url['host'] ) ) { - return $url['scheme'] . '://' . $url['host'] . - $locations[$countLocations - 1]; - } - } - } else { + if ( !$foundRelativeURI ) { return $locations[$countLocations - 1]; } + if ( $domain ) { + return $domain . $locations[$countLocations - 1]; + } + $url = parse_url( $this->url ); + if ( isset( $url['host'] ) ) { + return $url['scheme'] . '://' . $url['host'] . + $locations[$countLocations - 1]; + } } return $this->url; @@ -632,4 +613,34 @@ class MWHttpRequest implements LoggerAwareInterface { public function canFollowRedirects() { return true; } + + /** + * Set information about the original request. This can be useful for + * endpoints/API modules which act as a proxy for some service, and + * throttling etc. needs to happen in that service. + * Calling this will result in the X-Forwarded-For and X-Original-User-Agent + * headers being set. + * @param WebRequest|array $originalRequest When in array form, it's + * expected to have the keys 'ip' and 'userAgent'. + * @note IP/user agent is personally identifiable information, and should + * only be set when the privacy policy of the request target is + * compatible with that of the MediaWiki installation. + */ + public function setOriginalRequest( $originalRequest ) { + if ( $originalRequest instanceof WebRequest ) { + $originalRequest = [ + 'ip' => $originalRequest->getIP(), + 'userAgent' => $originalRequest->getHeader( 'User-Agent' ), + ]; + } elseif ( + !is_array( $originalRequest ) + || array_diff( [ 'ip', 'userAgent' ], array_keys( $originalRequest ) ) + ) { + throw new InvalidArgumentException( __METHOD__ . ': $originalRequest must be a ' + . "WebRequest or an array with 'ip' and 'userAgent' keys" ); + } + + $this->reqHeaders['X-Forwarded-For'] = $originalRequest['ip']; + $this->reqHeaders['X-Original-User-Agent'] = $originalRequest['userAgent']; + } }