python-websockets / websockets

Library for building WebSocket servers and clients in Python

Home Page:https://websockets.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Accessing the websocket object after leaving the process_request function

lonode opened this issue · comments

commented

Hello,

Like suggested in the documentation, i'm defining a custom Websocket protocol to authenticate a client. I'm therefore overriding process_request in my custom class definition.
In my backend, when the client is authenticated, it leads to stateful modification behind the scenes.

I noticed that if a browser sends a pure HTTP request to the websocket endpoint, it gets rejected because it does not talk with the websocket protocol, all good. But the request still goes through the process_request function and can go without problem if the Authorization is validated.

The websocket is then immediatly closed, how do you access it again to know that it has been closed, so that i can clean my backend other services ?

To be pragmatic, I recommend that you test if headers.get("Upgrade").lower() == "websocket" and, if that's not true, cleanup immediately in process_request.

This conditions should be true for WebSocket connections and false for HTTP requests. Strictly speaking, the handshake could fail for other reasons but that should be good enough in practice.

You need a cleanup mechanism anyway in case the Python process dies unexpectedly, and therefore doesn't free backend resources on exit.

commented

Thanks, i wanted to avoid double checking myself something you do inside your lib, maybe i'll forget some corner case when checking the invalidity of the websocket header.

Can't i override a function defined in the object WebSocketServerProtocol or WebSocketCommonProtocol to check if the state property is CLOSED ?

There is no public API for that in the current version of websockets.

If, some day, I rewrite the asyncio implementation, you may get a process_response API that does what you want. Right now this is only available in the threading implementation (docs), which doesn't scale to more than a few hundred clients. I don't imagine having time for that in the next year so don't hold your breath...