Problem/Motivation

In a module, I'm trying to configure time based access restriction so I use a _custom_access callback in which I return an AccessResult object on which I apply setCacheMaxAge(60) to ensure that access is checked once per minute.

The problem is that this access check never expires for anonymous users - even if I set the page cache max age to 60 seconds too.
Logged in users do not have the same issue.

The same problem occurs with page content.

I created a quick gist to illustrate : https://gist.github.com/DuaelFr/7a11327b8a5acaa5da30

Steps to reproduce

  1. install Drupal standard
  2. create a tiny module like shown in the gist above
  3. navigate to /test as anonymous
  4. wait between 61 and 119 seconds
  5. reload the page

Expected result :
Something changed

Current result :
Nothing changed

Proposed resolution

No idea.

Remaining tasks

Find out what's going on. Fix it.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

DuaelFr created an issue. See original summary.

duaelfr’s picture

Issue summary: View changes
dawehner’s picture

Well yeah, this is basically by design sort of.

fabianx’s picture

The workaround is to use:

- $attached['http_header']['Expires'] = time() + 60; (or a date format of it)

somewhere for _just_ this route.

While page cache does not use max-age header from a cacheable response, it does use the Expires header ...

duaelfr’s picture

@Fabianx thank you very much for that workaround.

I think that's quite a big problem, though. Any site builder can create a view block with time based cache from the interface and put it on any page of hir site. S/he cannot imagine that this View is going to be cached for ever for anonymous users. Could the page cache module become aware of that max-age setting somehow?

Aside, while reading the page_cache code, in \Drupal\page_cache\StackMiddleware\PageCache::fetch() I've seen that if the Expire header was leasser or equal to the result of time(), cache was considered as permanent. I'd understand that an empty or negative Expire could be considered as permanent but an outdated one should just be considered as expired, isn't it? At least, we should rely on REQUEST_TIME instead of time().
Let's imagine I set my expire header as time() + 2s then there is a long rendering process before the response goes to page_cache fetch. At this given moment the expire value could already be outdated and considered as permanent. Weird, no?
Do you think I'm right? If I am, I'll open a new issue about that problem.

wim leers’s picture

Status: Active » Closed (duplicate)

I think that's quite a big problem, though. Any site builder can create a view block with time based cache from the interface and put it on any page of hir site.

Agreed.

This is exactly what #2352009: Bubbling of elements' max-age to the page's headers and the page cache is about.