From bc42dae162bcab809cfd817363c21a3159470d37 Mon Sep 17 00:00:00 2001 From: alquerci Date: Tue, 31 Dec 2013 17:23:37 +0100 Subject: [PATCH 1/2] Added test when TTL has expired --- .../Tests/HttpCache/HttpCacheTest.php | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index 50a1de907d..c54caf832e 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -595,6 +595,89 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('Hello World', $this->response->getContent()); } + public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpired() + { + $this->setNextResponse(); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertTraceContains('miss'); + $this->assertTraceContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + + sleep(4); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('stale'); + $this->assertTraceContains('invalid'); + $this->assertTraceContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + } + + public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpiredWithStatus304() + { + $this->setNextResponse(); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertTraceContains('miss'); + $this->assertTraceContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + + sleep(4); + + $this->setNextResponse(304); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('stale'); + $this->assertTraceContains('valid'); + $this->assertTraceContains('store'); + $this->assertTraceNotContains('miss'); + $this->assertEquals('Hello World', $this->response->getContent()); + + $this->cacheConfig['default_ttl'] = 2; + $this->request('GET', '/'); + $this->assertHttpKernelIsNotCalled(); + $this->assertEquals(200, $this->response->getStatusCode()); + $this->assertTraceContains('fresh'); + $this->assertTraceNotContains('store'); + $this->assertEquals('Hello World', $this->response->getContent()); + } + public function testDoesNotAssignDefaultTtlWhenResponseHasMustRevalidateDirective() { $this->setNextResponse(200, array('Cache-Control' => 'must-revalidate')); From e3983e8ec584311d6eced6a8547eae5a6113e8df Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 12 May 2014 17:25:47 +0200 Subject: [PATCH 2/2] [HttpKernel] fixed default TTL not applied under certain conditions --- .../HttpKernel/HttpCache/HttpCache.php | 12 +++--- .../Tests/HttpCache/HttpCacheTest.php | 38 ++++++++++++++----- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 2bea9f58ba..871b3a87fc 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -428,12 +428,6 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $response = $this->forward($subRequest, $catch); - if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { - $response->setPrivate(true); - } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) { - $response->setTtl($this->options['default_ttl']); - } - if ($response->isCacheable()) { $this->store($request, $response); } @@ -487,6 +481,12 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $this->processResponseBody($request, $response); + if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { + $response->setPrivate(true); + } elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) { + $response->setTtl($this->options['default_ttl']); + } + return $response; } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php index c54caf832e..e08f198281 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php @@ -593,6 +593,7 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=10/', $this->response->headers->get('Cache-Control')); } public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpired() @@ -607,17 +608,25 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('Hello World', $this->response->getContent()); $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - sleep(4); + // expires the cache + $values = $this->getMetaStorageValues(); + $this->assertCount(1, $values); + $tmp = unserialize($values[0]); + $time = \DateTime::createFromFormat('U', time()); + $tmp[0][1]['date'] = \DateTime::createFromFormat('U', time() - 5)->format(DATE_RFC2822); + $r = new \ReflectionObject($this->store); + $m = $r->getMethod('save'); + $m->setAccessible(true); + $m->invoke($this->store, 'md'.sha1('http://localhost/'), serialize($tmp)); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsCalled(); $this->assertEquals(200, $this->response->getStatusCode()); @@ -625,14 +634,17 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceContains('invalid'); $this->assertTraceContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); + + $this->setNextResponse(); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); } public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpiredWithStatus304() @@ -647,7 +659,6 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertEquals('Hello World', $this->response->getContent()); $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); @@ -655,11 +666,17 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); - sleep(4); + // expires the cache + $values = $this->getMetaStorageValues(); + $this->assertCount(1, $values); + $tmp = unserialize($values[0]); + $time = \DateTime::createFromFormat('U', time()); + $tmp[0][1]['date'] = \DateTime::createFromFormat('U', time() - 5)->format(DATE_RFC2822); + $r = new \ReflectionObject($this->store); + $m = $r->getMethod('save'); + $m->setAccessible(true); + $m->invoke($this->store, 'md'.sha1('http://localhost/'), serialize($tmp)); - $this->setNextResponse(304); - - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsCalled(); $this->assertEquals(200, $this->response->getStatusCode()); @@ -668,14 +685,15 @@ class HttpCacheTest extends HttpCacheTestCase $this->assertTraceContains('store'); $this->assertTraceNotContains('miss'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); - $this->cacheConfig['default_ttl'] = 2; $this->request('GET', '/'); $this->assertHttpKernelIsNotCalled(); $this->assertEquals(200, $this->response->getStatusCode()); $this->assertTraceContains('fresh'); $this->assertTraceNotContains('store'); $this->assertEquals('Hello World', $this->response->getContent()); + $this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control')); } public function testDoesNotAssignDefaultTtlWhenResponseHasMustRevalidateDirective()