From 011cd38974039bf378f9c7f68f96d85a633fd9c0 Mon Sep 17 00:00:00 2001 From: azjezz Date: Wed, 1 Apr 2020 11:36:04 +0100 Subject: [PATCH] [HttpFoundation] Add support for all core http control directives --- .../Component/HttpFoundation/CHANGELOG.md | 1 + .../Component/HttpFoundation/Response.php | 36 +++++++++++++++---- .../HttpFoundation/Tests/ResponseTest.php | 13 +++++++ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 4355b5af9a..e6ea6811e8 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -15,6 +15,7 @@ CHANGELOG * made the Mime component an optional dependency * added `MarshallingSessionHandler`, `IdentityMarshaller` * made `Session` accept a callback to report when the session is being used + * Add support for all core cache control directives 5.0.0 ----- diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index 072c4d22ba..fe35832f87 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -85,6 +85,24 @@ class Response const HTTP_NOT_EXTENDED = 510; // RFC2774 const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585 + /** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + */ + private const HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES = [ + 'must_revalidate' => false, + 'no_cache' => false, + 'no_store' => false, + 'no_transform' => false, + 'public' => false, + 'private' => false, + 'proxy_revalidate' => false, + 'max_age' => true, + 's_maxage' => true, + 'immutable' => false, + 'last_modified' => true, + 'etag' => true, + ]; + /** * @var ResponseHeaderBag */ @@ -921,7 +939,7 @@ class Response /** * Sets the response's cache headers (validation and/or expiration). * - * Available options are: etag, last_modified, max_age, s_maxage, private, public and immutable. + * Available options are: must_revalidate, no_cache, no_store, no_transform, public, private, proxy_revalidate, max_age, s_maxage, immutable, last_modified and etag. * * @return $this * @@ -931,7 +949,7 @@ class Response */ public function setCache(array $options): object { - if ($diff = array_diff(array_keys($options), ['etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'])) { + if ($diff = array_diff(array_keys($options), array_keys(static::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES))) { throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', $diff))); } @@ -951,6 +969,16 @@ class Response $this->setSharedMaxAge($options['s_maxage']); } + foreach (self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES as $directive => $hasValue) { + if (!$hasValue && isset($options[$directive])) { + if ($options[$directive]) { + $this->headers->addCacheControlDirective(str_replace('_', '-', $directive)); + } else { + $this->headers->removeCacheControlDirective(str_replace('_', '-', $directive)); + } + } + } + if (isset($options['public'])) { if ($options['public']) { $this->setPublic(); @@ -967,10 +995,6 @@ class Response } } - if (isset($options['immutable'])) { - $this->setImmutable((bool) $options['immutable']); - } - return $this; } diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php index 93714572a9..73a6936807 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php @@ -659,6 +659,19 @@ class ResponseTest extends ResponseTestCase $response->setCache(['immutable' => false]); $this->assertFalse($response->headers->hasCacheControlDirective('immutable')); + + $directives = ['proxy_revalidate', 'must_revalidate', 'no_cache', 'no_store', 'no_transform']; + foreach ($directives as $directive) { + $response->setCache([$directive => true]); + + $this->assertTrue($response->headers->hasCacheControlDirective(str_replace('_', '-', $directive))); + } + + foreach ($directives as $directive) { + $response->setCache([$directive => false]); + + $this->assertFalse($response->headers->hasCacheControlDirective(str_replace('_', '-', $directive))); + } } public function testSendContent()