.../page_cache/src/StackMiddleware/PageCache.php | 12 +++++++++++- core/modules/page_cache/src/Tests/PageCacheTest.php | 19 +++++++++++++++++++ .../src/Controller/SystemTestController.php | 9 +++++++++ .../tests/modules/system_test/system_test.routing.yml | 7 +++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/core/modules/page_cache/src/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php index 85a7275..b83433e 100644 --- a/core/modules/page_cache/src/StackMiddleware/PageCache.php +++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php @@ -225,7 +225,17 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch $date = $response->getExpires()->getTimestamp(); $expire = ($date > time()) ? $date : Cache::PERMANENT; - $tags = ($response instanceof CacheableResponseInterface) ? $response->getCacheableMetadata()->getCacheTags() : []; + $tags = []; + if ($response instanceof CacheableResponseInterface) { + $tags = $response->getCacheableMetadata()->getCacheTags(); + } + // The above (superior) mechanism to retrieve a response's cache tags was + // introduced during the RC phase. This exists to maintain backwards + // compatibility. + // @todo Remove in Drupal 9.0.0. + elseif ($response->headers->has('X-Drupal-Cache-Tags')) { + $tags = explode(' ', $response->headers->get('X-Drupal-Cache-Tags')); + } $this->set($request, $response, $expire, $tags); // Mark response as a cache miss. diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php index 262ab4c..17a1f73 100644 --- a/core/modules/page_cache/src/Tests/PageCacheTest.php +++ b/core/modules/page_cache/src/Tests/PageCacheTest.php @@ -111,6 +111,25 @@ function testPageCacheTagsIndependentFromCacheabilityHeaders() { } /** + * Tests that we retain BC: responses with X-Drupal-Cache-Tags headers should + * have cache tag-based invalidation support in the Page Cache. + */ + function testBackwardsCompatibilityResponseWithXDrupalCacheTagsHeader() { + $path = 'system-test/backwards_compatibility_response_with_x_drupal_cache_tags_header'; + $this->drupalGet($path); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); + $this->drupalGet($path); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); + $this->assertCacheTag('bar'); + + // Verify that invalidating cache tags in the X-Drupal-Cache-Tags header + // causes the corresponding Page Cache item to be invalidated. + Cache::invalidateTags(['bar']); + $this->drupalGet($path); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); + } + + /** * Tests support for different cache items with different request formats * specified via a query parameter. */ diff --git a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php index abd9022..6a29835 100644 --- a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php +++ b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php @@ -237,6 +237,15 @@ public function system_test_cache_maxage_page() { } /** + * A response with an X-Drupal-Cache-Tags header. For backwards compatibility. + * + * @todo Remove in Drupal 9.0.0. + */ + public function backwardsCompatibilityResponseWithXDrupalCacheTagsHeader() { + return new Response('', 200, ['X-Drupal-Cache-Tags' => 'foo bar']); + } + + /** * Sets a cache tag on an element to help test #pre_render and cache tags. */ public static function preRenderCacheTags($elements) { diff --git a/core/modules/system/tests/modules/system_test/system_test.routing.yml b/core/modules/system/tests/modules/system_test/system_test.routing.yml index 94a1bef..ca95c97 100644 --- a/core/modules/system/tests/modules/system_test/system_test.routing.yml +++ b/core/modules/system/tests/modules/system_test/system_test.routing.yml @@ -73,6 +73,13 @@ system_test.cache_maxage_page: requirements: _access: 'TRUE' +system_test.backwards_compatibility_response_with_x_drupal_cache_tags_header: + path: '/system-test/backwards_compatibility_response_with_x_drupal_cache_tags_header' + defaults: + _controller: '\Drupal\system_test\Controller\SystemTestController::backwardsCompatibilityResponseWithXDrupalCacheTagsHeader' + requirements: + _access: 'TRUE' + system_test.authorize_init: path: '/system-test/authorize-init/{page_title}' defaults: