diff --git a/src/AbstractPrivateCache.php b/src/AbstractPrivateCache.php index ec373ec2..aec36822 100644 --- a/src/AbstractPrivateCache.php +++ b/src/AbstractPrivateCache.php @@ -28,6 +28,12 @@ protected function getCacheObject(ResponseInterface $response) return null; } + if (in_array("no-cache", $cacheControlDirectives)) { + // Stale response (RFC 7234 5.2.1.4) + $entry = new CacheEntry($response, new \DateTime('-1 seconds')); + return $entry->hasValidationInformation() ? $entry : null; + } + foreach ($cacheControlDirectives as $directive) { $matches = []; diff --git a/src/CacheEntry.php b/src/CacheEntry.php index c065cb93..60fd6433 100644 --- a/src/CacheEntry.php +++ b/src/CacheEntry.php @@ -99,4 +99,12 @@ public function serveStaleIfError() return (bool)$this->staleIfError; } + /** + * @return bool + */ + public function hasValidationInformation() + { + return $this->response->hasHeader("Etag") || $this->response->hasHeader("Last-Modified"); + } + } diff --git a/tests/HeaderCacheControlTest.php b/tests/HeaderCacheControlTest.php index b4989f7e..21ad89e0 100644 --- a/tests/HeaderCacheControlTest.php +++ b/tests/HeaderCacheControlTest.php @@ -35,6 +35,16 @@ public function setUp() (new Response()) ->withAddedHeader("Cache-Control", "no-store") ); + case '/no-cache': + if ($request->getHeaderLine("If-None-Match") == "TheHash") { + return new FulfilledPromise(new Response(304)); + } + + return new FulfilledPromise( + (new Response()) + ->withAddedHeader("Cache-Control", "no-cache") + ->withAddedHeader("Etag", "TheHash") + ); } throw new \InvalidArgumentException(); @@ -68,4 +78,12 @@ public function testNoStoreHeader() $this->assertEquals("", $response->getHeaderLine("X-Cache")); } + public function testNoCacheHeader() + { + $this->client->get("http://test.com/no-cache"); + + $response = $this->client->get("http://test.com/no-cache"); + $this->assertEquals("HIT with validation", $response->getHeaderLine("X-Cache")); + } + } \ No newline at end of file