From 728a19220b69f8ff1185ce934765d860186b2081 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 3 Mar 2022 11:39:01 +0100 Subject: [PATCH] [HttpKernel] Remove private headers before storing responses with HttpCache --- HttpCache/Store.php | 20 +++++++++++++++++--- Tests/HttpCache/StoreTest.php | 13 +++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/HttpCache/Store.php b/HttpCache/Store.php index eeb7a6ef94..43bd7c8082 100644 --- a/HttpCache/Store.php +++ b/HttpCache/Store.php @@ -26,19 +26,29 @@ class Store implements StoreInterface { protected $root; private $keyCache; - private $locks; + private $locks = []; + private $options; /** + * Constructor. + * + * The available options are: + * + * * private_headers Set of response headers that should not be stored + * when a response is cached. (default: Set-Cookie) + * * @throws \RuntimeException */ - public function __construct(string $root) + public function __construct(string $root, array $options = []) { $this->root = $root; if (!file_exists($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) { throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root)); } $this->keyCache = new \SplObjectStorage(); - $this->locks = []; + $this->options = array_merge([ + 'private_headers' => ['Set-Cookie'], + ], $options); } /** @@ -215,6 +225,10 @@ public function write(Request $request, Response $response) $headers = $this->persistResponse($response); unset($headers['age']); + foreach ($this->options['private_headers'] as $h) { + unset($headers[strtolower($h)]); + } + array_unshift($entries, [$storedEnv, $headers]); if (!$this->save($key, serialize($entries))) { diff --git a/Tests/HttpCache/StoreTest.php b/Tests/HttpCache/StoreTest.php index da1f649127..239361bc8c 100644 --- a/Tests/HttpCache/StoreTest.php +++ b/Tests/HttpCache/StoreTest.php @@ -12,8 +12,10 @@ namespace Symfony\Component\HttpKernel\Tests\HttpCache; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpCache\HttpCache; use Symfony\Component\HttpKernel\HttpCache\Store; class StoreTest extends TestCase @@ -317,6 +319,17 @@ public function testPurgeHttpAndHttps() $this->assertEmpty($this->getStoreMetadata($requestHttps)); } + public function testDoesNotStorePrivateHeaders() + { + $request = Request::create('https://example.com/foo'); + $response = new Response('foo'); + $response->headers->setCookie(Cookie::fromString('foo=bar')); + + $this->store->write($request, $response); + $this->assertArrayNotHasKey('set-cookie', $this->getStoreMetadata($request)[0][1]); + $this->assertNotEmpty($response->headers->getCookies()); + } + protected function storeSimpleEntry($path = null, $headers = []) { if (null === $path) {