Skip to content

Session indirectly started by RequestDataCollector in HttpKernel #25698

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
adamquaile opened this issue Jan 5, 2018 · 11 comments
Closed

Session indirectly started by RequestDataCollector in HttpKernel #25698

adamquaile opened this issue Jan 5, 2018 · 11 comments

Comments

@adamquaile
Copy link

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

In any environment where the profiler is enabled, I noticed Cache-control headers were not working correctly. This seems due to this bit of code, marking all requests in sessions as private with a max-age of 0 https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/EventListener/SaveSessionListener.php#L54 .

I wasn't aware my requests were actually using sessions, and on debugging with help in Slack, it looks like it's started by this RequestDataCollector as it doesn't check whether the session is started or not before inspecting it. Inspecting it starts the session, and overrides my cache headers.

The fix seems to be adding

if (!$event->getRequest()->getSession()->isStarted()) {
    return;
}

In https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php#L328

* I'm not sure exactly which symfony versions this affects, but it could have been introduced here: 95d0b72#diff-e8f5b14fbfbbeac60fc9f3abe310c3b0 . Does this commit need reverting or changing, or am I misunderstanding something?

@nicolas-grekas
Copy link
Member

Actually that's expected behavior: this page is not cachable - it used the session to be generated.
See #24774, which fixed the isStarted check.

@adamquaile
Copy link
Author

adamquaile commented Jan 5, 2018

@nicolas-grekas I don't quite understand, then. As my code didn't explicitly start and doesn't need it, can I disable the session functionality completely or is that required by the profiler to function?

@mvrhov
Copy link

mvrhov commented Jan 5, 2018

@nicolas-grekas: This is what I was talking about when you started the session refactoring. The framework or it's debug components shouldn't start the session unless it has been started by the developer's code explicitly.

@Tobion
Copy link
Contributor

Tobion commented Jan 6, 2018

This looks like a huge bug to me introduced with #25583. RequestDataCollector always starts the session and then SaveSessionListener will always mark the request uncachable due to #25583. So even if you don't use a session, the no cache headers will be set automatically.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Jan 6, 2018

As stated above, this is not a bug to me, and this is totally independent from #25583.
See #24774: the profiler cannot work without the session, so it has to use it.
This is just normal behavior and a side effect of using the profiler. Not doing so means re-introducing #24730.

@adamquaile
Copy link
Author

This make a little more sense to me now, so

A session is required for the profiler to work (to catch redirects I believe)

A session being started (even for an indirect reason such as this) means the response should be considered private, even if this could sometimes be inconvenient.

But, do we really need to setMaxAge(0) and override what a dev has specified as the cacheability for a response in their controller? And if we do, I think this should be clearly explained in the documentation on caching, as following the instructions in the docs in a dev environment don't seem to work right now.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Jan 6, 2018

Actually, this may be fixable: we should just not use the session to forward the sf_redirect array from one request to another, and just use a json_encoded cookie (or URL parameter BTW)!
@adamquaile would you like to give it a try?

@sroze
Copy link
Contributor

sroze commented Jan 7, 2018

we should just not use the session to forward the sf_redirect array from one request to another, and just use a json_encoded cookie

It's a tradeoff: using a cookie would mean that both the redirection and the target page will not be cachable (because of the Set-Cookie to set the sf_redirect and the one to clear it).

or URL parameter

IMHO that might confuse developers, but there are less hidden moving parts, so this might be a good idea, you've got my 👍 on this one.

Depending on the feedback, I'm happy to help going to either direction by PRing the changes.

@adamquaile
Copy link
Author

I think a URL parameter might be the simplest here, because there's no need to really clear it. I can imagine browser extensions or settings potentially causing more problems with cookies too. Happy to help on this when I next get a chance too, if that's the way people want to go.

@sroze
Copy link
Contributor

sroze commented Jan 8, 2018

The obvious problem is the URL parameter is that it requires the user to generates the URL using Symfony's router, and would require the HttpKernel component to know about it... which is not going to work well IMHO. The Cookie option seems to be the only suitable alternative.

@sroze
Copy link
Contributor

sroze commented Jan 8, 2018

See #25719

fabpot added a commit that referenced this issue Jan 8, 2018
…n (sroze)

This PR was merged into the 3.4 branch.

Discussion
----------

[HttpKernel] Uses cookies to track the requests redirection

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #25698
| License       | MIT
| Doc PR        | ø

In order to track the redirections across requests, we need to have some state. So far, we've been using the session but some users have complained about it (#24774, #24730). The idea is that we don't actually need the session, we can use cookies.

It's a tradeoff: using a cookie would mean that both the redirection and the target page will not be cachable (because of the Set-Cookie to set the sf_redirect and the one to clear it).

As it's only on dev, it seems fair to say that having no cache (because of `Set-Cookie`s) is a better side effect than starting the session.

Commits
-------

83f2579 Uses cookies to track the requests redirection
@fabpot fabpot closed this as completed Jan 8, 2018
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

8 participants