MediaWiki  master
HttpRequestFactory.php
Go to the documentation of this file.
1 <?php
20 namespace MediaWiki\Http;
21 
22 use CurlHttpRequest;
23 use GuzzleHttp\Client;
25 use Http;
28 use MultiHttpClient;
29 use MWHttpRequest;
30 use PhpHttpRequest;
31 use Profiler;
32 use Psr\Log\LoggerInterface;
33 use RuntimeException;
34 use 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__ ) {
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 }
MultiHttpClient
Class to handle multiple HTTP requests.
Definition: MultiHttpClient.php:55
Http\$httpEngine
static $httpEngine
Definition: Http.php:30
Profiler\instance
static instance()
Singleton.
Definition: Profiler.php:69
MediaWiki\Http\HttpRequestFactory\canMakeRequests
canMakeRequests()
Simple function to test if we can make any sort of requests at all, using cURL or fopen()
Definition: HttpRequestFactory.php:167
MediaWiki\Logger\LoggerFactory\getInstance
static getInstance( $channel)
Get a named logger instance from the currently configured logger factory.
Definition: LoggerFactory.php:92
MediaWiki\Http\HttpRequestFactory
Factory creating MWHttpRequest objects.
Definition: HttpRequestFactory.php:39
MediaWiki\Http\HttpRequestFactory\createMultiClient
createMultiClient( $options=[])
Get a MultiHttpClient with MediaWiki configured defaults applied.
Definition: HttpRequestFactory.php:246
MediaWiki\Http
Definition: HttpRequestFactory.php:20
MW_VERSION
const MW_VERSION
The running version of MediaWiki.
Definition: Defines.php:36
CurlHttpRequest
MWHttpRequest implemented using internal curl compiled into PHP.
Definition: CurlHttpRequest.php:24
MediaWiki\Http\HttpRequestFactory\createGuzzleClient
createGuzzleClient(array $config=[])
Get a GuzzleHttp\Client instance.
Definition: HttpRequestFactory.php:281
MediaWiki\Http\HttpRequestFactory\$logger
LoggerInterface $logger
Definition: HttpRequestFactory.php:43
MediaWiki\Http\HttpRequestFactory\__construct
__construct(ServiceOptions $options, LoggerInterface $logger)
Definition: HttpRequestFactory.php:55
MediaWiki\Http\HttpRequestFactory\getUserAgent
getUserAgent()
Definition: HttpRequestFactory.php:230
Status
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:44
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:27
MediaWiki\Http\HttpRequestFactory\request
request( $method, $url, array $options=[], $caller=__METHOD__)
Perform an HTTP request.
Definition: HttpRequestFactory.php:182
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
Config\get
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
Status\wrap
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
Definition: Status.php:62
GuzzleHttpRequest
MWHttpRequest implemented using the Guzzle library.
Definition: GuzzleHttpRequest.php:42
Profiler
Profiler base class that defines the interface and some shared functionality.
Definition: Profiler.php:36
MWHttpRequest
This wrapper class will call out to curl (if available) or fallback to regular PHP if necessary for h...
Definition: MWHttpRequest.php:33
wfIniGetBool
wfIniGetBool( $setting)
Safety wrapper around ini_get() for boolean settings.
Definition: GlobalFunctions.php:1871
MediaWiki\Http\HttpRequestFactory\CONSTRUCTOR_OPTIONS
const CONSTRUCTOR_OPTIONS
Definition: HttpRequestFactory.php:48
MediaWiki\Http\HttpRequestFactory\post
post( $url, array $options=[], $caller=__METHOD__)
Simple wrapper for request( 'POST' ), parameters have same meaning as for request()
Definition: HttpRequestFactory.php:223
MediaWiki\Http\HttpRequestFactory\normalizeTimeout
normalizeTimeout( $parameter, $maxParameter, $default, $maxConfigured)
Given a passed parameter value, a default and a maximum, figure out the correct timeout to pass to th...
Definition: HttpRequestFactory.php:140
MediaWiki\$config
Config $config
Definition: MediaWiki.php:42
MediaWiki\Config\ServiceOptions\get
get( $key)
Definition: ServiceOptions.php:93
PhpHttpRequest
Definition: PhpHttpRequest.php:21
MediaWiki\Http\HttpRequestFactory\$options
ServiceOptions $options
Definition: HttpRequestFactory.php:41
MediaWiki\Http\HttpRequestFactory\create
create( $url, array $options=[], $caller=__METHOD__)
Generate a new MWHttpRequest object.
Definition: HttpRequestFactory.php:97
Http
Various HTTP related functions.
Definition: Http.php:28
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:71