HTTP Cache Control needs documentation that the max_age value cannot be the same as a response code value

Created on 22 April 2022, over 2 years ago
Updated 7 February 2023, almost 2 years ago

Problem/Motivation

Recently, our team noticed an issue in which our 404 error pages had an s-max-age of 30 days, despite them being defined as 5 minutes. After doing some sleuthing, we determined that this line was causing the issue: https://git.drupalcode.org/project/http_cache_control/-/blob/8.x-2.x/src...

Because we had the regular max-age (the browser max-age) and the 404 max-age both set to be 5 minutes, this conditional did not pass. Thus, our 404 pages were receiving our 'global' s-max-age, rather than the max-age defined in the settings.

Changing the max-age from 5 minutes to 3 minutes resolved this situation. However, we only came to this solution after reviewing the module's code -- this limitation is not explained anywhere else.

Proposed resolution

Either document on the module page or in the System Performance settings form that these values cannot be the same.

πŸ› Bug report
Status

Needs review

Version

2.0

Component

Documentation

Created by

πŸ‡ΊπŸ‡ΈUnited States kmonty San Francisco, CA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΈπŸ‡ͺSweden kevineinarsson

    Attached a test + patch (not a clean patch but it... works(?)) Maybe need to check if these values are null too.

  • Status changed to Needs work almost 2 years ago
  • πŸ‡ΈπŸ‡ͺSweden kevineinarsson

    The patch doesn't work, s-maxage and max-age are always set to the same value.
    The configuration form says that the 3xx/404/5xx max-age value should be the same as 200 responses. If that's the case, why is setClientTtl called?

  • First commit to issue fork.
  • πŸ‡§πŸ‡ͺBelgium dieterholvoet Brussels

    I don't understand how the code even gets past $response->isCacheable(). That method contains the following logic:

    public function isCacheable(): bool
    {
        if (!\in_array($this->statusCode, [200, 203, 300, 301, 302, 404, 410])) {
            return false;
        }
        if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
            return false;
        }
        return $this->isValidateable() || $this->isFresh();
    }
    

    It explicitly disables caching for 404/302/301 responses, so if I'm understanding correctly the max-ages provided by this module for those status codes are never used, right?

  • πŸ‡§πŸ‡ͺBelgium dieterholvoet Brussels

    A couple things I don't understand either about the current code:

    1. Why are the 404/302/301 TTL's being assigned to the maxage, even though their setting descriptions state they are only being used for s-maxages?
    2. Why is setClientTtl() used for max-ages and setSharedMaxAge() for s-maxages? The former considers the Age header, the latter doesn't.
    3. Why is the s-maxage set when it's the same as the max-age?
    4. Why is the configured s-maxage only used when it's > 0?

    I'm afraid that fixing the first one would require a new major release. It's undocumented behaviour, but still behavior that people might depend on. I started a MR fixing 1, 2 and 3, which in turn also fixes this issue. I did keep the last one for now, but I decided to document it in the form.

    Existing and new tests are passing, but it would be great if @josh waihi could review, just to make sure we're not missing anything here.

Production build 0.71.5 2024