socketry / async-websocket

Asynchronous WebSocket client and server, supporting HTTP/1 and HTTP/2 for Ruby.
MIT License
168 stars 18 forks source link

How to response `401 Unauthorized` before opening connection by the server and handle it by the client? #72

Closed ksimmi closed 2 months ago

ksimmi commented 2 months ago

Hello.

I'm trying to emulate partners API behavior with my stub server.

On the client side I have to use a Bearer token on requesting new connection. I did Async::WebSocket::Client.connect(Async::HTTP::Endpoint.parse(URL_SOCK), headers: {Authorization: token}) do ...

On the server side I trying to validate the token before create connection:

def run(env)
    token = env['HTTP_AUTHORIZATION']
    return [401, {}, []] if TokenRegistry.expired?(token)

    Async::WebSocket::Adapters::Rack.open(env) do |connection|
       ...

The client raises Async::WebSocket::ProtocolError.

 > e.code
=> 1002
 > e.message
=> "Failed to negotiate connection: 401

I can leave the code like this because it solves my problem by checking message includes 401 substring, but I doubt that I did it correctly.

Thank you.

ioquatix commented 2 months ago

In v0.28.0, I added ConnectionError: https://github.com/socketry/async-websocket/blob/534cad73595292b82b88de3b66d10773106c254d/lib/async/websocket/error.rb#L19-L28

This allows you to catch connection errors and check the response status etc.