From: Luca Greco Date: Fri, 14 Oct 2011 18:27:45 +0000 (-0400) Subject: websocket: tweak hybi ReadHandshake to supports Firefox implementation X-Git-Tag: weekly.2011-10-18~71 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d296fa1c9523d5c767cbf2def38c9360fae97af6;p=gostls13.git websocket: tweak hybi ReadHandshake to supports Firefox implementation Firefox Websocket implementation send a "Connection: keep-alive, upgrade" header during the handshake (and as descripted on the last hybi draft the "Connection" header must include, but doesn't need to be equal to, "upgrade": '4. A "Connection" header field that includes the token "Upgrade", treated as an ASCII case-insensitive value.' From: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#page-23 R=golang-dev, ukai, cw, rsc CC=golang-dev https://golang.org/cl/5233059 --- diff --git a/src/pkg/websocket/hybi.go b/src/pkg/websocket/hybi.go index c832dfc832..fe08b3d738 100644 --- a/src/pkg/websocket/hybi.go +++ b/src/pkg/websocket/hybi.go @@ -476,7 +476,7 @@ func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Reques // HTTP version can be safely ignored. if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" || - strings.ToLower(req.Header.Get("Connection")) != "upgrade" { + !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { return http.StatusBadRequest, ErrNotWebSocket } diff --git a/src/pkg/websocket/hybi_test.go b/src/pkg/websocket/hybi_test.go index 71d1893b30..9db57e3f1b 100644 --- a/src/pkg/websocket/hybi_test.go +++ b/src/pkg/websocket/hybi_test.go @@ -533,3 +533,52 @@ func TestHybiClientReadWithMasking(t *testing.T) { t.Errorf("read 1st frame, expect %q, but got %q", os.EOF, err) } } + +// Test the hybiServerHandshaker supports firefox implementation and +// checks Connection request header include (but it's not necessary +// equal to) "upgrade" +func TestHybiServerFirefoxHandshake(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: keep-alive, upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +Sec-WebSocket-Protocol: chat, superchat +Sec-WebSocket-Version: 13 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + if code != http.StatusSwitchingProtocols { + t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + config.Protocol = []string{"chat"} + + err = handshaker.AcceptHandshake(bw) + if err != nil { + t.Errorf("handshake response failed: %v", err) + } + expectedResponse := strings.Join([]string{ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", + "Sec-WebSocket-Protocol: chat", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +}