phoenixframework / websock_adapter

Implementation of the WebSock specification for servers
MIT License
32 stars 10 forks source link

Handle Close Codes #2

Closed jeregrine closed 1 year ago

jeregrine commented 1 year ago

Currently Bandit and this Cowboy adapter, only allow for sending of "WebSocket Close" codes 1000 and 1002. Or in the case of cowboy adapter they drop/ignore close codes entirely.

The WebSocket specification allows any code from with registered values here. As well as a short UTF8 Binary message along with close codes.

I previously did some work to handle the case where the user is force disconnected by sending a status code 3000, which is registered unauthorized. This allowed the socket.js to not retry connections if they are booted by the server purposely. While maintaining some level of backwards of compatibility.

I don't see any reason why would should limit to 1000 and 1002. With cowboy we could handle the reply {:stop, {:close, CODE, REASON}, state} correctly. In Bandit it looks like this is a known thing but it is simply not being used by the websocket close function.

I Post all this because maybe I'm missing something?

Why limit the close codes? Why drop/ignore close messages? I can do the work to enable it on your end and phoenix's end but I wanted to gut check myself.

mtrudel commented 1 year ago

I was just looking at phoenixframework/phoenix#5024!

I deliberately didn't accommodate sending close frames in WebSock because I didn't see a clear way to expose it, but now that the dust has settled I think I see a way forward that's really easy to land:

Happy to accept PRs for this! I'd suspect it to be three PRs, one each for websock, websock_adapter, and bandit.

Gazler commented 1 year ago

Just to confirm on the note about Cowboy, it does automatically close the websocket if a :close reply is sent.

https://github.com/ninenines/cowboy/blob/30ee75cea14c1fd63a46093cfb2bb9ad3f844f75/src/cowboy_websocket.erl#L506

mtrudel commented 1 year ago

This functionality is ready for review on Cowboy at the PRs linked above.

Next step is to get the websock PR reviewed & landed.

Once that's done, I'll cut a websock release and update the websock_adapter PR and Bandit PR to point at it.

jeregrine commented 1 year ago

Awesome!

mtrudel commented 1 year ago

All work for this is done & merged. This will now work for websock_adapter >= 0.5.0. You can update this dependency locally within any recent phoenix app & have access as needed.

mtrudel commented 1 year ago

Just to confirm on the note about Cowboy, it does automatically close the websocket if a :close reply is sent.

https://github.com/ninenines/cowboy/blob/30ee75cea14c1fd63a46093cfb2bb9ad3f844f75/src/cowboy_websocket.erl#L506

I just found explicit validation of this in Cowboy's documentation at the very bottom of https://ninenines.eu/docs/en/cowboy/2.6/guide/ws_handlers/