Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[HttpFoundation] Add Request::isStateless method #57852

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
wants to merge 7 commits into from

Conversation

VincentLanglet
Copy link
Contributor

@VincentLanglet VincentLanglet commented Jul 27, 2024

Q A
Branch? 7.2
Bug fix? no
New feature? no
Deprecations? no
Issues Related to #57502 but does not fix it
License MIT

I think asking the user to check everywhere in his code for

$request->attributes->get('_stateless')

before accessing getSession is kinda verbose and rely on some internal knowledge about how symfony describe the request as stateless.

It's easier for the developer to write

if (!$request->isStateless() && $request->hasSession()) {

rather than having to know the "internal attribute" to check

if (!$request->attributes->getBoolean('_stateless') && $request->hasSession()) {

So I propose to introduce this method as a facade to the internal attribute.

@VincentLanglet VincentLanglet requested a review from chalasr as a code owner July 27, 2024 18:03
@carsonbot carsonbot added this to the 7.2 milestone Jul 27, 2024
@carsonbot carsonbot changed the title Introduce Request::isStateless method [HttpFoundation] Introduce Request::isStateless method Jul 27, 2024
@VincentLanglet VincentLanglet force-pushed the stateless branch 3 times, most recently from 53e5d30 to 5719dcb Compare July 27, 2024 19:15
@OskarStark OskarStark changed the title [HttpFoundation] Introduce Request::isStateless method [HttpFoundation] Add Request::isStateless method Jul 28, 2024
Copy link
Member

@xabbuh xabbuh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new method should also be documented in the changelog file of the HttpFoundation component.

@VincentLanglet
Copy link
Contributor Author

I tried to resolve the suggestion from @fabpot (#57852 (comment)) in the latest commit aa9e241

If we want to have only one place to deal with _stateless logic, we have to provide a way to know

  • When the stateless attribute is set to false/true
  • When the stateless attribute is not set (the has check)

This may be done by having a nullable boolean as return type of the isStateless method.

That doesn't change a lot to the check !$request->isStateless() since null and false behave the same way, but this allow to check null !== $request->isStateless() to reproduce the check $request->attributes->has('_stateless').

WDYT ?

@stof
Copy link
Member

stof commented Jul 29, 2024

having isStateless return bool|null looks weird to me as the name indicate a boolean.

Code wanting to guard session reads will only need a boolean anyway (as they don't need to distinguish the default case).
Special places needing to distinguish a request marked explicitly as stateful vs the default case (no explicit configuration) can check the attribute directly (and I doubt we will have lots of such use cases outside the core)

@VincentLanglet
Copy link
Contributor Author

having isStateless return bool|null looks weird to me as the name indicate a boolean.

Code wanting to guard session reads will only need a boolean anyway (as they don't need to distinguish the default case). Special places needing to distinguish a request marked explicitly as stateful vs the default case (no explicit configuration) can check the attribute directly (and I doubt we will have lots of such use cases outside the core)

I reverted this in a17bfcd then @stof

@VincentLanglet VincentLanglet requested review from stof and fabpot July 29, 2024 11:57
@nicolas-grekas
Copy link
Member

After my comment in #57854 (comment), I'm wondering if this is common enough to deserve a dedicated method. I feel like this builds on a wrong definition of the _stateless attribute.

@VincentLanglet
Copy link
Contributor Author

I feel like this builds on a wrong definition of the _stateless attribute.

I'm not sure to understand where is the wrong definition

Well it all boils down if you consider stateless as a check or as a directive.

The blog post which introduced it reads

Routes can now configure a stateless boolean option. If set to true, they declare that session won't be used during the handling of the request.

Note that it is written declare, not force.

If it doesn't force the session to be stateless, then this check shouldn't exists

if ($this->debug) {
throw new UnexpectedSessionUsageException('Session was used while the request was declared stateless.');
}
if ($this->container->has('logger')) {
$this->container->get('logger')->warning('Session was used while the request was declared stateless.');
}

And even if it's still a declaration, a way to know if the request is stateless should exists (in order to know if the session is useful/usable or not) and therefore a method would be better than having to know which private attribute is used.

@MatTheCat
Copy link
Contributor

MatTheCat commented Aug 14, 2024

Isn't isStateless a misleading name? What it returns is if the request is supposed to be stateless; if it has been configured as such.

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Aug 14, 2024

Isn't isStateless a misleading name? What it returns is if the request is supposed to be stateless; if it has been configured as such.

Do you have a suggestion @MatTheCat ? "ShouldBeStateless" ?

I understand isStateless as "is declared Stateless", which is ok with your definition here: #57854 (comment)

@MatTheCat
Copy link
Contributor

shouldBeStateless sounds good to me indeed.

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Aug 14, 2024

shouldBeStateless sounds good to me indeed.

Currently there is already some FirewallConfig::isStateless method. This one is not misleading ?

And setStateless is ok for the setter ?

@MatTheCat
Copy link
Contributor

MatTheCat commented Aug 15, 2024

Currently there is already some FirewallConfig::isStateless method. This one is not misleading ?

FirewallConfig::isStateless returns true if you configured the firewall stateless. Why would that be misleading?

When you configure a route stateless, you’re asking Symfony to warn you if the session is used. This does not offer any guarantee regarding the fact the session is used or not. As such, you cannot use this information to tell if the request is stateless or not. That’s why I think Request::isStateless is not a good name.

And setStateless is ok for the setter ?

Do you have use-cases in mind where a setter would make sense (if yes the name would be wrong the same way it is wrong for the getter)? 🤔

@VincentLanglet
Copy link
Contributor Author

Currently there is already some FirewallConfig::isStateless method. This one is not misleading ?

FirewallConfig::isStateless returns true if you configured the firewall stateless. Why would that be misleading?

When you configure a route stateless, you’re asking Symfony to warn you if the session is used. This does not offer any guarantee regarding the fact the session is used or not. As such, you cannot use this information to tell if the request is stateless or not. That’s why I think Request::isStateless is not a good name.

IMHO part of my misunderstanding come from the fact that FirewallConfig::isStateless imply the fact that request is flagged as stateless. Reverting this behavior, as asked in #50715 (comment) would solve all my issues and avoid the need of this method.

And setStateless is ok for the setter ?

Do you have use-cases in mind where a setter would make sense (if yes the name would be wrong the same way it is wrong for the getter)? 🤔

No, it was just to be used in Symfony code (in order to avoid having to know the private attribute when setting it, but using the getter when accessing it).

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Aug 16, 2024

I'd rather be 👎 here, reading the attribute is fine, and the setter doesn't really make sense to me. This gives too much visibility to the setting IMHO.

@chalasr
Copy link
Member

chalasr commented Aug 16, 2024

Symfony does not enforce requests to be fully stateless so isStateless would potentially bring false impressions, and I don’t get the need for shouldBeStateless() in userland.
Let’s close. Thanks for proposing @VincentLanglet.

@VincentLanglet
Copy link
Contributor Author

Symfony does not enforce requests to be fully stateless so isStateless would potentially bring false impressions, and I don’t get the need for shouldBeStateless() in userland. Let’s close. Thanks for proposing @VincentLanglet.

Yes, and personally I never used stateless request, I just needed a check because the request was declared stateless when I use stateless firewall...
Since #58017 is merged, I won't need to check it again.

@derrabus
Copy link
Member

I have worked on several applications that made unnecessarily heavy use of the session before the decision was made to transition towards a RESTful API. It has always been hard to trace down where the stateless request processing is "tainted" by an unexpected session access. I think, Symfony could implement tooling to help with such a transition.

Maybe this PR wasn't the right way (and the now-reverted logic for auto-flagging requests in stateless firewalls wasn't either), but I think we should continue talking about how we could tackle stateful/stateless requests better. Maybe we should start over with an issue where we could discuss the topic?

@VincentLanglet
Copy link
Contributor Author

Maybe this PR wasn't the right way (and the now-reverted logic for auto-flagging requests in stateless firewalls wasn't either), but I think we should continue talking about how we could tackle stateful/stateless requests better. Maybe we should start over with an issue where we could discuss the topic?

Do you think the discussion could be done in the issue #57502 @derrabus or it would require a different one ?

@94noni
Copy link
Contributor

94noni commented Aug 16, 2024

reading PRs/issues/discussions on such request stateless topic, we can see the "misleading/misusage" of such point
same as you on this

Maybe we should start over with an issue where we could discuss the topic?

I do think this is a good starting point yes (or use existing one?)

@derrabus
Copy link
Member

Do you think the discussion could be done in the issue #57502 @derrabus or it would require a different one ?

I missed that one. Of course, let's continue the discussion there.

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

Successfully merging this pull request may close these issues.