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

feat(websocket): add support for reason in WebSocket.close() #2056

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

wendy5667
Copy link

@wendy5667 wendy5667 commented Apr 21, 2022

Summary of Changes

This PR adds reason to Websocket.close() as specified in version 2.3 of the HTTP & WebSocket ASGI Message Format. Closure due to HTTPErrors are rendered automatically from HTTP status code, while others are rendered by a default mapping, which could be changed by users.

Related Issues

Closes #2025

Pull Request Checklist

  • Applied changes to both WSGI and ASGI code paths and interfaces (where applicable).
  • Added tests for changed code.
  • Prefixed code comments with GitHub nick and an appropriate prefix.
  • Coding style is consistent with the rest of the framework.
  • Updated documentation for changed code.
    • Added docstrings for any new classes, functions, or modules.
    • Updated docstrings for any modifications to existing code.
    • Updated both WSGI and ASGI docs (where applicable).
    • Added references to new classes, functions, or modules to the relevant RST file under docs/.
    • Updated all relevant supporting documentation files under docs/.
    • A copyright notice is included at the top of any new modules (using your own name or the name of your organization).
    • Changed/added classes/methods/functions have appropriate versionadded, versionchanged, or deprecated directives.
  • Changes (and possible deprecations) have towncrier news fragments under docs/_newsfragments/, with the file name format {issue_number}.{fragment_type}.rst. (Run towncrier --draft to ensure it renders correctly.)

@codecov
Copy link

codecov bot commented Apr 21, 2022

Codecov Report

Merging #2056 (d3a0e51) into master (1850381) will not change coverage.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##            master     #2056   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           55        55           
  Lines         5553      5587   +34     
  Branches       880       888    +8     
=========================================
+ Hits          5553      5587   +34     
Impacted Files Coverage Δ
falcon/asgi/app.py 100.00% <100.00%> (ø)
falcon/asgi/ws.py 100.00% <100.00%> (ø)
falcon/testing/helpers.py 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Copy link
Member

@vytas7 vytas7 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR @wendy5667, and sorry we've been slow to review this. 👿

It looks great at first glance, particularly additions to the test suite. 💯

I'm yet to read this thoroughly... just posting a couple of potential mprovements off the top of my head:

  • We need to write a newsfragment for the new feature you've implemented.
  • I'm not sure if we can always send() a reason indiscriminately inside an ASGI WebSocket protocol message. Maybe it's safer to only include a reason iff we've verified we're dealing with ASGI HTTP+WebSocket protocol spec version 2.3+?

@CaselIT
Copy link
Member

CaselIT commented May 6, 2022

  • I'm not sure if we can always send() a reason indiscriminately inside an ASGI WebSocket protocol message. Maybe it's safer to only include a reason iff we've verified we're dealing with ASGI HTTP+WebSocket protocol spec version 2.3+?

I agree, this seems the safest option

Copy link
Member

@CaselIT CaselIT left a comment

Choose a reason for hiding this comment

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

great work, I've marked some minor things

{
'type': EventType.WS_CLOSE,
'code': WSCloseCode.SERVER_ERROR,
'reason': 'Internal Server Error',
Copy link
Member

Choose a reason for hiding this comment

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

here we should probably send reason only if the ver is 2.3 or greater.

This here poses a problem since doing a simple ver >= "2.3" does not work assuming future version, since that check would fail if ver ever goes over "2.10".

we probably need to convert ver to a tuple of int, but I don't know if we can assume that it will always be in the form xx.yy and not have values like 2.3.1 or something. @vytas7 do you have suggestions here?

Copy link
Author

@wendy5667 wendy5667 May 7, 2022

Choose a reason for hiding this comment

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

I added a new member function in asgi/ws.py to check if the asgi version support reason. Is it more reasonable to put this function in util/misc.py so both asgi/ws.py and asgi/app.py can utilize it?

Copy link
Member

Choose a reason for hiding this comment

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

I think we could keep it in ws.py, but we could make _check_support_reason a function, so that app could call it too?

Copy link
Member

@vytas7 vytas7 May 13, 2022

Choose a reason for hiding this comment

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

Personally, I can accept >= '2.3' as good enough until proven otherwise; the ASGI WebSocket spec is not evolving that fast and I'm not sure if we live to see 2.10 😈 Moreover, they might cut straight to 3.x which would still work with this simple comparison.

Let's just add a # NOTE for posterity if we go this way.

Copy link
Member

Choose a reason for hiding this comment

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

since that's not too performance critical (happens once per web socket), I think being correct here is worth it since it's not that much more code

Copy link
Author

Choose a reason for hiding this comment

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

The function check_support_reason() has been added in ws.py. Hopefully, it could deal with any form of ver string, whether it is 2.3 or 2.10.1.

falcon/asgi/ws.py Outdated Show resolved Hide resolved
falcon/asgi/ws.py Outdated Show resolved Hide resolved
falcon/testing/helpers.py Show resolved Hide resolved
falcon/testing/helpers.py Show resolved Hide resolved
falcon/testing/helpers.py Show resolved Hide resolved
return {
'type': EventType.WS_DISCONNECT,
'code': self._close_code,
'reason': self._close_reason,
Copy link
Member

Choose a reason for hiding this comment

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

I guess if we decide to keep None reason could be omitted in case of None

Copy link
Member

Choose a reason for hiding this comment

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

Here I think we could omit reason if empty string?

Copy link
Member

@CaselIT CaselIT left a comment

Choose a reason for hiding this comment

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

Thanks for the update and sorry for the delay.

looks better, I've replied to a few comments

falcon/testing/helpers.py Show resolved Hide resolved
return {
'type': EventType.WS_DISCONNECT,
'code': self._close_code,
'reason': self._close_reason,
Copy link
Member

Choose a reason for hiding this comment

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

Here I think we could omit reason if empty string?

@wendy5667
Copy link
Author

  • We need to write a newsfragment for the new feature you've implemented.

Could you kindly share the style guide for newsfragments? I couldn't find it in the Contributor's Guide. Thank you!

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

Successfully merging this pull request may close these issues.

Add support for reason in WebSocket.close()
4 participants