MediaWiki REL1_37
HttpRequestFactory.php
Go to the documentation of this file.
1<?php
21
23use GuzzleHttp\Client;
25use Http;
31use Profiler;
32use Psr\Log\LoggerInterface;
33use RuntimeException;
34use Status;
35
41 private $options;
43 private $logger;
44
48 public const CONSTRUCTOR_OPTIONS = [
49 'HTTPTimeout',
50 'HTTPConnectTimeout',
51 'HTTPMaxTimeout',
52 'HTTPMaxConnectTimeout',
53 ];
54
55 public function __construct( ServiceOptions $options, LoggerInterface $logger ) {
56 $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
57 $this->options = $options;
58 $this->logger = $logger;
59 }
60
97 public function create( $url, array $options = [], $caller = __METHOD__ ) {
98 if ( !Http::$httpEngine ) {
99 Http::$httpEngine = 'guzzle';
100 }
101
102 if ( !isset( $options['logger'] ) ) {
103 $options['logger'] = $this->logger;
104 }
105 $options['timeout'] = $this->normalizeTimeout(
106 $options['timeout'] ?? null,
107 $options['maxTimeout'] ?? null,
108 $this->options->get( 'HTTPTimeout' ),
109 $this->options->get( 'HTTPMaxTimeout' )
110 );
111 $options['connectTimeout'] = $this->normalizeTimeout(
112 $options['connectTimeout'] ?? null,
113 $options['maxConnectTimeout'] ?? null,
114 $this->options->get( 'HTTPConnectTimeout' ),
115 $this->options->get( 'HTTPMaxConnectTimeout' )
116 );
117
118 switch ( Http::$httpEngine ) {
119 case 'guzzle':
120 return new GuzzleHttpRequest( $url, $options, $caller, Profiler::instance() );
121 case 'curl':
122 return new CurlHttpRequest( $url, $options, $caller, Profiler::instance() );
123 case 'php':
124 return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
125 default:
126 throw new RuntimeException( __METHOD__ . ': The requested engine is not valid.' );
127 }
128 }
129
140 private function normalizeTimeout( $parameter, $maxParameter, $default, $maxConfigured ) {
141 if ( $parameter === 'default' || $parameter === null ) {
142 if ( !is_numeric( $default ) ) {
143 throw new \InvalidArgumentException(
144 '$wgHTTPTimeout and $wgHTTPConnectTimeout must be set to a number' );
145 }
146 $value = $default;
147 } else {
148 $value = $parameter;
149 }
150 if ( $maxParameter !== null ) {
151 $max = $maxParameter;
152 } else {
153 $max = $maxConfigured;
154 }
155 if ( $max && $value > $max ) {
156 return $max;
157 } else {
158 return $value;
159 }
160 }
161
167 public function canMakeRequests() {
168 return function_exists( 'curl_init' ) || wfIniGetBool( 'allow_url_fopen' );
169 }
170
182 public function request( $method, $url, array $options = [], $caller = __METHOD__ ) {
183 $logger = LoggerFactory::getInstance( 'http' );
184 $logger->debug( "$method: $url" );
185
186 $options['method'] = strtoupper( $method );
187
188 $req = $this->create( $url, $options, $caller );
189 $status = $req->execute();
190
191 if ( $status->isOK() ) {
192 return $req->getContent();
193 } else {
194 $errors = $status->getErrorsByType( 'error' );
195 $logger->warning( Status::wrap( $status )->getWikiText( false, false, 'en' ),
196 [ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
197 return null;
198 }
199 }
200
210 public function get( $url, array $options = [], $caller = __METHOD__ ) {
211 return $this->request( 'GET', $url, $options, $caller );
212 }
213
223 public function post( $url, array $options = [], $caller = __METHOD__ ) {
224 return $this->request( 'POST', $url, $options, $caller );
225 }
226
230 public function getUserAgent() {
231 return 'MediaWiki/' . MW_VERSION;
232 }
233
246 public function createMultiClient( $options = [] ) {
247 $options['reqTimeout'] = $this->normalizeTimeout(
248 $options['reqTimeout'] ?? $options['timeout'] ?? null,
249 $options['maxReqTimeout'] ?? $options['maxTimeout'] ?? null,
250 $this->options->get( 'HTTPTimeout' ),
251 $this->options->get( 'HTTPMaxTimeout' )
252 );
253 $options['connTimeout'] = $this->normalizeTimeout(
254 $options['connTimeout'] ?? $options['connectTimeout'] ?? null,
255 $options['maxConnTimeout'] ?? $options['maxConnectTimeout'] ?? null,
256 $this->options->get( 'HTTPConnectTimeout' ),
257 $this->options->get( 'HTTPMaxConnectTimeout' )
258 );
259 $options += [
260 'maxReqTimeout' => $this->options->get( 'HTTPMaxTimeout' ),
261 'maxConnTimeout' => $this->options->get( 'HTTPMaxConnectTimeout' ),
262 'userAgent' => $this->getUserAgent(),
263 'logger' => $this->logger
264 ];
265 return new MultiHttpClient( $options );
266 }
267
281 public function createGuzzleClient( array $config = [] ): Client {
282 $config['timeout'] = $this->normalizeTimeout(
283 $config['timeout'] ?? null,
284 $config['maxTimeout'] ?? null,
285 $this->options->get( 'HTTPTimeout' ),
286 $this->options->get( 'HTTPMaxTimeout' )
287 );
288
289 $config['connect_timeout'] = $this->normalizeTimeout(
290 $config['connect_timeout'] ?? null,
291 $config['maxConnectTimeout'] ?? null,
292 $this->options->get( 'HTTPConnectTimeout' ),
293 $this->options->get( 'HTTPMaxConnectTimeout' )
294 );
295
296 if ( !isset( $config['headers']['User-Agent'] ) ) {
297 $config['headers']['User-Agent'] = $this->getUserAgent();
298 }
299
300 return new Client( $config );
301 }
302}
const MW_VERSION
The running version of MediaWiki.
Definition Defines.php:36
wfIniGetBool( $setting)
Safety wrapper around ini_get() for boolean settings.
MWHttpRequest implemented using internal curl compiled into PHP.
MWHttpRequest implemented using the Guzzle library.
Various HTTP related functions.
Definition Http.php:28
static $httpEngine
Definition Http.php:30
This wrapper class will call out to curl (if available) or fallback to regular PHP if necessary for h...
A class for passing options to services.
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Factory creating MWHttpRequest objects.
normalizeTimeout( $parameter, $maxParameter, $default, $maxConfigured)
Given a passed parameter value, a default and a maximum, figure out the correct timeout to pass to th...
get( $url, array $options=[], $caller=__METHOD__)
Simple wrapper for request( 'GET' ), parameters have same meaning as for request()
__construct(ServiceOptions $options, LoggerInterface $logger)
createMultiClient( $options=[])
Get a MultiHttpClient with MediaWiki configured defaults applied.
post( $url, array $options=[], $caller=__METHOD__)
Simple wrapper for request( 'POST' ), parameters have same meaning as for request()
create( $url, array $options=[], $caller=__METHOD__)
Generate a new MWHttpRequest object.
createGuzzleClient(array $config=[])
Get a GuzzleHttp\Client instance.
canMakeRequests()
Simple function to test if we can make any sort of requests at all, using cURL or fopen()
request( $method, $url, array $options=[], $caller=__METHOD__)
Perform an HTTP request.
PSR-3 logger instance factory.
Class to handle multiple HTTP requests.
Profiler base class that defines the interface and some shared functionality.
Definition Profiler.php:36
static instance()
Singleton.
Definition Profiler.php:69
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:44