aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFumitoshi Ukai <ukai@google.com>2013-05-14 15:08:31 +0900
committerMikio Hara <mikioh.mikioh@gmail.com>2013-05-14 15:08:31 +0900
commit4c1c96f7e0a2ce6386a53be9b94a8d31a0bb2434 (patch)
tree6edacc80bf23c2ab01c5098408e857d0dfa7df68
parente4c0e9ee2dec6270b010405afb4c1482d0b4ab7c (diff)
downloadnet-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.go9
-rw-r--r--websocket/hybi_test.go51
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}