Skip to content
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

Wrong typing for expires in set_cookie #1878

Closed
maartenbreddels opened this issue Sep 30, 2022 · 14 comments · Fixed by #1908
Closed

Wrong typing for expires in set_cookie #1878

maartenbreddels opened this issue Sep 30, 2022 · 14 comments · Fixed by #1908
Labels
feature New feature or request good first issue Good for beginners refactor Refactor code typing Type annotations or mypy issues

Comments

@maartenbreddels
Copy link

I think the type for

expires: typing.Optional[int] = None,

This should be a date according to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

So I think a better type is Optional[str] , or Optional[str | datetime] and provide the right formatting.

@Kludex
Copy link
Member

Kludex commented Sep 30, 2022

I have the feeling we had this discussion before... Need to find where. 🤔

EDIT: Maybe not?
EDIT2: It was not discussed before.

maartenbreddels added a commit to widgetti/solara that referenced this issue Sep 30, 2022
See encode/starlette#1878

and the get_directories argument has changed, but we don't use it.
@Kludex
Copy link
Member

Kludex commented Sep 30, 2022

Hold on... Does the field expires is even used by the browser as is?

EDIT: It is, I've checked on Google Chrome. It works as if it was seconds. Can someone double check this?

@Kludex
Copy link
Member

Kludex commented Sep 30, 2022

Based on RFC-6265, we should send a string in cookie date format, as the OP said.

We have even reference in code using expires as it should (introduced 4 years ago in #158):

header_value = "{session_cookie}={data}; path={path}; {expires}{security_flags}".format( # noqa E501
session_cookie=self.session_cookie,
data="null",
path=self.path,
expires="expires=Thu, 01 Jan 1970 00:00:00 GMT; ",
security_flags=self.security_flags,
)

@Kludex
Copy link
Member

Kludex commented Sep 30, 2022

Questions:

  1. Why the current expires works?
  2. Should we change the type from Optional[int] (Union[int, None]) to Union[int, str, None]?
  3. Should we accept datetime instead, and let Starlette format as cookie date?

@Kludex Kludex added feature New feature or request typing Type annotations or mypy issues refactor Refactor code labels Sep 30, 2022
@maartenbreddels
Copy link
Author

  1. I think it doesn't work (maybe on chrome) when you pass an int, but ignoring typing you can safely pass a str in the right format (as I do now).
  2. I think Optional[Union[datetime, str]] makes the most sense, as I don't think int is described in any standard (that I know of)
  3. that would be great.

@Kludex
Copy link
Member

Kludex commented Oct 3, 2022

It would be cool to understand why it works on Chrome 👀

@Kludex
Copy link
Member

Kludex commented Oct 4, 2022

PR welcome to change the type annotation, and add datetime, with conversion to the format mentioned.

@oskipa
Copy link
Contributor

oskipa commented Oct 8, 2022

Hi, there! I created a pull request adding the changes requested by @Kludex . I made a point to follow them strictly.

As I was working on the issue, two questions came to me, which I think it is good to discuss.

  1. Integers are used by other frameworks to set expiration dates in seconds. So even though one can argue that integers are not valid cookie date tokens, it has been interpreted so by other frameworks, servers, and browsers

  2. This change may break existing code.

For these two reasons, I would suggest to add int to the allow types, for this value to be cast to string, and then set as the expiration date, as a courtesy for existing code.

If we want to insist that int shouldn't be allowed, we could add the suggestion above along with a deprecated warning about supporting ints for expirations.

Again, these are suggestions. This is the first time I have attempted to contribute to this project, so whatever you decide is best :) Thanks for making this beautiful framework.

@maartenbreddels
Copy link
Author

maartenbreddels commented Oct 11, 2022 via email

@Kludex
Copy link
Member

Kludex commented Oct 11, 2022

Integers are used by other frameworks to set expiration dates in seconds. So even though one can argue that integers are not valid cookie date tokens, it has been interpreted so by other frameworks, servers, and browsers

Which frameworks, servers and browsers?

@foolishhugo
Copy link

Integers are used by other frameworks to set expiration dates in seconds. So even though one can argue that integers are not valid cookie date tokens, it has been interpreted so by other frameworks, servers, and browsers

Which frameworks, servers and browsers?

Php, for example, uses seconds from epoch, https://www.php.net/manual/en/function.setcookie.php

I thought I saw more examples, but maybe it was just PHP :)

@Kludex
Copy link
Member

Kludex commented Oct 22, 2022

@maartenbreddels if we just accept datetime it's enough for you, right?

@maartenbreddels
Copy link
Author

I would also support string, unless I’m 100+% sure with datetime we can cover the whole spec (which in reality is unlikely). The risk of adding no escape hatch is just too high in practice. So I’d say datetime | str to be safe.

@Kludex
Copy link
Member

Kludex commented Oct 24, 2022

Why is it unlikely?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request good first issue Good for beginners refactor Refactor code typing Type annotations or mypy issues
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants