From f6f302c515ecdc9a057db8a916e7464b92a286b9 Mon Sep 17 00:00:00 2001 From: t0xicCode Date: Wed, 4 Mar 2015 18:17:46 -0500 Subject: [PATCH] Implemented base_url rewriting --- .../StackMiddleware/ReverseProxyMiddleware.php | 16 ++++-- .../StackMiddleware/ReverseProxyMiddlewareTest.php | 61 ++++++++++++++++++++-- sites/default/default.settings.php | 18 +++++++ 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php b/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php index 344364d..ad659b4 100644 --- a/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php +++ b/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php @@ -11,7 +11,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; /** - * + * Provides support for reverse proxies. */ class ReverseProxyMiddleware implements HttpKernelInterface { @@ -48,8 +48,18 @@ public function __construct(HttpKernelInterface $http_kernel, Settings $settings public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) { // Initialize proxy settings. if ($this->settings->get('reverse_proxy', FALSE)) { - $reverse_proxy_header = $this->settings->get('reverse_proxy_header', 'X_FORWARDED_FOR'); - $request::setTrustedHeaderName($request::HEADER_CLIENT_IP, $reverse_proxy_header); + $ip_header = $this->settings->get('reverse_proxy_header', 'X_FORWARDED_FOR'); + $request::setTrustedHeaderName($request::HEADER_CLIENT_IP, $ip_header); + + $proto_header = $this->settings->get('reverse_proxy_proto_header', 'X_FORWARDED_PROTO'); + $request::setTrustedHeaderName($request::HEADER_CLIENT_PROTO, $proto_header); + + $host_header = $this->settings->get('reverse_proxy_host_header', 'X_FORWARDED_HOST'); + $request::setTrustedHeaderName($request::HEADER_CLIENT_HOST, $host_header); + + $port_header = $this->settings->get('reverse_proxy_port_header', 'X_FORWARDED_PORT'); + $request::setTrustedHeaderName($request::HEADER_CLIENT_PORT, $port_header); + $proxies = $this->settings->get('reverse_proxy_addresses', array()); if (count($proxies) > 0) { $request::setTrustedProxies($proxies); diff --git a/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php b/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php index f92109b..b5b71f2 100644 --- a/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php +++ b/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php @@ -36,11 +36,14 @@ public function setUp() { */ public function testNoProxy() { $settings = new Settings(array()); - $this->assertEquals(0, $settings->get('reverse_proxy')); + $this->assertEquals(FALSE, $settings->get('reverse_proxy')); $middleware = new ReverseProxyMiddleware($this->mockHttpKernel, $settings); // Mock a request object. - $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array('setTrustedHeaderName', 'setTrustedProxies')); + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array( + 'setTrustedHeaderName', + 'setTrustedProxies' + )); // setTrustedHeaderName() should never fire. $request->expects($this->never()) ->method('setTrustedHeaderName'); @@ -54,9 +57,54 @@ public function testNoProxy() { * @dataProvider reverseProxyEnabledProvider */ public function testReverseProxyEnabled($provided_settings) { - // Enable reverse proxy and add test values. - $settings = new Settings(array('reverse_proxy' => 1) + $provided_settings); - $this->trustedHeadersAreSet($settings); + // Enable reverse proxy and add test values. + $settings = new Settings(array('reverse_proxy' => 1) + $provided_settings); + $this->trustedHeadersAreSet($settings); + } + + /** + * Tests the ability of the http kernel to recognize that it is behind a + * crypto offloader. + */ + public function testCryptoOffload() { + $config = array( + 'reverse_proxy' => 1, + 'reverse_proxy_addresses' => array('127.0.0.2'), + ); + $settings = new Settings($config); + $request = new Request(); + $request->server->set('REMOTE_ADDR', '127.0.0.2'); + $request->headers->set('X_FORWARDED_PROTO', 'https'); + + $middleware = new ReverseProxyMiddleware($this->mockHttpKernel, $settings); + $middleware->handle($request); + + $this->assertTrue($request->isSecure()); + } + + /** + * Tests the ability of the http kernel to recognize that it is behind a + * crypto offloader. + */ + public function testBaseUrlAndPathRewrite() { + $config = array( + 'base_url' => 'http://test.base.url.and.path.rewrite.test', + 'reverse_proxy' => 1, + 'reverse_proxy_addresses' => array('127.0.0.2'), + ); + $settings = new Settings($config); + $request = new Request(); + $request->server->set('REQUEST_URI', '/'); + $request->server->set('REMOTE_ADDR', '127.0.0.2'); + $request->headers->set('X_FORWARDED_PROTO', 'https'); + $request->headers->set('X_FORWARDED_HOST', 'test.base.url.and.path.rewrite.test'); + + $middleware = new ReverseProxyMiddleware($this->mockHttpKernel, $settings); + $middleware->handle($request); + + $this->assertTrue($request->isSecure()); + $this->assertEquals('https://test.base.url.and.path.rewrite.test', $request->getSchemeAndHttpHost()); + $this->assertEquals('', $request->getBaseUrl()); } /** @@ -67,12 +115,14 @@ public function reverseProxyEnabledProvider() { array( array( 'reverse_proxy_header' => 'HTTP_X_FORWARDED_FOR', + 'reverse_proxy_proto_header' => 'HTTP_X_FORWARDED_PROTO', 'reverse_proxy_addresses' => array(), ), ), array( array( 'reverse_proxy_header' => 'X_FORWARDED_HOST', + 'reverse_proxy_proto_header' => 'X_FORWARDED_PROTO', 'reverse_proxy_addresses' => array('127.0.0.2', '127.0.0.3'), ), ), @@ -95,6 +145,7 @@ protected function trustedHeadersAreSet(Settings $settings) { $middleware->handle($request); $this->assertSame($settings->get('reverse_proxy_header'), $request->getTrustedHeaderName($request::HEADER_CLIENT_IP)); + $this->assertSame($settings->get('reverse_proxy_proto_header'), $request->getTrustedHeaderName($request::HEADER_CLIENT_PROTO)); $this->assertSame($settings->get('reverse_proxy_addresses'), $request->getTrustedProxies()); } } diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index d5d8704..cfbd59e 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -351,6 +351,24 @@ # $settings['reverse_proxy_header'] = 'HTTP_X_CLUSTER_CLIENT_IP'; /** + * Set this value if your proxy server sends the client protocol in a header + * other than X-Forwarded-Proto. + */ +# $conf['reverse_proxy_proto_header'] = 'HTTP_X_FORWARDED_PROTO'; + +/** + * Set this value if your proxy server sends the client protocol in a header + * other than X-Forwarded-Host. + */ +# $conf['reverse_proxy_host_header'] = 'HTTP_X_FORWARDED_HOST'; + +/** + * Set this value if your proxy server sends the client protocol in a header + * other than X-Forwarded-Port. + */ +# $conf['reverse_proxy_port_header'] = 'HTTP_X_FORWARDED_PORT'; + +/** * Page caching: * * By default, Drupal sends a "Vary: Cookie" HTTP header for anonymous page -- 1.9.1