8000 [HttpFoundation] Add support for all core http control directives · symfony/symfony@9e20d79 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e20d79

Browse files
committed
[HttpFoundation] Add support for all core http control directives
1 parent 2130465 commit 9e20d79

File tree

3 files changed

+69
-29
lines changed

3 files changed

+69
-29
lines changed

src/Symfony/Component/HttpFoundation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CHANGELOG
1515
* made the Mime component an optional dependency
1616
* added `MarshallingSessionHandler`, `IdentityMarshaller`
1717
* made `Session` accept a callback to report when the session is being used
18+
* Add support for all core cache control directives
1819

1920
5.0.0
2021
-----

src/Symfony/Component/HttpFoundation/Response.php

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ class Response
8585
const HTTP_NOT_EXTENDED = 510; // RFC2774
8686
const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585
8787

88+
/**
89+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
90+
*/
91+
private const HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES = [
92+
'must_revalidate' => false,
93+
'no_cache' => false,
94+
'no_store' => false,
95+
'no_transform' => false,
96+
'public' => false,
97+
'private' => false,
98+
'proxy_revalidate' => false,
99+
'max_age' => true,
100+
's_maxage' => true,
101+
'immutable' => false,
102+
'last_modified' => true,
103+
'etag' => true
104+
];
105+
88106
/**
89107
* @var ResponseHeaderBag
90108
*/
@@ -893,35 +911,10 @@ public function getEtag(): ?string
893911
return $this->headers->get('ETag');
894912
}
895913

896-
/**
897-
* Sets the ETag value.
898-
*
899-
* @param string|null $etag The ETag unique identifier or null to remove the header
900-
* @param bool $weak Whether you want a weak ETag or not
901-
*
902-
* @return $this
903-
*
904-
* @final
905-
*/
906-
public function setEtag(string $etag = null, bool $weak = false): object
907-
{
908-
if (null === $etag) {
909-
$this->headers->remove('Etag');
910-
} else {
911-
if (0 !== strpos($etag, '"')) {
912-
$etag = '"'.$etag.'"';
913-
}
914-
915-
$this->headers->set('ETag', (true === $weak ? 'W/' : '').$etag);
916-
}
917-
918-
return $this;
919-
}
920-
921914
/**
922915
* Sets the response's cache headers (validation and/or expiration).
923916
*
924-
* Available options are: etag, last_modified, max_age, s_maxage, private, public and immutable.
917+
* Available options are: must_revalidate, no_cache, no_store, no_transform, public, private, proxy_revalidate, max_age, s_maxage, immutable, last_modified and etag.
925918
*
926919
* @return $this
927920
*
@@ -931,7 +924,7 @@ public function setEtag(string $etag = null, bool $weak = false): object
931924
*/
932925
public function setCache(array $options): object
933926
{
934-
if ($diff = array_diff(array_keys($options), ['etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'])) {
927+
if ($diff = array_diff(array_keys($options), array_keys(static::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES))) {
935928
throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', $diff)));
936929
}
937930

@@ -951,6 +944,18 @@ public function setCache(array $options): object
951944
$this->setSharedMaxAge($options['s_maxage']);
952945
}
953946

947+
foreach (self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES as $directive => $hasValue) {
948+
if (!$hasValue) {
949+
if (isset($options[$directive])) {
950+
if ($options[$directive]) {
951+
$this->headers->addCacheControlDirective(str_replace('_', '-', $directive));
952+
} else {
953+
$this->headers->removeCacheControlDirective(str_replace('_', '-', $directive));
954+
}
955+
}
956+
}
957+
}
958+
954959
if (isset($options['public'])) {
955960
if ($options['public']) {
956961
$this->setPublic();
@@ -967,8 +972,29 @@ public function setCache(array $options): object
967972
}
968973
}
969974

970-
if (isset($options['immutable'])) {
971-
$this->setImmutable((bool) $options['immutable']);
975+
return $this;
976+
}
977+
978+
/**
979+
* Sets the ETag value.
980+
*
981+
* @param string|null $etag The ETag unique identifier or null to remove the header
982+
* @param bool $weak Whether you want a weak ETag or not
983+
*
984+
* @return $this
985+
*
986+
* @final
987+
*/
988+
public function setEtag(string $etag = null, bool $weak = false): object
989+
{
990+
if (null === $etag) {
991+
$this->headers->remove('Etag');
992+
} else {
993+
if (0 !== strpos($etag, '"')) {
994+
$etag = '"'.$etag.'"';
995+
}
996+
997+
$this->headers->set('ETag', (true === $weak ? 'W/' : '').$etag);
972998
}
973999

9741000
return $this;

src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,19 @@ public function testSetCache()
659659

660660
$response->setCache(['immutable' => false]);
661661
$this->assertFalse($response->headers->hasCacheControlDirective('immutable'));
662+
663+
$directives = ['proxy_revalidate', 'must_revalidate', 'no_cache', 'no_store', 'no_transform'];
664+
foreach ($directives as $directive) {
665+
$response->setCache([$directive => true]);
666+
667+
$this->assertTrue($response->headers->hasCacheControlDirective(str_replace('_', '-', $directive)));
668+
}
669+
670+
foreach ($directives as $directive) {
671+
$response->setCache([$directive => false]);
672+
673+
$this->assertFalse($response->headers->hasCacheControlDirective(str_replace('_', '-', $directive)));
674+
}
662675
}
663676

664677
public function testSendContent()

0 commit comments

Comments
 (0)
0