Follow-up to #2476407: Use CacheableResponseInterface to determine which responses should be cached

Problem/Motivation

PageCache caches 'no-store' and 'private' responses. There is no way except for a ResponsePolicy to make a response uncacheable.

That is a bug.

#2476407: Use CacheableResponseInterface to determine which responses should be cached has test coverage for PageCache and intended to test this behavior, but it does not work correctly. (Bug in tests)

Proposed resolution

At minimum do:

diff --git a/core/modules/page_cache/src/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php
index 23ddb84..5a1d99c 100644
--- a/core/modules/page_cache/src/StackMiddleware/PageCache.php
+++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php
@@ -220,6 +220,10 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch
       return $response;
     }
 
+    if ($response->headers->hasCacheControlDirective('no-store') || $response->headers->getCacheControlDirective('private')) {
+      return $response;
+    }
+
     // Use the actual timestamp from an Expires header, if available.
     $date = $response->getExpires()->getTimestamp();
     $expire = ($date > time()) ? $date : Cache::PERMANENT;

Remaining tasks

- Patch it
- Fix tests

User interface changes

- None

API changes

- no-store and private responses are no longer cached, but that should have been the case already from an Expectation point-of-view since #2476407: Use CacheableResponseInterface to determine which responses should be cached, so it is not a true API change. Just fixing behavior that should have been fixed already.

Comments

Fabianx created an issue. See original summary.

fabianx’s picture

Issue tags: +rc target triage
berdir’s picture

This isn't going to work as expected right now.

If you disable *external* caching on the performance settings page, then we send a private header, but we still cache it in the internal page cache. That's a perfectly valid reason IMHO. For example, browsers respect max-age partially and cache pages. We've seen that on some of our D8 sites, despite cache tag invalidation working perfectly with fastly, you had to force re-fresh in the browser to see the updated page. That's why we now send a very short max-age but a separate header to control caching on fastly.

This would obviously break that.

znerol’s picture

@Berdir very much agree on the edge-cache vs browser-cache difference. This still seems to confuse people working at cacheability issues.

Would it be acceptable to only apply the proposed restriction to plain Symfony responses? I.e., if there is cacheability metadata available exclusively use that to determine whether or not to store it (and for how long), and for plain Symfony responses implement the logic used in HttpCache.

effulgentsia’s picture

Given the above comments, should this now be closed as "by design" now that as of #2527126: Only send X-Drupal-Cache-Tags and -Contexts headers when developer explicitly enables them, PageCache only caches CacheableResponseInterface responses? Or is there more to do here? I like the idea of letting CacheableResponseInterface be the sole API for PageCache, and leaving response headers for external caches (proxies and browsers), but not sure if there's something about this issue that still makes sense to do.

xjm’s picture

Issue tags: -rc target triage +Needs issue summary update

Thanks for tagging this for rc target triage! To have committers consider it for inclusion in RC, we should add a statement to the issue summary of why we need to make this change during RC, including what happens if we do not make the change and what any disruptions from it are. We can add a section <h3>Why this should be an RC target</h3> to the summary.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
catch’s picture

Status: Active » Closed (works as designed)