This library is used by the Pebble watch project for its pypkjs phone emulation environment. In exploring its subprotocol support, I found that connections fail with Invalid subprotocol if none of the requested subprotocols are returned by the server. The relevant code in this library appears to be the following:
|
if subprotocols: |
|
subproto = headers.get("sec-websocket-protocol", None) |
|
if not subproto or subproto.lower() not in [s.lower() for s in subprotocols]: |
|
error(f"Invalid subprotocol: {subprotocols}") |
|
return False, None |
This project's documentation helpfully links to the WebSocket RFC to explain its behavior. The link is to a non-normative section which states:
The client can request that the server use a specific subprotocol by including the |Sec-WebSocket-Protocol| field in its handshake. If it is specified, the server needs to include the same field and one of the selected subprotocol values in its response for the connection to be established.
This strongly suggests that the server must include one of the subprotocols in its response for the connection to be valid. This is what this library implements.
Unfortunately, the normative text that follows later in the RFC makes it clear that the server may choose not to include any subprotocol in its response and the connection is still valid. For example, it says that if no subprotocol is in the response, the subprotocol is null:
The Subprotocol In Use is defined to be the value of the Sec-WebSocket-Protocol header field in the server's handshake or the null value if that header field was not present in the server's handshake.
It also states that the value provided by the server (or absence thereof) is for scripts (not the WebSocket library) to check which protocol was selected by the server.
The Sec-WebSocket-Protocol header field is used in the WebSocket opening handshake. It is sent from the client to the server and back from the server to the client to confirm the subprotocol of the connection. This enables scripts to both select a subprotocol and be sure that the server agreed to serve that subprotocol.
As far as I am aware, the WebSocket class implementations in all web browsers follow the normative section of the RFC for subprotocols, and so do not reject the handshake if the server does not select any of the requested subprotocols.
This library is used by the Pebble watch project for its
pypkjsphone emulation environment. In exploring its subprotocol support, I found that connections fail withInvalid subprotocolif none of the requested subprotocols are returned by the server. The relevant code in this library appears to be the following:websocket-client/websocket/_handshake.py
Lines 177 to 181 in 52329c4
This project's documentation helpfully links to the WebSocket RFC to explain its behavior. The link is to a non-normative section which states:
This strongly suggests that the server must include one of the subprotocols in its response for the connection to be valid. This is what this library implements.
Unfortunately, the normative text that follows later in the RFC makes it clear that the server may choose not to include any subprotocol in its response and the connection is still valid. For example, it says that if no subprotocol is in the response, the subprotocol is null:
It also states that the value provided by the server (or absence thereof) is for scripts (not the WebSocket library) to check which protocol was selected by the server.
As far as I am aware, the
WebSocketclass implementations in all web browsers follow the normative section of the RFC for subprotocols, and so do not reject the handshake if the server does not select any of the requested subprotocols.