From b98e25a949cc7b79490ef9f89b049b2c3942c45b Mon Sep 17 00:00:00 2001 From: Andreas Schempp Date: Sun, 15 Apr 2018 08:28:27 +0200 Subject: [PATCH] Correctly merge mix of public and private responses If a response is flagged as public and others are flagged private, the merged response can be considered private-cacheable. --- .../HttpCache/ResponseCacheStrategy.php | 18 ++++++++++++++++-- .../HttpCache/ResponseCacheStrategyTest.php | 2 -- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php index 6737bfd839af5..eda29158627b7 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php @@ -36,7 +36,7 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface /** * Cache-Control headers that are sent to the final response if the appear in ALL of the responses. */ - private static $inheritDirectives = array('public', 'private', 'immutable'); + private static $inheritDirectives = array('immutable'); private $embeddedResponses = 0; private $isNotCacheableResponseEmbedded = false; @@ -76,6 +76,14 @@ public function add(Response $response) } } + if (false !== $this->flagDirectives['public']) { + $this->flagDirectives['public'] = $response->headers->hasCacheControlDirective('public'); + } + + if (false !== $this->flagDirectives['private']) { + $this->flagDirectives['private'] = $response->headers->hasCacheControlDirective('private') || $response->headers->hasCacheControlDirective('public'); + } + $age = $response->getAge(); $this->age = max($this->age, $age); @@ -124,7 +132,13 @@ public function update(Response $response) return; } - $response->headers->set('Cache-Control', implode(', ', array_keys(array_filter($this->flagDirectives)))); + $flags = array_filter($this->flagDirectives); + + if (isset($flags['public'], $flags['private'])) { + unset($flags['private']); + } + + $response->headers->set('Cache-Control', implode(', ', array_keys($flags))); if ($this->ageDirectives['max-age']) { $response->headers->addCacheControlDirective('max-age', $this->ageDirectives['max-age'] + $this->age); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php index 061c88fc501b1..2cd3c5023eb10 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php @@ -112,8 +112,6 @@ public function testValidationOnMasterResponseIsNotPossibleWhenItContainsEmbedde $this->assertFalse($masterResponse->isValidateable()); $this->assertFalse($masterResponse->headers->has('Last-Modified')); $this->assertFalse($masterResponse->headers->has('ETag')); -// $this->assertTrue($masterResponse->headers->hasCacheControlDirective('no-cache')); -// $this->assertTrue($masterResponse->headers->hasCacheControlDirective('must-revalidate')); } public function testMasterResponseWithValidationIsUnchangedWhenThereIsNoEmbeddedResponse()