bug #10896 [HttpKernel] Fixed cache behavior when TTL has expired and a default "global" TTL is defined (alquerci, fabpot)
This PR was merged into the 2.3 branch. Discussion ---------- [HttpKernel] Fixed cache behavior when TTL has expired and a default "global" TTL is defined | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | no | Fixed tickets | #8232, #10822, #9919 | License | MIT From #9919: "When the cache is stale the `validate` method `forward` the request to the backend. A new response will be created with or without TTL configuration. If the TTL was not set then the default one should be set like in the `fetch` method." This PR fixes this issue, the tests provided in #9919 pass, and I've tweaked them to avoid the costly sleep calls. Commits -------e3983e8
[HttpKernel] fixed default TTL not applied under certain conditionsbc42dae
Added test when TTL has expired
This commit is contained in:
commit
a44945a306
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -593,6 +593,107 @@ 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()
|
||||
{
|
||||
$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->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'));
|
||||
|
||||
// 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->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->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
|
||||
|
||||
$this->setNextResponse();
|
||||
|
||||
$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()
|
||||
{
|
||||
$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->request('GET', '/');
|
||||
$this->assertHttpKernelIsNotCalled();
|
||||
$this->assertEquals(200, $this->response->getStatusCode());
|
||||
$this->assertTraceContains('fresh');
|
||||
$this->assertTraceNotContains('store');
|
||||
$this->assertEquals('Hello World', $this->response->getContent());
|
||||
|
||||
// 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->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->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
|
||||
|
||||
$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()
|
||||
|
|
Reference in New Issue