Skip to content

Cache-Control public/private directives set when not always required #53920

Closed
@donoskaro

Description

@donoskaro

Symfony version(s) affected

2.0.0 and greater

Description

This commit introduced a change whereby if the value of the s-maxage directive is not set, the private directive is added to the Cache-Control header (snippet pasted below for reference).

        // public if s-maxage is defined, private otherwise
        if (!isset($this->cacheControl['s-maxage'])) {
            return $header.', private';
        }

Additionally, this commit introduced a change whereby if the s-maxage directive is set, the public directive is added as well.

According to RFC 9111, including the s-maxage directive "permits a shared cache to reuse a response to a request containing an Authorization header field subject to the above requirements on maximum age and revalidation". Also, according to the same RFC, the public directive "permits a shared cache to reuse a response to a request containing an Authorization header field".

We can see that as per the RFC, there is an overlap between the s-maxage and public directives and including s-maxage does not necessarily require the use of public. Similarly, the lack of the s-maxage directive does indicate that the response should not be cached by a shared cache.

Therefore, HttpFoundation should not force the use of either the public or private directives when s-maxage is missing or present.

How to reproduce

// First, run "composer require symfony/http-foundation"
// Then, execute this file:
<?php
require_once __DIR__.'/vendor/autoload.php';
use Symfony\Component\HttpFoundation\Response;

// in this scenario, the 'private' directive should not be automatically set:
$response = new Response();

$response->setCache([
    'max_age' => 600,
]);

// expected: "max-age=600", got: "max-age=600, private"
var_dump($response->headers->get('Cache-Control'));

// in this scenario, the 'public' directive should not be automatically set:
$response = new Response();

$response->setCache([
    's_maxage' => 600,
]);

// expected: "s-maxage=600", got: "public, s-maxage=600"
var_dump($response->headers->get('Cache-Control'));

Possible Solution

Remove the automatic addition of the public and private directives when not explicitly defined (either by calling the setPublic/setPrivate methods or by defining appropriate keys when calling setCache).

Whilst this may be a breaking change as other developers may be relying on this behaviour to exist, a potential configuration flag could be added to allow 'strict' RFC 9111 headers to be generated.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions