Skip to content

Commit

Permalink
[HttpFoundation] added support for must-revalidate and proxy-revalida…
Browse files Browse the repository at this point in the history
…te cache control directives in Response#setCache()
  • Loading branch information
axiac committed Jul 30, 2015
1 parent c980c3f commit cc92569
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
41 changes: 39 additions & 2 deletions src/Symfony/Component/HttpFoundation/Response.php
Expand Up @@ -590,6 +590,27 @@ public function mustRevalidate()
return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->hasCacheControlDirective('proxy-revalidate');
}


/**
* Indicates that the response must not be served stale by a shared cache
* in any circumstance without first revalidating with the origin.
*
* This methods sets the Cache-Control public and proxy-revalidate directives.
* The public directive is needed because private responses must not be stored by a shared cache.
* (a private cache control directive renders proxy-revalidate useless)
*
* @return Response
*
* @api
*/
public function setProxyRevalidate()
{
$this->setPublic();
$this->headers->addCacheControlDirective('proxy-revalidate');

return $this;
}

/**
* Returns the Date header as a DateTime instance.
*
Expand Down Expand Up @@ -888,7 +909,7 @@ public function setEtag($etag = null, $weak = false)
/**
* Sets the response's cache headers (validation and/or expiration).
*
* Available options are: etag, last_modified, max_age, s_maxage, private, and public.
* Available options are: etag, last_modified, max_age, s_maxage, must_revalidate, proxy_revalidate, private, and public.
*
* @param array $options An array of cache options
*
Expand All @@ -900,7 +921,7 @@ public function setEtag($etag = null, $weak = false)
*/
public function setCache(array $options)
{
if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public'))) {
if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'must_revalidate', 'proxy_revalidate', 'private', 'public'))) {
throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff))));
}

Expand All @@ -920,6 +941,22 @@ public function setCache(array $options)
$this->setSharedMaxAge($options['s_maxage']);
}

if (isset($options['must_revalidate'])) {
if ($options['must_revalidate']) {
$this->headers->addCacheControlDirective('must-revalidate');
} else {
$this->headers->removeCacheControlDirective('must-revalidate');
}
}

if (isset($options['proxy_revalidate'])) {
if ($options['proxy_revalidate']) {
$this->setProxyRevalidate();
} else {
$this->headers->removeCacheControlDirective('proxy-revalidate');
}
}

if (isset($options['public'])) {
if ($options['public']) {
$this->setPublic();
Expand Down
29 changes: 28 additions & 1 deletion src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php
Expand Up @@ -92,6 +92,15 @@ public function testMustRevalidate()
$this->assertFalse($response->mustRevalidate());
}

public function testProxyRevalidate()
{
$response = new Response();
$response->setProxyRevalidate();
$this->assertTrue($response->mustRevalidate());
$this->assertTrue($response->headers->hasCacheControlDirective('public'));
$this->assertTrue($response->headers->hasCacheControlDirective('proxy-revalidate'));
}

public function testSetNotModified()
{
$response = new Response();
Expand Down Expand Up @@ -495,7 +504,7 @@ public function testPrepareSetsPragmaOnHttp10Only()
public function testSetCache()
{
$response = new Response();
//array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public')
//array('etag', 'last_modified', 'max_age', 's_maxage', 'must_revalidate', 'proxy_revalidate', 'private', 'public')
try {
$response->setCache(array('wrong option' => 'value'));
$this->fail('->setCache() throws an InvalidArgumentException if an option is not supported');
Expand Down Expand Up @@ -524,6 +533,22 @@ public function testSetCache()
$this->assertTrue($response->headers->hasCacheControlDirective('public'));
$this->assertFalse($response->headers->hasCacheControlDirective('private'));

$response->setCache(array('must_revalidate' => true));
$this->assertTrue($response->headers->hasCacheControlDirective('must-revalidate'));
$this->assertTrue($response->mustRevalidate());

$response->setCache(array('must_revalidate' => false));
$this->assertFalse($response->headers->hasCacheControlDirective('must-revalidate'));

$response->setCache(array('proxy_revalidate' => true));
$this->assertTrue($response->headers->hasCacheControlDirective('public'));
$this->assertFalse($response->headers->hasCacheControlDirective('private'));
$this->assertTrue($response->headers->hasCacheControlDirective('proxy-revalidate'));
$this->assertTrue($response->mustRevalidate());

$response->setCache(array('proxy_revalidate' => false));
$this->assertFalse($response->headers->hasCacheControlDirective('proxy-revalidate'));

$response->setCache(array('public' => true));
$this->assertTrue($response->headers->hasCacheControlDirective('public'));
$this->assertFalse($response->headers->hasCacheControlDirective('private'));
Expand Down Expand Up @@ -761,12 +786,14 @@ public function testSettersAreChainable()
'setCharset' => 'UTF-8',
'setPublic' => null,
'setPrivate' => null,
'setProxyRevalidate' => null,
'setDate' => new \DateTime(),
'expire' => null,
'setMaxAge' => 1,
'setSharedMaxAge' => 1,
'setTtl' => 1,
'setClientTtl' => 1,
'setCache' => array(),
);

foreach ($setters as $setter => $arg) {
Expand Down

0 comments on commit cc92569

Please sign in to comment.