21 use GuzzleHttp\Client;
22 use GuzzleHttp\HandlerStack;
23 use GuzzleHttp\MessageFormatter;
24 use GuzzleHttp\Middleware;
25 use GuzzleHttp\Psr7\Request;
27 use Psr\Http\Message\RequestInterface;
28 use Psr\Log\NullLogger;
66 if ( isset( $options[
'handler'] ) ) {
67 $this->handler = $options[
'handler'];
69 if ( isset( $options[
'sink'] ) ) {
70 $this->sink = $options[
'sink'];
110 if ( !$this->sink ) {
124 if ( !$this->status->isOK() ) {
125 return Status::wrap( $this->status );
128 if ( $this->proxy ) {
134 $this->guzzleOptions[
'version'] =
'1.1';
136 if ( !$this->followRedirects ) {
137 $this->guzzleOptions[
'allow_redirects'] =
false;
139 $this->guzzleOptions[
'allow_redirects'] = [
144 if ( $this->method ==
'POST' ) {
147 $this->guzzleOptions[
'form_params'] =
$postData;
149 $this->guzzleOptions[
'body'] =
$postData;
151 if ( !isset( $this->reqHeaders[
'Content-Type'] ) ) {
152 $this->reqHeaders[
'Content-Type'] =
'application/x-www-form-urlencoded';
159 $this->guzzleOptions[
'expect'] =
false;
162 $stack = HandlerStack::create( $this->handler );
169 $stack->remove(
'cookies' );
171 $stack->push( Middleware::mapRequest(
172 static function ( RequestInterface $request ) use ( $mwCookieJar ) {
173 $uri = $request->getUri();
174 $cookieHeader = $mwCookieJar->serializeToHttpRequest(
175 $uri->getPath() ?:
'/',
178 if ( !$cookieHeader ) {
182 return $request->withHeader(
'Cookie', $cookieHeader );
186 if ( !$this->logger instanceof NullLogger ) {
187 $stack->push( Middleware::log( $this->logger,
new MessageFormatter(
191 '[{ts}] {method} {uri} HTTP/{version} - {code} {error}'
195 $this->guzzleOptions[
'handler'] = $stack;
201 if ( $this->caInfo ) {
203 } elseif ( !$this->sslVerifyHost && !$this->sslVerifyCert ) {
204 $this->guzzleOptions[
'verify'] =
false;
207 $client =
new Client( $this->guzzleOptions );
208 $request =
new Request( $this->method, $this->url );
209 foreach ( $this->reqHeaders as $name => $value ) {
210 $request = $request->withHeader( $name, $value );
214 $response = $client->send( $request );
215 $this->headerList = $response->getHeaders();
217 $this->respVersion = $response->getProtocolVersion();
218 $this->respStatus = $response->getStatusCode() .
' ' . $response->getReasonPhrase();
219 }
catch ( GuzzleHttp\Exception\ConnectException $e ) {
227 $handlerContext = $e->getHandlerContext();
228 if ( $handlerContext[
'errno'] == CURLE_OPERATION_TIMEOUTED ) {
229 $this->status->fatal(
'http-timed-out', $this->url );
231 $this->status->fatal(
'http-curl-error', $handlerContext[
'error'] );
234 $this->status->fatal(
'http-request-error' );
236 }
catch ( GuzzleHttp\Exception\RequestException $e ) {
238 $handlerContext = $e->getHandlerContext();
239 $this->status->fatal(
'http-curl-error', $handlerContext[
'error'] );
242 $needle =
'Connection timed out';
243 if ( strpos( $e->getMessage(), $needle ) !==
false ) {
244 $this->status->fatal(
'http-timed-out', $this->url );
246 $this->status->fatal(
'http-request-error' );
249 }
catch ( GuzzleHttp\Exception\GuzzleException $e ) {
250 $this->status->fatal(
'http-internal-error' );
253 if ( $this->profiler ) {
254 $profileSection = $this->profiler->scopedProfileIn(
255 __METHOD__ .
'-' . $this->profileName
259 if ( $this->profiler ) {
260 $this->profiler->scopedProfileOut( $profileSection );
266 return Status::wrap( $this->status );
278 return ( $this->handler && is_a( $this->handler,
'GuzzleHttp\Handler\CurlHandler' ) ) ||
279 ( !$this->handler && extension_loaded(
'curl' ) );
288 if ( !$this->status->isOK() ) {
289 $this->respStatus =
'0 Error';
292 foreach ( $this->headerList as $name => $values ) {
293 $this->respHeaders[strtolower( $name )] = $values;
if(!defined('MW_SETUP_CALLBACK'))
MWHttpRequest implemented using the Guzzle library.
parseHeader()
Guzzle provides headers as an array.
setCallback( $callback)
Set a read callback to accept data read from the HTTP request.
doSetCallback( $callback)
Worker function for setting callbacks.
__construct( $url, array $options=[], $caller=__METHOD__, Profiler $profiler=null)
const SUPPORTS_FILE_POSTS
This wrapper class will call out to curl (if available) or fallback to regular PHP if necessary for h...
getCookieJar()
Returns the cookie jar in use.
setStatus()
Sets HTTPRequest status member to a fatal value with the error message if the returned integer value ...
parseCookies()
Parse the cookies in the response headers and store them in the cookie jar.
Profiler base class that defines the interface and some shared functionality.