Skip to content

Unable to cache expensive requests that need Session #26242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
christiaan opened this issue Feb 20, 2018 · 10 comments
Closed

Unable to cache expensive requests that need Session #26242

christiaan opened this issue Feb 20, 2018 · 10 comments

Comments

@christiaan
Copy link

christiaan commented Feb 20, 2018

Q A
Bug report? yes
Feature request? no
BC Break report? yes
RFC? no
Symfony version ^3.4.3

I have a controller that responds with a photo, the photo is private and the user needs to be authenticated and authorized to access it. The photo is encrypted and needs to be decrypted on each request. This is why I like the browser to cache the photo.

Using the following this used to work pre 3.4.3

        $response->setMaxAge(604800 /* 1 week */);
        $response->setPrivate();

In #25583 this behaviour has changed that if a session is started nothing can be cached.

I do understand that if the user logs out that the photo would still be in the browser cache but that is a risk I am willing to accept in turn for the huge performance boost.

How would I go about and implement this now?

@christiaan
Copy link
Author

christiaan commented Feb 20, 2018

@nicolas-grekas seeing as you mostly oversaw the changes in #25583

The problem I have with the change from #25583 is that besides what it describes it does it also does the following actions.

               ->setMaxAge(0)
               ->headers->addCacheControlDirective('must-revalidate');

In my opinion it is up to the implementation to determine if the request can be privately cached and requires revalidation.

I am curious to hear why caching is completely disallowed.

@mvrhov
Copy link

mvrhov commented Feb 21, 2018

Duplicate of #26245?

@christiaan
Copy link
Author

Could be, but from my limited understanding I would say it is different.

This used to work. That was always broken?

@mvrhov
Copy link

mvrhov commented Feb 21, 2018

No this was "broken" with session refactoring.

@nicolas-grekas
Copy link
Member

This is actually a duplicate of #26237, and is not a BC break, but a bugfix.

@xabbuh
Copy link
Member

xabbuh commented Feb 22, 2018

closing as a duplicate of #26237

@xabbuh xabbuh closed this as completed Feb 22, 2018
@smurfy
Copy link

smurfy commented Mar 1, 2018

Well this issue is a bit different than mine. (#26237)

I had the problem that i have actions which use the user and actions which do not.
If session is started all actions get no-cache headers. (which is good)

My fix was easy i separated the user needing and not needing actions within my security.yml,
so only actions which are using the user are protected by a "firewall" and start the session.

@christiaan has the problem that he wants to cache private responses, which the change breaks.
Since using max-age cache headers with cache private is within the specs and the settings gets overwritten. i say this is either a BC break or a Bug on symfonys part.

In my opinion either the listener should not touch the cache headers if already private or the headers set should be configurable. OR even both options.

Also that everything is in an abstract class does not help overwriting this any easier.
Only almost clean way i can think of is creating another listener which runs after and strips the unwanted headers out.

@clement-garrigou
Copy link

My fix was easy i separated the user needing and not needing actions within my security.yml,
so only actions which are using the user are protected by a "firewall" and start the session.

@smurfy could you give me more details ? Can you give me the part of the security.yml ?

Thanks !

@smurfy
Copy link

smurfy commented Mar 29, 2018

@clement-garrigou

Well i added all routes which needs auth to the patterns.
If you have "subpaths" like /user or something can make the patterns shorter.
Hope this helps.

This way only the routes matching the firewalls pattern actually start the session.
Every other route does not and therefore do not overwrite the cache-headers.

security:
    ....
    firewalls:
        main:
            pattern: ^/(login|logout|register|resetting|change-password)
            ....

    access_control:
        - { path: ^(logout|change-password), role: IS_AUTHENTICATED_REMEMBERED}
        - { path: ^(login|register|resetting), role: IS_AUTHENTICATED_ANONYMOUSLY}

@clement-garrigou
Copy link

@smurfy It works, thank you very much !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants