When an entity bundle has Rabbit Hole configured to redirect to a value of a field on the entity (using tokens) and “Page cache maximum age” under Configuration > Performance is set to anything but "", for example 1 minute - 1 day, the site fails to create cache control headers for specifying max-age for the cached page. This can result in unpredictable caching behavior, depending on how the browser chooses to handle the absence of the cache control header. For instance, the browser may end up holding onto the page longer than you would like, regardless of whether or not drupal invalidates the associated entities cache. Some browsers are better at handling the absence of cache control tags than others; firefox seems to do terribly when this header field is absent.

Steps to Reproduce

  1. 1. Turn on anonymous page caching. Set “Page cache maximum age” under Configuration > Performance anything but "", for example 1 minute - 1 day.
  2. Configure Rabbit Hole's behavior on an entity bundle (content type, media bundle) to issue a page redirect.
  3. Set the Redirect Path to the url defined by a field value using tokens (for example: [media:field_document:entity:url].
  4. Set the Redirect Path to the url defined by a field value using tokens (for example: [media:field_document:entity:url].
  5. Create an entity, A.
  6. Turn on Developer Tools within your browser of choice, and switch to the Network Tab
  7. As an anonymous user view entity A. Experience, the redirect as you intended.
  8. View the Page Headers; notice the missing Cache Control Header
  9. Repeat the same steps, but using a brand new entity, with rabbit hole disabled(skip steps 2 & 3).
  10. View the Page Headers; notice the missing Cache Control Header.
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

freddya21 created an issue. See original summary.

freddya21’s picture

Issue Reported

japerry made their first commit to this issue’s fork.

japerry’s picture

Status: Active » Needs review

The originally reported bug is already fixed in current 8.x-1.x. I reproduced the exact scenario in ddev — token-based redirect ([node:author:uid]), cache.page.max_age = 300, anonymous request — and 301/302/303/307 all return Cache-Control: max-age=300, public correctly.

However, there are some other issues found while investigating this, specifically:

  • 304 / 305 use a bare Response, Not a CacheableResponseInterface, so core's FinishResponseSubscriber skips it entirely → Cache-Control: must-revalidate, no-cache, private, X-Drupal-Cache: UNCACHEABLE (no cacheability).
  • Bundle settings config tag missing: config:rabbit_hole.behavior_settings.* was reaching the response only incidentally. Editing a bundle's Rabbit Hole settings left cached redirects stale.
  • user.permissions never bubbled: BehaviorInvoker::getBehaviorPlugin() checks rabbit hole bypass but never records the context.
  • Entity not a cacheable dependency: PageRedirect relied on the token service happening to add the entity tag; a non-token redirect got no entity tag.
  • $cacheMetadata never reset: Accumulates across performAction() calls on a reused plugin instance.

The following MR fixes the above issues.

japerry’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

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