diff options
author | Fumitoshi Ukai <ukai@google.com> | 2013-05-14 15:08:31 +0900 |
---|---|---|
committer | Mikio Hara <mikioh.mikioh@gmail.com> | 2013-05-14 15:08:31 +0900 |
commit | 4c1c96f7e0a2ce6386a53be9b94a8d31a0bb2434 (patch) | |
tree | 6edacc80bf23c2ab01c5098408e857d0dfa7df68 | |
parent | e4c0e9ee2dec6270b010405afb4c1482d0b4ab7c (diff) | |
download | net-4c1c96f7e0a2ce6386a53be9b94a8d31a0bb2434.tar.gz |
go.net/websocket: fix handshake error.
If client sent no subprotocol (e.g. no Sec-WebSocket-Protocol),
websocket server responded with the following header
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: E7SRWRnZL9RuGFLuZ0j4508nqdg=
Sec-WebSocket-Protocol:
So, client may close the connection because it contains
wrong empty Sec-WebSocket-Protocol header.
If client didn't offer any subprotocol, don't set
config.Protocol, so that not emit empty Sec-WebSocket-Protocol.
Fixes golang/go#5457.
R=golang-dev, mikioh.mikioh
CC=golang-dev
https://golang.org/cl/9379044
-rw-r--r-- | websocket/hybi.go | 9 | ||||
-rw-r--r-- | websocket/hybi_test.go | 51 |
2 files changed, 56 insertions, 4 deletions
diff --git a/websocket/hybi.go b/websocket/hybi.go index c6ba6cf..90f5d9c 100644 --- a/websocket/hybi.go +++ b/websocket/hybi.go @@ -516,9 +516,11 @@ func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Reques return http.StatusBadRequest, err } protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol")) - protocols := strings.Split(protocol, ",") - for i := 0; i < len(protocols); i++ { - c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i])) + if protocol != "" { + protocols := strings.Split(protocol, ",") + for i := 0; i < len(protocols); i++ { + c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i])) + } } c.accept, err = getNonceAccept([]byte(key)) if err != nil { @@ -546,6 +548,7 @@ func Origin(config *Config, req *http.Request) (*url.URL, error) { func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) { if len(c.Protocol) > 0 { if len(c.Protocol) != 1 { + // You need choose a Protocol in Handshake func in Server. return ErrBadWebSocketProtocol } } diff --git a/websocket/hybi_test.go b/websocket/hybi_test.go index 01ed9e9..9db0ef9 100644 --- a/websocket/hybi_test.go +++ b/websocket/hybi_test.go @@ -243,10 +243,14 @@ Sec-WebSocket-Version: 13 if code != http.StatusSwitchingProtocols { t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) } + expectedProtocols := []string{"chat", "superchat"} + if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) { + t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol) + } b := bytes.NewBuffer([]byte{}) bw := bufio.NewWriter(b) - config.Protocol = []string{"chat"} + config.Protocol = config.Protocol[:1] err = handshaker.AcceptHandshake(bw) if err != nil { @@ -265,6 +269,51 @@ Sec-WebSocket-Version: 13 } } +func TestHybiServerHandshakeNoSubProtocol(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: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +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) + } + if len(config.Protocol) != 0 { + t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol)) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + 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=", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +} + func TestHybiServerHandshakeHybi08(t *testing.T) { config := new(Config) handshaker := &hybiServerHandshaker{Config: config} |