diff -u b/core/modules/page_cache/src/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php --- b/core/modules/page_cache/src/StackMiddleware/PageCache.php +++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php @@ -249,14 +249,14 @@ // - Get the time expiration from the Expires header, rather than the // interface, but see https://www.drupal.org/node/2352009 about possibly // changing that. - $expire = FALSE; - // 404 responses can fill non-LRU cache backends and generally are likely to - // have a low cache hit rate. So do not cache them permanently. - if ($response->getStatusCode() === $response::HTTP_NOT_FOUND) { + $expire = 0; + // 403 and 404 responses can fill non-LRU cache backends and generally are + // likely to have a low cache hit rate. So do not cache them permanently. + if ($response->isNotFound() || $response->isForbidden()) { // Cache for an hour by default, or the max age, whichever is the smaller. - // If the ttl is set to FALSE then do not cache it. - $settings_ttl = Settings::get('404_cache_ttl', 3600); - if ($settings_ttl) { + // If the ttl is set to 0 then do not cache it. + $settings_ttl = Settings::get('negative_cache_ttl', 3600); + if ($settings_ttl > 0) { $max_age = $response->getMaxAge(); // The response's max_age will be negative in the case the response has // no time set. @@ -269,7 +269,7 @@ $expire = ($date > time()) ? $date : Cache::PERMANENT; } - if ($expire !== FALSE) { + if ($expire === Cache::PERMANENT || $expire > REQUEST_TIME) { $tags = $response->getCacheableMetadata()->getCacheTags(); $this->set($request, $response, $expire, $tags); } diff -u b/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php --- b/core/modules/page_cache/src/Tests/PageCacheTest.php +++ b/core/modules/page_cache/src/Tests/PageCacheTest.php @@ -376,20 +376,21 @@ $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); } - // Disable 404 caching - $settings['settings']['404_cache_ttl'] = (object) array( - 'value' => FALSE, + // Disable 403 and 404 caching. + $settings['settings']['negative_cache_ttl'] = (object) array( + 'value' => 0, 'required' => TRUE, ); $this->writeSettings($settings); \Drupal::service('cache.render')->deleteAll(); - // Getting the 404 page twice you still result in a cache miss. - $this->drupalGet($invalid_url); - $this->drupalGet($invalid_url); - $this->assertResponse(404); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - + foreach ($tests as $code => $content_url) { + // Getting the 404 page twice you still result in a cache miss. + $this->drupalGet($content_url); + $this->drupalGet($content_url); + $this->assertResponse($code); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); + } } /** diff -u b/sites/default/default.settings.php b/sites/default/default.settings.php --- b/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -422,14 +422,15 @@ /** - * Cache TTL for 404 responses. + * Cache TTL for 403 and 404 responses. * * Items cached per-URL tend to result in a large number of cache items, and * this can be problematic on 404 pages which by their nature are unbounded. A * fixed TTL can be set for these items, defaulting to one hour, so that cache - * backends which do not support LRU can purge older entries. + * backends which do not support LRU can purge older entries. To disable caching + * set the value to 0. */ -# $settings['404_cache_ttl'] = 3600; +# $settings['negative_cache_ttl'] = 3600; /**