Problem/Motivation

See #606840-92: Enable internal page cache by default, plus comments #95, #96 and #97.

Caused by #2443073: Add #cache[max-age] to disable caching and bubble the max-age's adding of

    // If an explicit non-infinite max-age is specified by a part of the page,
    // respect that by applying it to the response's headers.
    if ($cache_max_age !== Cache::PERMANENT) {
      $response->setMaxAge($cache_max_age);
    }

Which only was possible due to lacking test coverage.

Critical because:

That completely breaks reverse proxies? And If that's not a release-blocking bug, then I don't know what is? :)

(@Berdir in #606840-96: Enable internal page cache by default)

Proposed resolution

Revert that hunk and add test coverage. This is what @Berdir proposed in #606840-96: Enable internal page cache by default:

The max_age setting and the max-age bubbling seem to contradict each other, and we know that bubbling doesn't actually work yet, as long as many things are still setting max-age: 0. So I think we should disable that setMaxAge() until we know that it actually works as expected *and* is implemented in a way that doesn't break the other headers? Which we should probably be set unconditionally anyway? And then we can also remove the global max_age setting.

Remaining tasks

Do it.

User interface changes

None.

API changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers’s picture

Issue summary: View changes

IS updated.

Wim Leers’s picture

Issue tags: +Novice, +php-novice
Berdir’s picture

Thanks for creating the issue, I was too lazy again. +1 obviously, since it's my own suggestion :)

Fabianx’s picture

My take on that is:

- Make the default -1 == CACHE::Permanent and expose it in the UI
- External proxy and internal cache override max-age with the configured value IF the user is anonymous, else max-age = 0

We should support max-age bubbling for page cache and external proxies at some other point though.

xjm’s picture

Title: max-age on HTML responses wrongly set to `max-age=0, private` instead of `max-age=N, public` » max-age on HTML responses wrongly set to `max-age=0, private` instead of `max-age=N, public` (breaks reverse proxies)
Wim Leers’s picture

Title: max-age on HTML responses wrongly set to `max-age=0, private` instead of `max-age=N, public` (breaks reverse proxies) » max-age on HTML responses wrongly set to `max-age=0, private` instead of `max-age=N, public` (breaks reverse proxies and client-side caching)
jan.stoeckler’s picture

Assigned: Unassigned » jan.stoeckler

I'll take a shot at this one.

xjm’s picture

Issue tags: +D8 Accelerate Dev Days
mr.baileys’s picture

Hey @jan.tsoeckler, are you still working on this one?

jan.stoeckler’s picture

Status: Active » Needs review
FileSize
2.81 KB

Sorry this took so long, I can't for the life of me figure out why the two added tests don't work as intended.

mr.baileys’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
    @@ -176,9 +174,6 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
         // If an explicit non-infinite max-age is specified by a part of the page,
         // respect that by applying it to the response's headers.
    

    The comment should also be reverted.

  2. +++ b/core/modules/system/src/Tests/Bootstrap/PageCacheTest.php
    @@ -227,6 +227,20 @@ function testPageCache() {
    +    // Check that max-age on HTML responses is persistent.
    +    $config->set('cache.page.max_age', 0);
    +    $config->save();
    +    $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar')));
    +    $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'must-revalidate, no-cache, post-check=0, pre-check=0, private', 'Cache-Control max-age (0) header is persistent.');
    +
    +    // @todo: make the following line nicer.
    +    drupal_flush_all_caches();
    +
    +    $config->set('cache.page.max_age', 300);
    +    $config->save();
    +    $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar')));
    +    $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control max-age (300) header is persistent.');
    +
    

    If I understand correctly, this issue is about the fact that when #cache max-age is set explicitly on any element, it bubbles up the stack up until it causes setMaxAge() to be called on the response (which is the change being reverted in this issue), and causes the the Cache-Control header to contain "max-age: 0, private" instead of the standard cache header (with max-age set to page.cache.max_age).

    This test however seems to only test setting max_age on the page cache, not on elements itself, so I don't think correctly provides coverage for this issue.

    In any case, could you upload the test separately? That way you can verify that the test fails, while your patch together with the test succeeds (if that is the case, it proves that your test correctly covers the bug.)

The last submitted patch, 10: 2467041-10_cache_max_age_persistence.patch, failed testing.

jan.stoeckler’s picture

Thanks for your review! I'm not quite sure whether or not bubbling is supposed to be supported at this point (I may well misconstrue the issue summary, though), so maybe this issue is just a bit too out of my wheelhouse. Anyway, uploaded the updated patch & the test separately.

jan.stoeckler’s picture

Status: Needs work » Needs review

Forgot to change status, sorry (again).

The last submitted patch, 13: 2467041-12_cache_max_age_persistence.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 13: 2467041-12_cache_max_age_persistence-test-only.patch, failed testing.

jan.stoeckler’s picture

Assigned: jan.stoeckler » Unassigned

I'm taking myself off this issue, there's no way I'm going to fix it in an appropriate time frame.

mr.baileys’s picture

Assigned: Unassigned » mr.baileys
Status: Needs work » Needs review
FileSize
4.27 KB
2.94 KB

I talked to Wim Leers to determine how to best test this, patch attached.

Fabianx’s picture

Status: Needs review » Reviewed & tested by the community

RTBC, both patch and test look great to me.

We can always bring the code back when we properly support it.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/system/src/Tests/Bootstrap/PageCacheTest.php
@@ -236,6 +236,13 @@ function testPageCache() {
+    $this->assertNotEqual($this->drupalGetHeader('Cache-Control'), 'max-age=0, private');
+    $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public');

Surely only the positive assertion is necessary? And we is the 300 coming from? The default configuration? We should get it from whether it is coming from.

mr.baileys’s picture

Status: Needs work » Needs review
FileSize
4.18 KB
  • The max-age=300 is set at the start of the test.
  • Removed the unnecessary assertion.
Fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC, we indeed only need to check once.

mr.baileys’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
4.17 KB

... and fixed a typo in a comment.

mr.baileys’s picture

Status: Needs review » Reviewed & tested by the community

cross-post.

The last submitted patch, 18: maxage-bubbling-2467041-17-test-only.patch, failed testing.

znerol’s picture

+1. Is there any issue to make the max-age bubbling actually work?

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

This issue addresses a critical bug and is allowed per https://www.drupal.org/core/beta-changes. Committed 3bc5a5c and pushed to 8.0.x. Thanks!

I think the issue to fix this is #2352009: [pp-3] Bubbling of elements' max-age to the page's headers and the page cache

  • alexpott committed 3bc5a5c on 8.0.x
    Issue #2467041 by mr.baileys, jan.stoeckler: max-age on HTML responses...
Wim Leers’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.