Merge "Allow using a reverse proxy for local HTTP requests"
This commit is contained in:
commit
93821348aa
3 changed files with 57 additions and 4 deletions
|
|
@ -9675,6 +9675,8 @@ $wgHTTPProxy = '';
|
|||
* Local virtual hosts.
|
||||
*
|
||||
* This lists domains that are configured as virtual hosts on the same machine.
|
||||
* It is expected that each domain can be identified by its hostname alone,
|
||||
* without any ports.
|
||||
*
|
||||
* This affects the following:
|
||||
* - MWHttpRequest: If a request is to be made to a domain listed here, or any
|
||||
|
|
@ -9687,12 +9689,16 @@ $wgHTTPProxy = '';
|
|||
$wgLocalVirtualHosts = [];
|
||||
|
||||
/**
|
||||
* Proxy to use to requests to domains in $wgLocalVirtualHosts
|
||||
* Reverse proxy to use for requests to domains in $wgLocalVirtualHosts
|
||||
*
|
||||
* If set to false, no proxy will be used for local requests
|
||||
* When used, any port in the request URL will be dropped. The behavior of
|
||||
* redirects and cookies is dependent upon the reverse proxy actually in use,
|
||||
* as MediaWiki doesn't implement any special handling for them.
|
||||
*
|
||||
* If set to false, no reverse proxy will be used for local requests.
|
||||
*
|
||||
* @var string|bool
|
||||
* @since 1.37
|
||||
* @since 1.38
|
||||
*/
|
||||
$wgLocalHTTPProxy = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -239,12 +239,47 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
|
|||
// Otherwise, fallback to $wgLocalHTTPProxy for local URLs
|
||||
// or $wgHTTPProxy for everything else
|
||||
if ( self::isLocalURL( $this->url ) ) {
|
||||
$this->proxy = (string)$wgLocalHTTPProxy;
|
||||
if ( $wgLocalHTTPProxy !== false ) {
|
||||
$this->setReverseProxy( $wgLocalHTTPProxy );
|
||||
}
|
||||
} else {
|
||||
$this->proxy = (string)$wgHTTPProxy;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable use of a reverse proxy in which the hostname is
|
||||
* passed as a "Host" header, and the request is sent to the
|
||||
* proxy's host:port instead.
|
||||
*
|
||||
* Note that any custom port in the request URL will be lost
|
||||
* and cookies and redirects may not work properly.
|
||||
*
|
||||
* @param string $proxy URL of proxy
|
||||
*/
|
||||
protected function setReverseProxy( string $proxy ) {
|
||||
$parsedProxy = wfParseUrl( $proxy );
|
||||
if ( $parsedProxy === false ) {
|
||||
throw new Exception( "Invalid reverseProxy configured: $proxy" );
|
||||
}
|
||||
// Set the current host in the Host header
|
||||
$this->setHeader( 'Host', $this->parsedUrl['host'] );
|
||||
// Set current protocol in X-Forwarded-Proto
|
||||
// TODO: consider supporting the standardized "Forwarded" header too
|
||||
$this->setHeader( 'X-Forwarded-Proto', $this->parsedUrl['scheme'] );
|
||||
// Replace scheme, host and port in the request
|
||||
$this->parsedUrl['scheme'] = $parsedProxy['scheme'];
|
||||
$this->parsedUrl['host'] = $parsedProxy['host'];
|
||||
if ( isset( $parsedProxy['port'] ) ) {
|
||||
$this->parsedUrl['port'] = $parsedProxy['port'];
|
||||
} else {
|
||||
unset( $this->parsedUrl['port'] );
|
||||
}
|
||||
$this->url = wfAssembleUrl( $this->parsedUrl );
|
||||
// Mark that we're already using a proxy
|
||||
$this->noProxy = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the URL can be served by localhost
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
/**
|
||||
* @covers MWHttpRequest
|
||||
*/
|
||||
|
|
@ -85,4 +87,14 @@ class MWHttpRequestTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertSame( $expect, MWHttpRequest::isValidURI( $uri ), $message );
|
||||
}
|
||||
|
||||
public function testSetReverseProxy() {
|
||||
$req = TestingAccessWrapper::newFromObject(
|
||||
MWHttpRequest::factory( 'https://example.org/path?query=string' )
|
||||
);
|
||||
$req->setReverseProxy( 'http://localhost:1234' );
|
||||
$this->assertSame( $req->url, 'http://localhost:1234/path?query=string' );
|
||||
$this->assertSame( $req->reqHeaders['Host'], 'example.org' );
|
||||
$this->assertSame( $req->reqHeaders['X-Forwarded-Proto'], 'https' );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue