Google-chrome – How to know which websocket version the client uses

google-chromesafariversionwebsocket

I wrote a (not-so-)simple websocket server in python, which listens in a port, performs the handshaking and then sends to the client a sequence of messages (spaced out a random interval), containing numbers.

I wrote a javascript client and tested it under Chrome and Safari. I discovered that Chrome and Safari use different WebSocket versions. For example, Chrome uses Sec-WebSocket-Key (and expects Sec-WebSocket-Accept), while Safari sends instead Sec-WebSocket-Key1, Sec-WebSocket-Key2 and a bunch of 8 bytes after the header.

I implemented in the server a handshake function which detects the kind of handshake required, and performs it. This issue is solved. The websocket is correctly open from Chrome or Safari (both OSX, Windows and IOS5 versions).

But I have another problem. Apparently, Safari sends and expects messages delimited by 0x00 and 0xFF, while Chrome sends and expects framed and masked data (using a more recent version of the websocket specification).

I want to have a single server, which adapts himself to the expectations of the client. My question is, how can I tell in advance if the data has to be sent framed or 0x00,0xFF delimited?

I guess I could assume that, if the handshake protocol is based in Key1 and Key2, the client is Safari, and then use 0x00 0xFF to delimit data, while if it uses Sec-WebSocket-Key the client is Chrome, and then use framed data. However I'm not satisfied with this solution, since it is not general. Ideas?

Best Answer

There are published standards for both the hixie-76 protocol variant used by Safari (desktop & mobile) and RFC 6455 used by Chrome and others.

You can use the type of handshake requested to decide which protocol version a client speaks, what framing will exist on message reads and what framing you should use on message writes.