8000 [HttpKernel] Be smarter when merging cache directives in HttpCache/Re… · symfony/symfony@a243bca · GitHub
[go: up one dir, main page]

Skip to content

Commit a243bca

Browse files
[HttpKernel] Be smarter when merging cache directives in HttpCache/ResponseCacheStrategy
1 parent c572e6c commit a243bca

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

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

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
3030
{
3131
private $cacheable = true;
3232
private $embeddedResponses = 0;
33+
private $cacheDirectives = array(
34+
'no-cache' => false,
35+
'no-store' => false,
36+
'must-revalidate' => false,
37+
'private' => false,
38+
'proxy-revalidate' => false,
39+
);
3340
private $ttls = array();
3441
private $maxAges = array();
3542
private $isNotCacheableResponseEmbedded = false;
@@ -41,6 +48,17 @@ public function add(Response $response)
4148
{
4249
if (!$response->isFresh() || !$response->isCacheable()) {
4350
$this->cacheable = false;
51+
52+
$hasCacheDirective = $response->headers->hasCacheControlDirective('public');
53+
foreach ($this->cacheDirectives as $directive => $status) {
54+
if ($response->headers->hasCacheControlDirective($directive)) {
55+
$this->cacheDirectives[$directive] = $hasCacheDirective = true;
56+
}
57+
}
58+
59+
if (!$hasCacheDirective || !$response->isFresh()) {
60+
$this->cacheDirectives['no-cache'] = $this->cacheDirectives['must-revalidate'] = true;
61+
}
4462
} else {
4563
$maxAge = $response->getMaxAge();
4664
$this->ttls[] = $response->getTtl();
@@ -72,19 +90,14 @@ public function update(Response $response)
7290
$response->setLastModified(null);
7391
}
7492

75-
if (!$response->isFresh()) {
76-
$this->cacheable = false;
77-
}
93+
$this->add($response);
7894

7995
if (!$this->cacheable) {
80-
$response->headers->set('Cache-Control', 'no-cache, must-revalidate');
96+
$response->headers->set('Cache-Control', implode(', ', array_keys(array_filter($this->cacheDirectives))));
8197

8298
return;
8399
}
84100

85-
$this->ttls[] = $response->getTtl();
86-
$this->maxAges[] = $response->getMaxAge();
87-
88101
if ($this->isNotCacheableResponseEmbedded) {
89102
$response->headers->removeCacheControlDirective('s-maxage');
90103
} elseif (null !== $maxAge = min($this->maxAges)) {

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,24 @@ public function testResponseIsExpirableButNotValidateableWhenMasterResponseCombi
219219
$this->assertSame('60', $masterResponse->headers->getCacheControlDirective('s-maxage'));
220220
$this->assertFalse($masterResponse->isValidateable());
221221
}
222+
223+
public function testResponseIsPrivateWhenCombiningPrivateResponses()
224+
{
225+
$cacheStrategy = new ResponseCacheStrategy();
226+
227+
$masterResponse = new Response();
228+
$masterResponse->setSharedMaxAge(60);
229+
$masterResponse->setPrivate();
230+
231+
$embeddedResponse = new Response();
232+
$embeddedResponse->setSharedMaxAge(60);
233+
$embeddedResponse->setPrivate();
234+
235+
$cacheStrategy->add($embeddedResponse);
236+
$cacheStrategy->update($masterResponse);
237+
238+
$this->assertFalse($masterResponse->headers->hasCacheControlDirective('no-cache'));
239+
$this->assertFalse($masterResponse->headers->hasCacheControlDirective('must-revalidate'));
240+
$this->assertTrue($masterResponse->headers->hasCacheControlDirective('private'));
241+
}
222242
}

0 commit comments

Comments
 (0)
0