8000 Fix surrogate not using original request · symfony/symfony@ab86f43 · GitHub
[go: up one dir, main page]

Skip to content

Commit ab86f43

Browse files
Toflarnicolas-grekas
authored andcommitted
Fix surrogate not using original request
1 parent 9f1d1d8 commit ab86f43

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,11 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
185185
// FIXME: catch exceptions and implement a 500 error page here? -> in Varnish, there is a built-in error page mechanism
186186
if (HttpKernelInterface::MASTER_REQUEST === $type) {
187187
$this->traces = array();
188-
$this->request = $request;
188+
// Keep a clone of the original request for surrogates so they can access it.
189+
// We must clone here to get a separate instance because the application will modify the request during
190+
// the application flow (we know it always does because we do ourselves by setting REMOTE_ADDR to 127.0.0.1
191+
// and adding the X-Forwarded-For header, see HttpCache::forward()).
192+
$this->request = clone $request;
189193
if (null !== $this->surrogate) {
190194
$this->surrogateCacheStrategy = $this->surrogate->createCacheStrategy();
191195
}

src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111

1212
namespace Symfony\Component\HttpKernel\Tests\HttpCache;
1313

14+
use Symfony\Component\HttpKernel\HttpCache\Esi;
1415
use Symfony\Component\HttpKernel\HttpCache\HttpCache;
1516
use Symfony\Component\HttpFoundation\Request;
1617
use Symfony\Component\HttpFoundation\Response;
18+
use Symfony\Component\HttpKernel\HttpCache\Store;
19+
use Symfony\Component\HttpKernel\HttpCache\StoreInterface;
1720
use Symfony\Component\HttpKernel\HttpKernelInterface;
1821

1922
/**
@@ -1432,6 +1435,42 @@ public function testDoesNotCacheOptionsRequest()
14321435
$this->assertHttpKernelIsNotCalled();
14331436
$this->assertSame('get', $this->response->getContent());
14341437
}
1438+
1439+
public function testUsesOriginalRequestForSurrogate()
1440+
{
1441+
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
1442+
$store = $this->getMockBuilder(StoreInterface::class)->getMock();
1443+
1444+
$kernel
1445+
->expects($this->exactly(2))
1446+
->method('handle')
1447+
->willReturnCallback(function (Request $request) {
1448+
$this->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
1449+
1450+
return new Response();
1451+
});
1452+
1453+
$cache = new HttpCache($kernel,
1454+
$store,
1455+
new Esi()
1456+
);
1457+
1458+
$request = Request::create('/');
1459+
$request->server->set('REMOTE_ADDR', '10.0.0.1');
1460+
1461+
// Main request
1462+
$cache->handle($request, HttpKernelInterface::MASTER_REQUEST);
1463+
1464+
// Main request was now modified by HttpCache
1465+
// The surrogate will ask for the request using $this->cache->getRequest()
1466+
// which MUST return the original request so the surrogate
1467+
// can actually behave like a reverse proxy like e.g. Varnish would.
1468+
$this->assertSame('10.0.0.1', $cache->getRequest()->getClientIp());
1469+
$this->assertSame('10.0.0.1', $cache->getRequest()->server->get('REMOTE_ADDR'));
1470+
1471+
// Surrogate request
1472+
$cache->handle($request, HttpKernelInterface::SUB_REQUEST);
1473+
}
14351474
}
14361475

14371476
class TestKernel implements HttpKernelInterface

0 commit comments

Comments
 (0)
0