]> Cypherpunks repositories - gostls13.git/commitdiff
websocket: tweak hybi ReadHandshake to supports Firefox implementation
authorLuca Greco <luca.greco@alcacoop.it>
Fri, 14 Oct 2011 18:27:45 +0000 (14:27 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 14 Oct 2011 18:27:45 +0000 (14:27 -0400)
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

src/pkg/websocket/hybi.go
src/pkg/websocket/hybi_test.go

index c832dfc83229c863332da56891e4c57b929d5376..fe08b3d738b0f0d43901a78f74def154ad39d999 100644 (file)
@@ -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
        }
 
index 71d1893b30172a96a38fd10432ff7d888aee7571..9db57e3f1b79a9fa8c8f5f0c576a58ad1d2bae34 100644 (file)
@@ -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())
+       }
+}