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
This commit is contained in:
Fumitoshi Ukai 2011-11-03 14:13:39 +11:00 committed by Andrew Gerrand
parent bc440f1bfe
commit de3d647252
2 changed files with 17 additions and 12 deletions

View file

@ -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)
buf.WriteString("\r\n")
buf.WriteString(err.Error())
buf.Flush()
return
}
if err != nil {
@ -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))
buf.WriteString("\r\n")
buf.WriteString(err.Error())
buf.Flush()
return
}
config.Protocol = nil
err = hs.AcceptHandshake(buf.Writer)
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
}
conn = hs.NewServerConn(buf, rwc, req)

View file

@ -200,21 +200,20 @@ func TestHTTP(t *testing.T) {
once.Do(startServer)
// If the client did not send a handshake that matches the protocol
// specification, the server should abort the WebSocket connection.
_, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
if err == nil {
t.Error("Get: unexpected success")
return
}
urlerr, ok := err.(*url.Error)
if !ok {
t.Errorf("Get: not url.Error %#v", err)
return
}
if urlerr.Err != io.ErrUnexpectedEOF {
// specification, the server MUST return an HTTP respose with an
// appropriate error code (such as 400 Bad Request)
resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
if err != nil {
t.Errorf("Get: error %#v", err)
return
}
if resp == nil {
t.Error("Get: resp is null")
return
}
if resp.StatusCode != http.StatusBadRequest {
t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode)
}
}
func TestTrailingSpaces(t *testing.T) {