Safari Websocket Handshake Error

1.9k views Asked by At

I am building my own Http Server with built in Support for Websockets for a school project.

I mainly tested everything on Chrome and everything looks good, but I am having problems with Safari (10.0.2).

When establishing the Handshake WebSocket connection to 'ws://192.168.0.213' failed: Status line contains non-ASCII character appears as an Error in the development console, keep in mind, Chrome works as expected.

Here are the Exchanged Headers

Request Header (Safari => Server)

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.0.213
Origin: http://192.168.0.213
Cookie: session=MDQ5M2UzYTctODg5NC00ZTEwLWJlOWEtYjBiZTRkNzdiYTRj
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: 9/Mj26XS0JxG+Y+lDTvMcQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0.2 Safari/602.3.12

Response Header (Server => Safari)

HTTP/1.1 101 Switching Protocols
Connection:Upgrade
Upgrade:websocket
Sec-WebSocket-Accept:rpx9CefKAgOdM7RzjhLuWEcCIso=

Raw Response Header

[72][84][84][80][47][49][46][49][32][49]
[48][49][32][83][119][105][116][99][104][105]
[110][103][32][80][114][111][116][111][99][111]
[108][115][13][10][67][111][110][110][101][99]
[116][105][111][110][58][85][112][103][114][97]
[100][101][13][10][85][112][103][114][97][100]
[101][58][87][101][98][115][111][99][107][101]
[116][13][10][83][101][99][45][87][101][98]
[83][111][99][107][101][116][45][65][99][99]
[101][112][116][58][53][120][86][118][113][57]
[52][121][97][53][84][56][51][88][65][82]
[115][78][119][74][69][88][97][78][97][108]
[99][61][13][10][13][10]

How it is beeng generated (C#)

string handshakeString = $"HTTP/1.1 {(int)StatusCode.SwitchingProtocols} {StatusCode.SwitchingProtocols.GetStatusMessage()}" + Environment.NewLine
                                                 + "Connection:Upgrade" + Environment.NewLine
                                                 + "Upgrade:Websocket" + Environment.NewLine
                                                 + "Sec-WebSocket-Accept:" + Convert.ToBase64String($"{_initHeader["Sec-WebSocket-Key"]}258EAFA5-E914-47DA-95CA-C5AB0DC85B11".Sha1()) + Environment.NewLine
                                                 + Environment.NewLine;
byte[] handshake = Encoding.ASCII.GetBytes(handshakeString); // <- There is the ASCII part
await SendFrameData(OpCode.Text, handshake); // This frame neither gets fragmented or masked

I understand, that there must be an issue with the encoding of the header, but this header gets encoded as ASCII and send with an OpCode 0x1 (Text) to the Client and it is working in Chrome. Am I missing some header keys/values?

Thanks, David

1

There are 1 answers

0
David Gölzhäuser On BEST ANSWER

Answering my own Question. Thanks Remy Lebeau!

The Handshake was wrapped in a Websocket frame. This violates RFC 5455. So the handshake directly needs to be send over the socket.