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

Close status is not optional? #61

Open
rotu opened this issue Sep 11, 2024 · 4 comments
Open

Close status is not optional? #61

rotu opened this issue Sep 11, 2024 · 4 comments

Comments

@rotu
Copy link

rotu commented Sep 11, 2024

What is the issue with the WebSockets Standard?

This spec says that the close code is optional, in self-acknowledged contradiction1 of RFC 6455. The RFC is very explicit about this:

If this Close control frame contains no status code, The WebSocket Connection Close Code is considered to be 1005.

For instance, with Chrome and Node.JS using the popular ws package, closing a connection from the client with .close() results in CloseEvent with code 1005. On the other hand, closing the connection from the client with .close(1000) results in a CloseEvent with code 1000.

The MDN page has another take, suggesting that .close() is synonymous with .close(1000):

If unspecified, a close code for the connection is automatically set: to 1000 for a normal closure


From an end-user perspective, I think the behavior documented on MDN page makes the most sense (even though it aligns with neither standard. Calling the .close() function without an error indicates a normal, intended closure.

Footnotes

  1. @ricea, what was the erratum that you wished to make?

@ricea
Copy link
Collaborator

ricea commented Sep 12, 2024

@ricea, what was the erratum that you wished to make?

Section 7.1.2 says

To _Start the WebSocket Closing Handshake_ with a status code
   ([Section 7.4](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4)) /code/ and an optional close reason ([Section 7.1.6](https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6))
   /reason/, an endpoint MUST send a Close control frame, as described
   in [Section 5.5.1](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1), whose status code is set to /code/ and whose close
   reason is set to /reason/.

It implies that /code/ is compulsory, whereas the rest of RFC6455 suggests that is is optional.

I don't like MDN's interpretation, because it provides no way to send a Close frame with no body. I don't want to force someone to waste 2 bytes sending the code "1000" if the server doesn't care.

@rotu
Copy link
Author

rotu commented Sep 12, 2024

The code is optional in the sense that, if omitted, the connection still gets closed. My reading is that it should be sent to indicate the client intended to close the connection (rather than, say, that the status was accidentally omitted or lost by an intermediary).

I don’t think economizing on 2 bytes is a compelling reason. The server does care in that it is expected to behave differently and it does populate those two bytes in the response regardless.

It’s notable that, while you can call .close(1000), it is erroneous by this spec to call .close(1005).

So I guess the issue here (and what I hoped to glean from your erratum on RFC6455) is essentially that it’s unclear how code 1005 should be regarded:

  • “normal” (and essentially synonymous with 1000)
  • “the client does not use and does not care about the close code”
  • a mistake by the WebSocket client library
  • a mistake by the application using a WebSocket client library

@rotu
Copy link
Author

rotu commented Sep 14, 2024

Also, per this spec, if a WebSocket object is garbage-collected while open, then no status code is sent. It seems odd to make this the same code as if close() is called with no status.

@ricea
Copy link
Collaborator

ricea commented Sep 18, 2024

Interesting. From your analysis, it looks like there was a difference of opinion between the people who designed the protocol and the people who designed the API.

I don't have time to write an erratum, but if I did I would go for “the client does not use and does not care about the close code”, as I think it most closely describes real-world usage.

If a developer went to the trouble to send code 1000, I would take it to mean that they might send some other code in other circumstances.

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

No branches or pull requests

2 participants