How to "upgrade" an HTTP connection to a WebSocket

Hi,
I have been successful at writing Swift code using a NWListener to listen to WebSocket connections on a specific port, but I do not seem to be able to get the path from the URL for creating different types of connections.
For instance, differentiating between ws://127.0.0.1:80/updates and ws://127.0.0.1:80/changes.
I'd like to be able to get the "updates" or "changes" part when I receive the new connection notification.

Having more sample code around WebSockets and how the upgrade process works that would also be great.

Thank you !

Daniel Tapie
Answered by dtapie in 631207022
To make myself a little more clear: when a WebSocket client tries to establish a connection, it will send a HTTP request like this:

GET /remote HTTP/1.1
Host: 127.0.0.1:8080
Sec-WebSocket-Protocol: v1.1.main_update
Sec-WebSocket-Key: Oa2PP7lDFszNLrv6Lpk1iA==
Sec-WebSocket-Version: 13
Upgrade: websocket
Accept: */*
Accept-Language: en-ie
User-Agent: TestWebSocket/1 CFNetwork/1128.0.1 Darwin/19.6.0 (x86_64)
Accept-Encoding: gzip, deflate
Connection: Upgrade

But as soon as I add the ws protocol stack to my nw_listener, with something like this:

nw_protocol_stack_prepend_application_protocol(stack, wsOptions);

The negotiation is totally automatic and I have no access to the original "GET" part containing the relative path I need to differentiate connections.

So either there is a way to still get this "nw_listener_set_new_connection_handler" or "nw_ws_options_set_client_request_handler" (or anywhere else) or I have to handle the negotiation myself but then how do I upgrade my HTTP socket to become a WebSocket.

Thanks !

Daniel Tapie
Accepted Answer
To make myself a little more clear: when a WebSocket client tries to establish a connection, it will send a HTTP request like this:

GET /remote HTTP/1.1
Host: 127.0.0.1:8080
Sec-WebSocket-Protocol: v1.1.main_update
Sec-WebSocket-Key: Oa2PP7lDFszNLrv6Lpk1iA==
Sec-WebSocket-Version: 13
Upgrade: websocket
Accept: */*
Accept-Language: en-ie
User-Agent: TestWebSocket/1 CFNetwork/1128.0.1 Darwin/19.6.0 (x86_64)
Accept-Encoding: gzip, deflate
Connection: Upgrade

But as soon as I add the ws protocol stack to my nw_listener, with something like this:

nw_protocol_stack_prepend_application_protocol(stack, wsOptions);

The negotiation is totally automatic and I have no access to the original "GET" part containing the relative path I need to differentiate connections.

So either there is a way to still get this "nw_listener_set_new_connection_handler" or "nw_ws_options_set_client_request_handler" (or anywhere else) or I have to handle the negotiation myself but then how do I upgrade my HTTP socket to become a WebSocket.

Thanks !

Daniel Tapie

Do you ever find a solution?

I likewise expected to find the url within nw_ws_options_set_client_request_handler(), but the headers at that point omit it.

How to "upgrade" an HTTP connection to a WebSocket
 
 
Q