From 6a9c5102b29851460aafbcdae44d09ed7b002571 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 9 Feb 2013 21:11:02 +0100 Subject: [PATCH 1/2] fixed the IP address in HttpCache when calling the backend --- src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php | 4 ++++ .../HttpKernel/Tests/HttpCache/HttpCacheTest.php | 8 ++++++++ .../HttpKernel/Tests/HttpCache/TestHttpKernel.php | 7 +++++++ .../HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php | 8 ++++++++ 4 files changed, 27 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index ec66dcd5fc..1bc3aa492e 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -413,6 +413,10 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $subRequest->headers->remove('if_modified_since'); $subRequest->headers->remove('if_none_match'); + // fix the client IP address by setting it to 127.0.0.1 as HttpCache + // is always called from the same process as the backend. + $subRequest->server->set('REMOTE_ADDR', '127.0.0.1'); + $response = $this->forward($subRequest, $catch); if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index 5060a696c2..31dbbd555c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -1034,4 +1034,12 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('Hello World!', $this->response->getContent()); $this->assertEquals(12, $this->response->headers->get('Content-Length')); } + + public function testClientIpIsAlwaysLocalhostForForwardedRequests() + { + $this->setNextResponse(); + $this->request('GET', '/', array('REMOTE_ADDR' => '10.0.0.1')); + + $this->assertEquals('127.0.0.1', $this->kernel->getBackendRequest()->server->get('REMOTE_ADDR')); + } } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php index c732c673f3..cf23d7bf8a 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php @@ -26,6 +26,7 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface protected $called; protected $customizer; protected $catch; + protected $backendRequest; public function __construct($body, $status, $headers, \Closure $customizer = null) { @@ -39,9 +40,15 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface parent::__construct(new EventDispatcher(), $this); } + public function getBackendRequest() + { + return $this->backendRequest; + } + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = false) { $this->catch = $catch; + $this->backendRequest = $request; return parent::handle($request, $type, $catch); } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php index eeb9bea0dc..6dd3d9e499 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php @@ -25,6 +25,7 @@ class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInt protected $headers; protected $catch; protected $call; + protected $backendRequest; public function __construct($responses) { @@ -42,8 +43,15 @@ class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInt parent::__construct(new EventDispatcher(), $this); } + public function getBackendRequest() + { + return $this->backendRequest; + } + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = false) { + $this->backendRequest = $request; + return parent::handle($request, $type, $catch); } From 42d3c4c9cab5ec7ebcc17ffd41a12b99156147c6 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 9 Feb 2013 21:11:21 +0100 Subject: [PATCH 2/2] added support for the X-Forwarded-For header (closes #6982, closes #7000) --- .../HttpKernel/HttpCache/HttpCache.php | 8 +++++++ .../Tests/HttpCache/HttpCacheTest.php | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 1bc3aa492e..97e365008b 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -413,6 +413,14 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $subRequest->headers->remove('if_modified_since'); $subRequest->headers->remove('if_none_match'); + // modify the X-Forwarded-For header if needed + $forwardedFor = $subRequest->headers->get('X-Forwarded-For'); + if ($forwardedFor) { + $subRequest->headers->set('X-Forwarded-For', $forwardedFor.', '.$subRequest->server->get('REMOTE_ADDR')); + } else { + $subRequest->headers->set('X-Forwarded-For', $subRequest->server->get('REMOTE_ADDR')); + } + // fix the client IP address by setting it to 127.0.0.1 as HttpCache // is always called from the same process as the backend. $subRequest->server->set('REMOTE_ADDR', '127.0.0.1'); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index 31dbbd555c..89203a8ae2 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -1042,4 +1042,28 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('127.0.0.1', $this->kernel->getBackendRequest()->server->get('REMOTE_ADDR')); } + + /** + * @dataProvider getXForwardedForData + */ + public function testXForwarderForHeaderForForwardedRequests($xForwardedFor, $expected) + { + $this->setNextResponse(); + $server = array('REMOTE_ADDR' => '10.0.0.1'); + if (false !== $xForwardedFor) { + $server['HTTP_X_FORWARDED_FOR'] = $xForwardedFor; + } + $this->request('GET', '/', $server); + + $this->assertEquals($expected, $this->kernel->getBackendRequest()->headers->get('X-Forwarded-For')); + } + + public function getXForwardedForData() + { + return array( + array(false, '10.0.0.1'), + array('10.0.0.2', '10.0.0.2, 10.0.0.1'), + array('10.0.0.2, 10.0.0.3', '10.0.0.2, 10.0.0.3, 10.0.0.1'), + ); + } }