Skip to content

Conversation

ronaldmannak
Copy link

I'm opening this draft PR because I ran into a case that I believe isn't currently covered required for socket.io. I have added a continueToHTTP case to ShouldUpgradeResult.

The (mostly vibe coded) code is still rough and needs cleanup, but before spending more time on it, I wanted to see if there’s interest in supporting this use case.

If this is a direction the project wants to go in, I’ll tidy up the code and update the branch.

@adam-fowler
Copy link
Member

adam-fowler commented Jul 16, 2025

What does continueToHTTP do that dontUpgrade doesn't already support?

EDIT: is this for returning a custom HTTP response on a failed upgrade?

@adam-fowler
Copy link
Member

I don't know a great deal about socket.io, but it looks like it goes through a non-standard way to upgrade to websocket. ie it doesn't send the standard upgrade request. The spec sample session doesn't detail any headers sent or if any are sent at all https://socket.io/docs/v4/socket-io-protocol/#sample-session

GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
        Origin: http://example.com
        Sec-WebSocket-Protocol: chat, superchat
        Sec-WebSocket-Version: 13

So none of the Hummingbird WebSocket code will be triggered as the lower level SwiftNIO isn't triggered.

@ronaldmannak
Copy link
Author

The naming of the enum might be confusing, sorry about that. This PR enables support for the Socket.IO handshake protocol. After this handshake, the connection upgrades to use WebSockets.

With the existing implementation, I couldn't find a way to handle the initial handshake on the application layer. My assumption was that, once the handshake and upgrade were complete, all further communication would happen over standard WebSockets.

Are you saying that—even after a successful handshake and upgrade—communication still wouldn’t work because Socket.IO doesn’t fully adhere to the WebSocket protocol?

@adam-fowler
Copy link
Member

adam-fowler commented Jul 17, 2025

Does a socket.io websocket upgrade request include the headers I posted previously?

As far as I can tell from the spec sample session it doesn't. And your code won't work, as it is doesn't have the required headers to instigate an HTTP upgrade

case upgrade(HTTPFields = [:])
case continueToHTTP
case httpResponse(Response)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding enum cases is a breaking change. Unfortunately I made this a public enum, instead of a struct. I've wanted to do something similar to .httpResponse before but come up against this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants