Closed DanielleHuisman closed 1 month ago
Hi, @DanielleHuisman. Thanks for opening this.
WebSocketOverride only exposes the first value
That is correct. WebSocketOverride
complies with WebSocket
, which complies with WHATWG WebSocket, where the protocol
property on the WebSocket
interface is a single string representing the protocol that was eventually chosen by the instance (source).
In other words, this is also true:
let ws = new WebSocket(url, ['ws:', 'wss:'])
// You cannot access the full list of protocols anymore.
ws.protocol // "ws:"
Can you tell me more about your use case to access the list of protocols?
Also a bit of information about how the string[]
input of protocols
is handled:
Each string in the array is a subprotocol name. The connection will only be established if the server reports that it has selected one of these subprotocols.
As I understand it, the handshake request's Sec-WebSocket-Protocol
header will combine all the protocols you've specified on the client so then the server can report which protocol it ended up using.
Does this mean that you want to access the list of protocols to choose between them within the event handler? I'm still a bit confused how that's beneficial. Would love to learn more.
I think you're mixing up URL protocols and WebSocket subprotocols. The URL protocol (ws:
or wss:
) is specified in the url
parameter of the WebSocket
constructor. The WebSocket subprotocols are specified in the protocols
parameter of WebSocket
. The naming of the second parameter is a bit unfortunate.
WebSocket subprotocols are user defined strings that could represent the capabilities of the client and server. As you mentioned, the client and server need to agree on the subprotocol they are using and this single value is stored in WebSocket.protocol
. An example of these subprotocols can be found in section 1.2 of the RFC. More information can be found in the RFC when searching for Sec-WebSocket-Protocol
or subprotocol
.
I have some WebSocket client code that conditionally chooses a subprotocol, so I would like to verify this behaviour in unit tests using MSW. Currently, I can only verify the first value sent by the client in WebSocket.protocol
. My PR attempts to expose the full list of subprotocols provided by the client.
Now that I've looked at it in more detail, I think the default value (ws
) in WebSocketOverride
(line) does not match the specification. I believe if no subprotocols are provided by the client, WebSocket.protocol
is an empty string, because the client and server both agree not to use a subprotocol. Ofcourse assuming the server doesn't require the use of a subprotocol.
I hope this clarifies the intentions of my PR.
I think you're mixing up URL protocols and WebSocket subprotocols.
🤦 I totally am mixing those up. Thanks for clarifying!
My PR attempts to expose the full list of subprotocols provided by the client.
I think this is reasonable then. Let me think of the exact way we can do that.
Now that I've looked at it in more detail, I think the default value (ws) in WebSocketOverride (line) does not match the specification.
Yes, you are right. Please, could you open a new pull request to fix this? I would be grateful!
I've nested the protocols under info
key of the event payload. This is how you can access it now:
interceptor.on('connection', ({ info, client }) => {
info.protocols // ['one', 'two']
client.socket.protocol // 'one'
})
This has been released in v0.30.0!
Make sure to always update to the latest version (npm i @mswjs/interceptors@latest
) to get the newest features and bug fixes.
Predictable release automation by @ossjs/release.
Currently, there is no way to access the full list of protocols supported by the WebSocket client.
WebSocketOverride
only exposes the first value (relevant line).This PR exposes the client protocols in the
connection
event, so tests can verify the client provided the right protocols.