Commit de3d6472 authored by Fumitoshi Ukai's avatar Fumitoshi Ukai Committed by Andrew Gerrand

websocket: return an error HTTP response for bad websocket request.

websocket spec had changed server-side requiements to return
an HTTP response with an appropriate error code (such as 400 Bad
Request) when it finds client did not send a handshake that matches
websocket protocol, rather than just closing connection.
It needs to flush out response before closing connection.
Fixes issues 2396.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5318072
parent bc440f1b
...@@ -20,6 +20,7 @@ func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Requ ...@@ -20,6 +20,7 @@ func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Requ
fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion) fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion)
buf.WriteString("\r\n") buf.WriteString("\r\n")
buf.WriteString(err.Error()) buf.WriteString(err.Error())
buf.Flush()
return return
} }
if err != nil { if err != nil {
...@@ -34,12 +35,17 @@ func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Requ ...@@ -34,12 +35,17 @@ func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Requ
fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
buf.WriteString("\r\n") buf.WriteString("\r\n")
buf.WriteString(err.Error()) buf.WriteString(err.Error())
buf.Flush()
return return
} }
config.Protocol = nil config.Protocol = nil
err = hs.AcceptHandshake(buf.Writer) err = hs.AcceptHandshake(buf.Writer)
if err != nil { if err != nil {
code = http.StatusBadRequest
fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code))
buf.WriteString("\r\n")
buf.Flush()
return return
} }
conn = hs.NewServerConn(buf, rwc, req) conn = hs.NewServerConn(buf, rwc, req)
......
...@@ -200,20 +200,19 @@ func TestHTTP(t *testing.T) { ...@@ -200,20 +200,19 @@ func TestHTTP(t *testing.T) {
once.Do(startServer) once.Do(startServer)
// If the client did not send a handshake that matches the protocol // If the client did not send a handshake that matches the protocol
// specification, the server should abort the WebSocket connection. // specification, the server MUST return an HTTP respose with an
_, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr)) // appropriate error code (such as 400 Bad Request)
if err == nil { resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
t.Error("Get: unexpected success") if err != nil {
t.Errorf("Get: error %#v", err)
return return
} }
urlerr, ok := err.(*url.Error) if resp == nil {
if !ok { t.Error("Get: resp is null")
t.Errorf("Get: not url.Error %#v", err)
return return
} }
if urlerr.Err != io.ErrUnexpectedEOF { if resp.StatusCode != http.StatusBadRequest {
t.Errorf("Get: error %#v", err) t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode)
return
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment