Deprecate the Http class

All methods got moved to HttpRequestFactory or MWHttpRequest or dropped.

I made the return value of the new HttpRequestFactory::request/get/post
methods null on error instead of false, so that when we drop PHP 7
support, we can use a "?string" return value. This could theoretically
change behavior of code that was switched from the old Http methods, but
probably won't. I kept the old behavior for the deprecated methods.

I changed the default value of $wgHTTPProxy from false to ''. This way
it should be usable directly without a trivial wrapper method. For the
benefit of anyone who might have set it to false in LocalSettings.php, I
also recommend casting to string just in case.

Http::$httpEngine is deprecated. Eventually it will be removed along
with the curl and PHP engines, leaving only the Guzlle engine.

I also added deprecation of MWHttpRequest::factory, which occurred in
1.31, to the release notes for 1.34. Now hopefully we can hard-deprecate
it in another couple of versions.

Bug: T214390
Change-Id: I2a316a758d793857f248bd251b90f5e9a6440e3a
This commit is contained in:
Aryeh Gregor 2019-04-15 16:23:02 +03:00
parent 427fbee734
commit 9018579681
23 changed files with 256 additions and 122 deletions

View file

@ -116,7 +116,7 @@ because of Phabricator reports.
* …
=== Deprecations in 1.34 ===
* The MWNamespace class is deprecated. Use MediaWikiServices::getNamespaceInfo.
* The MWNamespace class is deprecated. Use NamespaceInfo.
* ExtensionRegistry->load() is deprecated, as it breaks dependency checking.
Instead, use ->queue().
* User::isBlocked() is deprecated since it does not tell you if the user is
@ -135,6 +135,13 @@ because of Phabricator reports.
RevisionLookup::getPreviousRevision and RevisionLookup::getNextRevision.
* The Title parameter to RevisionLookup::getPreviousRevision and
RevisionLookup::getNextRevision is deprecated and should be omitted.
* MWHttpRequest::factory is deprecated. Use HttpRequestFactory.
* The Http class is deprecated. For the request, get, and post methods, use
HttpRequestFactory. For isValidURI, use MWHttpRequest::isValidURI. For
getProxy, use (string)$wgHTTPProxy. For createMultiClient, construct a
MultiHttpClient directly.
* Http::$httpEngine is deprecated and has no replacement. The default 'guzzle'
engine will eventually be made the only engine for HTTP requests.
=== Other changes in 1.34 ===
* …

View file

@ -8399,7 +8399,7 @@ $wgAsyncHTTPTimeout = 25;
/**
* Proxy to use for CURL requests.
*/
$wgHTTPProxy = false;
$wgHTTPProxy = '';
/**
* Local virtual hosts.

View file

@ -22,6 +22,7 @@
use Psr\Log\LoggerInterface;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
/**
* Send information about this MediaWiki instance to MediaWiki.org.
@ -229,7 +230,7 @@ class Pingback {
$json = FormatJson::encode( $data );
$queryString = rawurlencode( str_replace( ' ', '\u0020', $json ) ) . ';';
$url = 'https://www.mediawiki.org/beacon/event?' . $queryString;
return Http::post( $url ) !== false;
return MediaWikiServices::getInstance()->getHttpRequestFactory()->post( $url ) !== null;
}
/**

View file

@ -20,6 +20,8 @@
* @file
*/
use MediaWiki\MediaWikiServices;
/**
* Example class for HTTP accessible external objects.
* Only supports reading, not storing.
@ -28,7 +30,8 @@
*/
class ExternalStoreHttp extends ExternalStoreMedium {
public function fetchFromURL( $url ) {
return Http::get( $url, [], __METHOD__ );
return MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $url, [], __METHOD__ );
}
public function store( $location, $data ) {

View file

@ -502,8 +502,9 @@ class ForeignAPIRepo extends FileRepo {
}
/**
* Like a Http:get request, but with custom User-Agent.
* @see Http::get
* Like a HttpRequestFactory::get request, but with custom User-Agent.
* @see HttpRequestFactory::get
* @todo Can this use HttpRequestFactory::get() but just pass the 'userAgent' option?
* @param string $url
* @param string $timeout
* @param array $options

View file

@ -2070,7 +2070,8 @@ abstract class File implements IDBAccessObject {
$this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl, $fname ) {
wfDebug( "Fetching shared description from $renderUrl\n" );
$res = Http::get( $renderUrl, [], $fname );
$res = MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $renderUrl, [], $fname );
if ( !$res ) {
$ttl = WANObjectCache::TTL_UNCACHEABLE;
}

View file

@ -165,7 +165,8 @@ class ForeignDBFile extends LocalFile {
$this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl, $fname ) {
wfDebug( "Fetching shared description from $renderUrl\n" );
$res = Http::get( $renderUrl, [], $fname );
$res = MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $renderUrl, [], $fname );
if ( !$res ) {
$ttl = WANObjectCache::TTL_UNCACHEABLE;
}

View file

@ -27,6 +27,18 @@ class CurlHttpRequest extends MWHttpRequest {
protected $curlOptions = [];
protected $headerText = "";
/**
* @throws RuntimeException
*/
public function __construct() {
if ( !function_exists( 'curl_init' ) ) {
throw new RuntimeException(
__METHOD__ . ': curl (https://www.php.net/curl) is not installed' );
}
parent::__construct( ...func_get_args() );
}
/**
* @param resource $fh
* @param string $content

View file

@ -45,7 +45,7 @@ class GuzzleHttpRequest extends MWHttpRequest {
/**
* @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL
* @param array $options (optional) extra params to pass (see Http::request())
* @param array $options (optional) extra params to pass (see HttpRequestFactory::create())
* @param string $caller The method making this request, for profiling
* @param Profiler|null $profiler An instance of the profiler for profiling, or null
* @throws Exception

View file

@ -19,74 +19,40 @@
*/
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
/**
* Various HTTP related functions
* @deprecated since 1.34
* @ingroup HTTP
*/
class Http {
public static $httpEngine = false;
/** @deprecated since 1.34, just use the default engine */
public static $httpEngine = null;
/**
* Perform an HTTP request
*
* @deprecated since 1.34, use HttpRequestFactory::request()
*
* @param string $method HTTP method. Usually GET/POST
* @param string $url Full URL to act on. If protocol-relative, will be expanded to an http:// URL
* @param array $options Options to pass to MWHttpRequest object.
* Possible keys for the array:
* - timeout Timeout length in seconds
* - connectTimeout Timeout for connection, in seconds (curl only)
* - postData An array of key-value pairs or a url-encoded form data
* - proxy The proxy to use.
* Otherwise it will use $wgHTTPProxy (if set)
* Otherwise it will use the environment variable "http_proxy" (if set)
* - noProxy Don't use any proxy at all. Takes precedence over proxy value(s).
* - sslVerifyHost Verify hostname against certificate
* - sslVerifyCert Verify SSL certificate
* - caInfo Provide CA information
* - maxRedirects Maximum number of redirects to follow (defaults to 5)
* - followRedirects Whether to follow redirects (defaults to false).
* Note: this should only be used when the target URL is trusted,
* to avoid attacks on intranet services accessible by HTTP.
* - userAgent A user agent, if you want to override the default
* MediaWiki/$wgVersion
* - logger A \Psr\Logger\LoggerInterface instance for debug logging
* - username Username for HTTP Basic Authentication
* - password Password for HTTP Basic Authentication
* - originalRequest Information about the original request (as a WebRequest object or
* an associative array with 'ip' and 'userAgent').
* @param array $options Options to pass to MWHttpRequest object. See HttpRequestFactory::create
* docs
* @param string $caller The method making this request, for profiling
* @return string|bool (bool)false on failure or a string on success
*/
public static function request( $method, $url, array $options = [], $caller = __METHOD__ ) {
$logger = LoggerFactory::getInstance( 'http' );
$logger->debug( "$method: $url" );
$options['method'] = strtoupper( $method );
if ( !isset( $options['timeout'] ) ) {
$options['timeout'] = 'default';
}
if ( !isset( $options['connectTimeout'] ) ) {
$options['connectTimeout'] = 'default';
}
$req = MWHttpRequest::factory( $url, $options, $caller );
$status = $req->execute();
if ( $status->isOK() ) {
return $req->getContent();
} else {
$errors = $status->getErrorsByType( 'error' );
$logger->warning( Status::wrap( $status )->getWikiText( false, false, 'en' ),
[ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
return false;
}
$ret = MediaWikiServices::getInstance()->getHttpRequestFactory()->request(
$method, $url, $options, $caller );
return is_string( $ret ) ? $ret : false;
}
/**
* Simple wrapper for Http::request( 'GET' )
* @see Http::request()
*
* @deprecated since 1.34, use HttpRequestFactory::get()
*
* @since 1.25 Second parameter $timeout removed. Second parameter
* is now $options which can be given a 'timeout'
*
@ -111,7 +77,8 @@ class Http {
/**
* Simple wrapper for Http::request( 'POST' )
* @see Http::request()
*
* @deprecated since 1.34, use HttpRequestFactory::post()
*
* @param string $url
* @param array $options
@ -124,11 +91,12 @@ class Http {
/**
* A standard user-agent we can use for external requests.
*
* @deprecated since 1.34, use HttpRequestFactory::getUserAgent()
* @return string
*/
public static function userAgent() {
global $wgVersion;
return "MediaWiki/$wgVersion";
return MediaWikiServices::getInstance()->getHttpRequestFactory()->getUserAgent();
}
/**
@ -143,37 +111,37 @@ class Http {
*
* @todo FIXME this is wildly inaccurate and fails to actually check most stuff
*
* @deprecated since 1.34, use MWHttpRequest::isValidURI
* @param string $uri URI to check for validity
* @return bool
*/
public static function isValidURI( $uri ) {
return (bool)preg_match(
'/^https?:\/\/[^\/\s]\S*$/D',
$uri
);
return MWHttpRequest::isValidURI( $uri );
}
/**
* Gets the relevant proxy from $wgHTTPProxy
*
* @return mixed The proxy address or an empty string if not set.
* @deprecated since 1.34, use $wgHTTPProxy directly
* @return string The proxy address or an empty string if not set.
*/
public static function getProxy() {
wfDeprecated( __METHOD__, '1.34' );
global $wgHTTPProxy;
if ( $wgHTTPProxy ) {
return $wgHTTPProxy;
}
return "";
return (string)$wgHTTPProxy;
}
/**
* Get a configured MultiHttpClient
*
* @deprecated since 1.34, construct it directly
* @param array $options
* @return MultiHttpClient
*/
public static function createMultiClient( array $options = [] ) {
wfDeprecated( __METHOD__, '1.34' );
global $wgHTTPConnectTimeout, $wgHTTPTimeout, $wgHTTPProxy;
return new MultiHttpClient( $options + [

View file

@ -20,34 +20,52 @@
namespace MediaWiki\Http;
use CurlHttpRequest;
use DomainException;
use GuzzleHttpRequest;
use Http;
use MediaWiki\Logger\LoggerFactory;
use MWHttpRequest;
use PhpHttpRequest;
use Profiler;
use GuzzleHttpRequest;
use RuntimeException;
use Status;
/**
* Factory creating MWHttpRequest objects.
*/
class HttpRequestFactory {
/**
* Generate a new MWHttpRequest object
* @param string $url Url to use
* @param array $options (optional) extra params to pass (see Http::request())
* @param array $options Possible keys for the array:
* - timeout Timeout length in seconds
* - connectTimeout Timeout for connection, in seconds (curl only)
* - postData An array of key-value pairs or a url-encoded form data
* - proxy The proxy to use.
* Otherwise it will use $wgHTTPProxy (if set)
* Otherwise it will use the environment variable "http_proxy" (if set)
* - noProxy Don't use any proxy at all. Takes precedence over proxy value(s).
* - sslVerifyHost Verify hostname against certificate
* - sslVerifyCert Verify SSL certificate
* - caInfo Provide CA information
* - maxRedirects Maximum number of redirects to follow (defaults to 5)
* - followRedirects Whether to follow redirects (defaults to false).
* Note: this should only be used when the target URL is trusted,
* to avoid attacks on intranet services accessible by HTTP.
* - userAgent A user agent, if you want to override the default
* MediaWiki/$wgVersion
* - logger A \Psr\Logger\LoggerInterface instance for debug logging
* - username Username for HTTP Basic Authentication
* - password Password for HTTP Basic Authentication
* - originalRequest Information about the original request (as a WebRequest object or
* an associative array with 'ip' and 'userAgent').
* @param string $caller The method making this request, for profiling
* @throws DomainException
* @throws RuntimeException
* @return MWHttpRequest
* @see MWHttpRequest::__construct
*/
public function create( $url, array $options = [], $caller = __METHOD__ ) {
if ( !Http::$httpEngine ) {
Http::$httpEngine = 'guzzle';
} elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
throw new DomainException( __METHOD__ . ': curl (https://www.php.net/curl) is not ' .
'installed, but Http::$httpEngine is set to "curl"' );
}
if ( !isset( $options['logger'] ) ) {
@ -60,16 +78,9 @@ class HttpRequestFactory {
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 ' .
'https://www.php.net/curl.'
);
}
return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
default:
throw new DomainException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' );
throw new RuntimeException( __METHOD__ . ': The requested engine is not valid.' );
}
}
@ -82,4 +93,75 @@ class HttpRequestFactory {
return function_exists( 'curl_init' ) || wfIniGetBool( 'allow_url_fopen' );
}
/**
* Perform an HTTP request
*
* @since 1.34
* @param string $method HTTP method. Usually GET/POST
* @param string $url Full URL to act on. If protocol-relative, will be expanded to an http://
* URL
* @param array $options See HttpRequestFactory::create
* @param string $caller The method making this request, for profiling
* @return string|null null on failure or a string on success
*/
public function request( $method, $url, array $options = [], $caller = __METHOD__ ) {
$logger = LoggerFactory::getInstance( 'http' );
$logger->debug( "$method: $url" );
$options['method'] = strtoupper( $method );
if ( !isset( $options['timeout'] ) ) {
$options['timeout'] = 'default';
}
if ( !isset( $options['connectTimeout'] ) ) {
$options['connectTimeout'] = 'default';
}
$req = $this->create( $url, $options, $caller );
$status = $req->execute();
if ( $status->isOK() ) {
return $req->getContent();
} else {
$errors = $status->getErrorsByType( 'error' );
$logger->warning( Status::wrap( $status )->getWikiText( false, false, 'en' ),
[ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
return null;
}
}
/**
* Simple wrapper for request( 'GET' ), parameters have same meaning as for request()
*
* @since 1.34
* @param string $url
* @param array $options
* @param string $caller
* @return string|null
*/
public function get( $url, array $options = [], $caller = __METHOD__ ) {
$this->request( 'GET', $url, $options, $caller );
}
/**
* Simple wrapper for request( 'POST' ), parameters have same meaning as for request()
*
* @since 1.34
* @param string $url
* @param array $options
* @param string $caller
* @return string|null
*/
public function post( $url, array $options = [], $caller = __METHOD__ ) {
$this->request( 'POST', $url, $options, $caller );
}
/**
* @return string
*/
public function getUserAgent() {
global $wgVersion;
return "MediaWiki/$wgVersion";
}
}

View file

@ -85,7 +85,7 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
/**
* @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL
* @param array $options (optional) extra params to pass (see Http::request())
* @param array $options (optional) extra params to pass (see HttpRequestFactory::create())
* @param string $caller The method making this request, for profiling
* @param Profiler|null $profiler An instance of the profiler for profiling, or null
* @throws Exception
@ -172,9 +172,9 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
/**
* Generate a new request object
* Deprecated: @see HttpRequestFactory::create
* @deprecated since 1.34, use HttpRequestFactory instead
* @param string $url Url to use
* @param array|null $options (optional) extra params to pass (see Http::request())
* @param array|null $options (optional) extra params to pass (see HttpRequestFactory::create())
* @param string $caller The method making this request, for profiling
* @throws DomainException
* @return MWHttpRequest
@ -224,7 +224,8 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
if ( self::isLocalURL( $this->url ) || $this->noProxy ) {
$this->proxy = '';
} else {
$this->proxy = Http::getProxy();
global $wgHTTPProxy;
$this->proxy = (string)$wgHTTPProxy;
}
}
@ -662,4 +663,27 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
$this->reqHeaders['X-Forwarded-For'] = $originalRequest['ip'];
$this->reqHeaders['X-Original-User-Agent'] = $originalRequest['userAgent'];
}
/**
* Check that the given URI is a valid one.
*
* This hardcodes a small set of protocols only, because we want to
* deterministically reject protocols not supported by all HTTP-transport
* methods.
*
* "file://" specifically must not be allowed, for security reasons
* (see <https://www.mediawiki.org/wiki/Special:Code/MediaWiki/r67684>).
*
* @todo FIXME this is wildly inaccurate and fails to actually check most stuff
*
* @since 1.34
* @param string $uri URI to check for validity
* @return bool
*/
public static function isValidURI( $uri ) {
return (bool)preg_match(
'/^https?:\/\/[^\/\s]\S*$/D',
$uri
);
}
}

View file

@ -22,6 +22,17 @@ class PhpHttpRequest extends MWHttpRequest {
private $fopenErrors = [];
public function __construct() {
if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
throw new RuntimeException( __METHOD__ . ': allow_url_fopen needs to be enabled for ' .
'pure PHP http requests to work. If possible, curl should be used instead. See ' .
'https://www.php.net/curl.'
);
}
parent::__construct( ...func_get_args() );
}
/**
* @param string $url
* @return string

View file

@ -112,7 +112,7 @@ class ImportStreamSource implements ImportSource {
# quicker and sorts out user-agent problems which might
# otherwise prevent importing from large sites, such
# as the Wikimedia cluster, etc.
$data = Http::request(
$data = MediaWikiServices::getInstance()->getHttpRequestFactory()->request(
$method,
$url,
[

View file

@ -1,5 +1,6 @@
<?php
use MediaWiki\MediaWikiServices;
use Psr\Log\LoggerInterface;
/**
@ -159,7 +160,8 @@ class ImportableUploadRevisionImporter implements UploadRevisionImporter {
// @todo FIXME!
$src = $wikiRevision->getSrc();
$data = Http::get( $src, [], __METHOD__ );
$data = MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $src, [], __METHOD__ );
if ( !$data ) {
$this->logger->debug( "IMPORT: couldn't fetch source $src\n" );
fclose( $f );

View file

@ -1203,9 +1203,11 @@ abstract class Installer {
}
try {
$text = Http::get( $url . $file, [ 'timeout' => 3 ], __METHOD__ );
$text = MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $url . $file, [ 'timeout' => 3 ], __METHOD__ );
} catch ( Exception $e ) {
// Http::get throws with allow_url_fopen = false and no curl extension.
// HttpRequestFactory::get can throw with allow_url_fopen = false and no curl
// extension.
$text = null;
}
unlink( $dir . $file );

View file

@ -24,6 +24,8 @@
* @author Platonides
*/
use MediaWiki\MediaWikiServices;
require_once __DIR__ . '/Benchmarker.php';
/**
@ -45,7 +47,8 @@ class BenchHttpHttps extends Benchmarker {
}
private function doRequest( $proto ) {
Http::get( "$proto://localhost/", [], __METHOD__ );
MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( "$proto://localhost/", [], __METHOD__ );
}
// bench function 1

View file

@ -34,6 +34,8 @@
* @author Antoine Musso <hashar at free dot fr>
*/
use MediaWiki\MediaWikiServices;
require_once __DIR__ . '/Maintenance.php';
/**
@ -216,7 +218,7 @@ class FindHooks extends Maintenance {
$retval = [];
while ( true ) {
$json = Http::get(
$json = MediaWikiServices::getInstance()->getHttpRequestFactory()->get(
wfAppendQuery( 'https://www.mediawiki.org/w/api.php', $params ),
[],
__METHOD__

View file

@ -21,6 +21,8 @@
* @ingroup Maintenance
*/
use MediaWiki\MediaWikiServices;
require_once __DIR__ . '/Maintenance.php';
/**
@ -64,7 +66,8 @@ class ImportSiteScripts extends Maintenance {
$url = wfAppendQuery( $baseUrl, [
'action' => 'raw',
'title' => "MediaWiki:{$page}" ] );
$text = Http::get( $url, [], __METHOD__ );
$text = MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $url, [], __METHOD__ );
$wikiPage = WikiPage::factory( $title );
$content = ContentHandler::makeContent( $text, $wikiPage->getTitle() );
@ -86,7 +89,8 @@ class ImportSiteScripts extends Maintenance {
while ( true ) {
$url = wfAppendQuery( $baseUrl, $data );
$strResult = Http::get( $url, [], __METHOD__ );
$strResult = MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $url, [], __METHOD__ );
$result = FormatJson::decode( $strResult, true );
$page = null;

View file

@ -86,7 +86,7 @@ TEXT
$url = rtrim( $this->source, '?' ) . '?' . $url;
}
$json = Http::get( $url );
$json = MediaWikiServices::getInstance()->getHttpRequestFactory()->get( $url );
$data = json_decode( $json, true );
if ( is_array( $data ) ) {

View file

@ -1,19 +1,25 @@
<?php
use MediaWiki\MediaWikiServices;
use Wikimedia\TestingAccessWrapper;
abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
protected static $httpEngine;
protected $oldHttpEngine;
/** @var HttpRequestFactory */
private $factory;
public function setUp() {
parent::setUp();
$this->oldHttpEngine = Http::$httpEngine;
Http::$httpEngine = static::$httpEngine;
$this->factory = MediaWikiServices::getInstance()->getHttpRequestFactory();
try {
$request = MWHttpRequest::factory( 'null:' );
} catch ( DomainException $e ) {
$request = $factory->create( 'null:' );
} catch ( RuntimeException $e ) {
$this->markTestSkipped( static::$httpEngine . ' engine not supported' );
}
@ -32,19 +38,19 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
// --------------------
public function testIsRedirect() {
$request = MWHttpRequest::factory( 'http://httpbin.org/get' );
$request = $this->factory->create( 'http://httpbin.org/get' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertFalse( $request->isRedirect() );
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/1' );
$request = $this->factory->create( 'http://httpbin.org/redirect/1' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertTrue( $request->isRedirect() );
}
public function testgetFinalUrl() {
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3' );
$request = $this->factory->create( 'http://httpbin.org/redirect/3' );
if ( !$request->canFollowRedirects() ) {
$this->markTestSkipped( 'cannot follow redirects' );
}
@ -52,14 +58,14 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
$this->assertTrue( $status->isGood() );
$this->assertNotSame( 'http://httpbin.org/get', $request->getFinalUrl() );
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
$request = $this->factory->create( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$this->assertSame( 'http://httpbin.org/get', $request->getFinalUrl() );
$this->assertResponseFieldValue( 'url', 'http://httpbin.org/get', $request );
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
$request = $this->factory->create( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
@ -71,7 +77,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
return;
}
$request = MWHttpRequest::factory( 'http://httpbin.org/redirect/3', [ 'followRedirects'
$request = $this->factory->create( 'http://httpbin.org/redirect/3', [ 'followRedirects'
=> true, 'maxRedirects' => 1 ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
@ -79,7 +85,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testSetCookie() {
$request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
$request = $this->factory->create( 'http://httpbin.org/cookies' );
$request->setCookie( 'foo', 'bar' );
$request->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
$status = $request->execute();
@ -88,7 +94,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testSetCookieJar() {
$request = MWHttpRequest::factory( 'http://httpbin.org/cookies' );
$request = $this->factory->create( 'http://httpbin.org/cookies' );
$cookieJar = new CookieJar();
$cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
$cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'example.com' ] );
@ -97,7 +103,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'cookies', [ 'foo' => 'bar' ], $request );
$request = MWHttpRequest::factory( 'http://httpbin.org/cookies/set?foo=bar' );
$request = $this->factory->create( 'http://httpbin.org/cookies/set?foo=bar' );
$cookieJar = new CookieJar();
$request->setCookieJar( $cookieJar );
$status = $request->execute();
@ -106,7 +112,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
$this->markTestIncomplete( 'CookieJar does not handle deletion' );
// $request = MWHttpRequest::factory( 'http://httpbin.org/cookies/delete?foo' );
// $request = $this->factory->create( 'http://httpbin.org/cookies/delete?foo' );
// $cookieJar = new CookieJar();
// $cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
// $cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'httpbin.org' ] );
@ -118,7 +124,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testGetResponseHeaders() {
$request = MWHttpRequest::factory( 'http://httpbin.org/response-headers?Foo=bar' );
$request = $this->factory->create( 'http://httpbin.org/response-headers?Foo=bar' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
$headers = array_change_key_case( $request->getResponseHeaders(), CASE_LOWER );
@ -127,7 +133,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testSetHeader() {
$request = MWHttpRequest::factory( 'http://httpbin.org/headers' );
$request = $this->factory->create( 'http://httpbin.org/headers' );
$request->setHeader( 'Foo', 'bar' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
@ -135,14 +141,14 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testGetStatus() {
$request = MWHttpRequest::factory( 'http://httpbin.org/status/418' );
$request = $this->factory->create( 'http://httpbin.org/status/418' );
$status = $request->execute();
$this->assertFalse( $status->isOK() );
$this->assertSame( $request->getStatus(), 418 );
}
public function testSetUserAgent() {
$request = MWHttpRequest::factory( 'http://httpbin.org/user-agent' );
$request = $this->factory->create( 'http://httpbin.org/user-agent' );
$request->setUserAgent( 'foo' );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
@ -150,7 +156,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testSetData() {
$request = MWHttpRequest::factory( 'http://httpbin.org/post', [ 'method' => 'POST' ] );
$request = $this->factory->create( 'http://httpbin.org/post', [ 'method' => 'POST' ] );
$request->setData( [ 'foo' => 'bar', 'foo2' => 'bar2' ] );
$status = $request->execute();
$this->assertTrue( $status->isGood() );
@ -163,7 +169,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
return;
}
$request = MWHttpRequest::factory( 'http://httpbin.org/ip' );
$request = $this->factory->create( 'http://httpbin.org/ip' );
$data = '';
$request->setCallback( function ( $fh, $content ) use ( &$data ) {
$data .= $content;
@ -177,7 +183,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testBasicAuthentication() {
$request = MWHttpRequest::factory( 'http://httpbin.org/basic-auth/user/pass', [
$request = $this->factory->create( 'http://httpbin.org/basic-auth/user/pass', [
'username' => 'user',
'password' => 'pass',
] );
@ -185,7 +191,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
$this->assertTrue( $status->isGood() );
$this->assertResponseFieldValue( 'authenticated', true, $request );
$request = MWHttpRequest::factory( 'http://httpbin.org/basic-auth/user/pass', [
$request = $this->factory->create( 'http://httpbin.org/basic-auth/user/pass', [
'username' => 'user',
'password' => 'wrongpass',
] );
@ -195,7 +201,7 @@ abstract class MWHttpRequestTestCase extends PHPUnit\Framework\TestCase {
}
public function testFactoryDefaults() {
$request = MWHttpRequest::factory( 'http://acme.test' );
$request = $this->factory->create( 'http://acme.test' );
$this->assertInstanceOf( MWHttpRequest::class, $request );
}

View file

@ -1,5 +1,6 @@
<?php
use MediaWiki\MediaWikiServices;
use Wikimedia\TestingAccessWrapper;
/**
@ -1538,7 +1539,8 @@ class FileBackendTest extends MediaWikiTestCase {
$url = $this->backend->getFileHttpUrl( [ 'src' => $source ] );
if ( $url !== null ) { // supported
$data = Http::request( "GET", $url, [], __METHOD__ );
$data = MediaWikiServices::getInstance()->getHttpRequestFactory()->
get( $url, [], __METHOD__ );
$this->assertEquals( $content, $data,
"HTTP GET of URL has right contents ($backendName)." );
}

View file

@ -67,6 +67,8 @@ class HttpTest extends MediaWikiTestCase {
* @covers Http::getProxy
*/
public function testGetProxy() {
$this->hideDeprecated( 'Http::getProxy' );
$this->setMwGlobals( 'wgHTTPProxy', false );
$this->assertEquals(
'',