diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 4b5b0c1574cd4..8629cf8bb7338 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -173,6 +173,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ { // FIXME: catch exceptions and implement a 500 error page here? -> in Varnish, there is a built-in error page mechanism if (HttpKernelInterface::MASTER_REQUEST === $type) { + $this->updateRequest($request); $this->traces = array(); $this->request = $request; if (null !== $this->esi) { @@ -664,4 +665,23 @@ private function record(Request $request, $event) } $this->traces[$request->getMethod().' '.$path][] = $event; } + + /** + * Set a Request to the same state a real reverse proxy would. + * + * @param Request $request A Request instance + */ + private function updateRequest(Request $request) + { + $forwardedFor = $request->server->get('REMOTE_ADDR'); + if (in_array($forwardedFor, array('127.0.0.1', 'fe80::1', '::1'))) { + return; + } + if ($currentlyForwardedFor = $request->headers->get('X_FORWARDED_FOR')) { + $forwardedFor = $currentlyForwardedFor . ', ' . $forwardedFor; + } + + $request->headers->set('X_FORWARDED_FOR', $forwardedFor); + $request->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 5060a696c2105..807591583c5f6 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -1034,4 +1034,24 @@ public function testEsiRecalculateContentLengthHeader() $this->assertEquals('Hello World!', $this->response->getContent()); $this->assertEquals(12, $this->response->headers->get('Content-Length')); } + + /** + * @dataProvider getIpForwardedForData + */ + public function testRequestIpForwardedFor($ip, $forwardedFor = null, $expectedForwardedFor = null) + { + $this->setNextResponse(200); + $this->request('GET', '/', array('REMOTE_ADDR' => $ip, 'HTTP_X_FORWARDED_FOR' => $forwardedFor)); + $this->assertEquals('127.0.0.1', $this->request->server->get('REMOTE_ADDR')); + $this->assertEquals($expectedForwardedFor, $this->request->headers->get('X_FORWARDED_FOR')); + } + + public function getIpForwardedForData() + { + return array( + array('10.20.30.40', null, '10.20.30.40'), + array('10.20.30.40', '11.22.33.44', '11.22.33.44, 10.20.30.40'), + array('127.0.0.1', null, null), + ); + } }