3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
20 namespace MediaWiki\Http
;
23 use GuzzleHttpRequest
;
25 use MediaWiki\Logger\LoggerFactory
;
33 * Factory creating MWHttpRequest objects.
35 class HttpRequestFactory
{
37 * Generate a new MWHttpRequest object
38 * @param string $url Url to use
39 * @param array $options Possible keys for the array:
40 * - timeout Timeout length in seconds
41 * - connectTimeout Timeout for connection, in seconds (curl only)
42 * - postData An array of key-value pairs or a url-encoded form data
43 * - proxy The proxy to use.
44 * Otherwise it will use $wgHTTPProxy (if set)
45 * Otherwise it will use the environment variable "http_proxy" (if set)
46 * - noProxy Don't use any proxy at all. Takes precedence over proxy value(s).
47 * - sslVerifyHost Verify hostname against certificate
48 * - sslVerifyCert Verify SSL certificate
49 * - caInfo Provide CA information
50 * - maxRedirects Maximum number of redirects to follow (defaults to 5)
51 * - followRedirects Whether to follow redirects (defaults to false).
52 * Note: this should only be used when the target URL is trusted,
53 * to avoid attacks on intranet services accessible by HTTP.
54 * - userAgent A user agent, if you want to override the default
55 * MediaWiki/$wgVersion
56 * - logger A \Psr\Logger\LoggerInterface instance for debug logging
57 * - username Username for HTTP Basic Authentication
58 * - password Password for HTTP Basic Authentication
59 * - originalRequest Information about the original request (as a WebRequest object or
60 * an associative array with 'ip' and 'userAgent').
61 * @codingStandardsIgnoreStart
62 * @phan-param array{timeout?:int,connectTimeout?:int,postData?:array,proxy?:string,noProxy?:bool,sslVerifyHost?:bool,sslVerifyCert?:bool,caInfo?:string,maxRedirects?:int,followRedirects?:bool,userAgent?:string,logger?:\Psr\Logger\LoggerInterface,username?:string,password?:string,originalRequest?:WebRequest|array{ip:string,userAgent:string}} $options
63 * @codingStandardsIgnoreEnd
64 * @param string $caller The method making this request, for profiling
65 * @throws RuntimeException
66 * @return MWHttpRequest
67 * @see MWHttpRequest::__construct
68 * @suppress PhanUndeclaredTypeParameter
70 public function create( $url, array $options = [], $caller = __METHOD__
) {
71 if ( !Http
::$httpEngine ) {
72 Http
::$httpEngine = 'guzzle';
75 if ( !isset( $options['logger'] ) ) {
76 $options['logger'] = LoggerFactory
::getInstance( 'http' );
79 switch ( Http
::$httpEngine ) {
81 return new GuzzleHttpRequest( $url, $options, $caller, Profiler
::instance() );
83 return new CurlHttpRequest( $url, $options, $caller, Profiler
::instance() );
85 return new PhpHttpRequest( $url, $options, $caller, Profiler
::instance() );
87 throw new RuntimeException( __METHOD__
. ': The requested engine is not valid.' );
92 * Simple function to test if we can make any sort of requests at all, using
96 public function canMakeRequests() {
97 return function_exists( 'curl_init' ) ||
wfIniGetBool( 'allow_url_fopen' );
101 * Perform an HTTP request
104 * @param string $method HTTP method. Usually GET/POST
105 * @param string $url Full URL to act on. If protocol-relative, will be expanded to an http://
107 * @param array $options See HttpRequestFactory::create
108 * @param string $caller The method making this request, for profiling
109 * @return string|null null on failure or a string on success
111 public function request( $method, $url, array $options = [], $caller = __METHOD__
) {
112 $logger = LoggerFactory
::getInstance( 'http' );
113 $logger->debug( "$method: $url" );
115 $options['method'] = strtoupper( $method );
117 if ( !isset( $options['timeout'] ) ) {
118 $options['timeout'] = 'default';
120 if ( !isset( $options['connectTimeout'] ) ) {
121 $options['connectTimeout'] = 'default';
124 $req = $this->create( $url, $options, $caller );
125 $status = $req->execute();
127 if ( $status->isOK() ) {
128 return $req->getContent();
130 $errors = $status->getErrorsByType( 'error' );
131 $logger->warning( Status
::wrap( $status )->getWikiText( false, false, 'en' ),
132 [ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
138 * Simple wrapper for request( 'GET' ), parameters have same meaning as for request()
142 * @param array $options
143 * @param string $caller
144 * @return string|null
146 public function get( $url, array $options = [], $caller = __METHOD__
) {
147 return $this->request( 'GET', $url, $options, $caller );
151 * Simple wrapper for request( 'POST' ), parameters have same meaning as for request()
155 * @param array $options
156 * @param string $caller
157 * @return string|null
159 public function post( $url, array $options = [], $caller = __METHOD__
) {
160 return $this->request( 'POST', $url, $options, $caller );
166 public function getUserAgent() {
169 return "MediaWiki/$wgVersion";