Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ CHANGELOG
* Add the `litespeed_finish_request` method to work with Litespeed
* Deprecate `upload_progress.*` and `url_rewriter.tags` session options
* Allow setting session options via DSN
* Add cache header stale-while-revalidate and stale-if-error RFC5861 support

5.3
---
Expand Down
43 changes: 43 additions & 0 deletions Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class Response
'proxy_revalidate' => false,
'max_age' => true,
's_maxage' => true,
'stale_if_error' => true, // RFC5861
'stale_while_revalidate' => true, // RFC5861
'immutable' => false,
'last_modified' => true,
'etag' => true,
Expand Down Expand Up @@ -796,6 +798,39 @@ public function setMaxAge(int $value): object
return $this;
}


/**
* Sets the number of seconds after which the response should no longer be returned by shared caches when backend is down.
*
* This methods sets the Cache-Control stale-if-error directive.
*
* @return $this
*
* @final
*/
public function setStaleIfError(int $value): object
{
$this->headers->addCacheControlDirective('stale-if-error', $value);

return $this;
}

/**
* Sets the number of seconds after which the response should no longer return stale content by shared caches.
*
* This methods sets the Cache-Control stale-while-revalidate directive.
*
* @return $this
*
* @final
*/
public function setStaleWhileRevalidate(int $value): object
{
$this->headers->addCacheControlDirective('stale-while-revalidate', $value);

return $this;
}

/**
* Sets the number of seconds after which the response should no longer be considered fresh by shared caches.
*
Expand Down Expand Up @@ -969,6 +1004,14 @@ public function setCache(array $options): object
$this->setSharedMaxAge($options['s_maxage']);
}

if (isset($options['stale_while_revalidate'])) {
$this->setStaleWhileRevalidate($options['stale_while_revalidate']);
}

if (isset($options['stale_if_error'])) {
$this->setStaleIfError($options['stale_if_error']);
}

foreach (self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES as $directive => $hasValue) {
if (!$hasValue && isset($options[$directive])) {
if ($options[$directive]) {
Expand Down
38 changes: 38 additions & 0 deletions Tests/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,44 @@ public function testSetSharedMaxAge()
$this->assertEquals('public, s-maxage=20', $cacheControl);
}

public function testSetStaleIfError()
{
$response = new Response();
$response->setSharedMaxAge(20);
$response->setStaleIfError(86400);

$cacheControl = $response->headers->get('Cache-Control');
$this->assertEquals('public, s-maxage=20, stale-if-error=86400', $cacheControl);
}

public function testSetStaleWhileRevalidate()
{
$response = new Response();
$response->setSharedMaxAge(20);
$response->setStaleWhileRevalidate(300);

$cacheControl = $response->headers->get('Cache-Control');
$this->assertEquals('public, s-maxage=20, stale-while-revalidate=300', $cacheControl);
}

public function testSetStaleIfErrorWithoutSharedMaxAge()
{
$response = new Response();
$response->setStaleIfError(86400);

$cacheControl = $response->headers->get('Cache-Control');
$this->assertEquals('stale-if-error=86400, private', $cacheControl);
}

public function testSetStaleWhileRevalidateWithoutSharedMaxAge()
{
$response = new Response();
$response->setStaleWhileRevalidate(300);

$cacheControl = $response->headers->get('Cache-Control');
$this->assertEquals('stale-while-revalidate=300, private', $cacheControl);
}

public function testIsPrivate()
{
$response = new Response();
Expand Down