Skip to content

Commit 92e5c4d

Browse files
committed
feature #45166 [HttpFoundation] add stale while revalidate cache header (remieuronews)
This PR was merged into the 6.1 branch. Discussion ---------- [HttpFoundation] add stale while revalidate cache header | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Feat (symfony/symfony#45036) | License | MIT | Doc PR | [symfony/symfony-docs#... <!-- required for new features -->](symfony/symfony-docs#16445) This PR allow support for RFC5861. Meaning you can now use stale_while_revalidate and stale_if_error https://httpwg.org/specs/rfc5861.html Very interesting doc from Fastly on the subject: https://developer.fastly.com/learning/concepts/stale/ Link to the issue symfony/symfony#45036 Commits ------- db553fb9f3 [cache] #45109 add stale while revalidate and stale if error cache header
2 parents f549e7a + d4a5ed1 commit 92e5c4d

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.1
5+
---
6+
7+
* Add stale while revalidate and stale if error cache header
8+
49
6.0
510
---
611

Response.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class Response
9898
'proxy_revalidate' => false,
9999
'max_age' => true,
100100
's_maxage' => true,
101+
'stale_if_error' => true, // RFC5861
102+
'stale_while_revalidate' => true, // RFC5861
101103
'immutable' => false,
102104
'last_modified' => true,
103105
'etag' => true,
@@ -773,6 +775,38 @@ public function setMaxAge(int $value): static
773775
return $this;
774776
}
775777

778+
/**
779+
* Sets the number of seconds after which the response should no longer be returned by shared caches when backend is down.
780+
*
781+
* This method sets the Cache-Control stale-if-error directive.
782+
*
783+
* @return $this
784+
*
785+
* @final
786+
*/
787+
public function setStaleIfError(int $value): static
788+
{
789+
$this->headers->addCacheControlDirective('stale-if-error', $value);
790+
791+
return $this;
792+
}
793+
794+
/**
795+
* Sets the number of seconds after which the response should no longer return stale content by shared caches.
796+
*
797+
* This method sets the Cache-Control stale-while-revalidate directive.
798+
*
799+
* @return $this
800+
*
801+
* @final
802+
*/
803+
public function setStaleWhileRevalidate(int $value): static
804+
{
805+
$this->headers->addCacheControlDirective('stale-while-revalidate', $value);
806+
807+
return $this;
808+
}
809+
776810
/**
777811
* Sets the number of seconds after which the response should no longer be considered fresh by shared caches.
778812
*
@@ -946,6 +980,14 @@ public function setCache(array $options): static
946980
$this->setSharedMaxAge($options['s_maxage']);
947981
}
948982

983+
if (isset($options['stale_while_revalidate'])) {
984+
$this->setStaleWhileRevalidate($options['stale_while_revalidate']);
985+
}
986+
987+
if (isset($options['stale_if_error'])) {
988+
$this->setStaleIfError($options['stale_if_error']);
989+
}
990+
949991
foreach (self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES as $directive => $hasValue) {
950992
if (!$hasValue && isset($options[$directive])) {
951993
if ($options[$directive]) {

Tests/ResponseTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,44 @@ public function testSetSharedMaxAge()
358358
$this->assertEquals('public, s-maxage=20', $cacheControl);
359359
}
360360

361+
public function testSetStaleIfError()
362+
{
363+
$response = new Response();
364+
$response->setSharedMaxAge(20);
365+
$response->setStaleIfError(86400);
366+
367+
$cacheControl = $response->headers->get('Cache-Control');
368+
$this->assertEquals('public, s-maxage=20, stale-if-error=86400', $cacheControl);
369+
}
370+
371+
public function testSetStaleWhileRevalidate()
372+
{
373+
$response = new Response();
374+
$response->setSharedMaxAge(20);
375+
$response->setStaleWhileRevalidate(300);
376+
377+
$cacheControl = $response->headers->get('Cache-Control');
378+
$this->assertEquals('public, s-maxage=20, stale-while-revalidate=300', $cacheControl);
379+
}
380+
381+
public function testSetStaleIfErrorWithoutSharedMaxAge()
382+
{
383+
$response = new Response();
384+
$response->setStaleIfError(86400);
385+
386+
$cacheControl = $response->headers->get('Cache-Control');
387+
$this->assertEquals('stale-if-error=86400, private', $cacheControl);
388+
}
389+
390+
public function testSetStaleWhileRevalidateWithoutSharedMaxAge()
391+
{
392+
$response = new Response();
393+
$response->setStaleWhileRevalidate(300);
394+
395+
$cacheControl = $response->headers->get('Cache-Control');
396+
$this->assertEquals('stale-while-revalidate=300, private', $cacheControl);
397+
}
398+
361399
public function testIsPrivate()
362400
{
363401
$response = new Response();

0 commit comments

Comments
 (0)