Commit bb64f4dc authored by Dave Cheney's avatar Dave Cheney

x/net/websocket: always close underlying connection on ws.Close

Fixes #10866

When ws.Close is called, always close the underlying ws.rwc.

Change-Id: Ia709d5e0bc51ffb7194668d2764848d012e0c652
Reviewed-on: https://go-review.googlesource.com/10135Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 5aa7325e
......@@ -216,10 +216,11 @@ func (ws *Conn) Write(msg []byte) (n int, err error) {
// Close implements the io.Closer interface.
func (ws *Conn) Close() error {
err := ws.frameHandler.WriteClose(ws.defaultCloseStatus)
err1 := ws.rwc.Close()
if err != nil {
return err
}
return ws.rwc.Close()
return err1
}
func (ws *Conn) IsClientConn() bool { return ws.request == nil }
......
......@@ -16,6 +16,7 @@ import (
"strings"
"sync"
"testing"
"time"
)
var serverAddr string
......@@ -412,3 +413,40 @@ func TestParseAuthority(t *testing.T) {
}
}
}
type closerConn struct {
net.Conn
closed int // count of the number of times Close was called
}
func (c *closerConn) Close() error {
c.closed++
return c.Conn.Close()
}
func TestClose(t *testing.T) {
once.Do(startServer)
conn, err := net.Dial("tcp", serverAddr)
if err != nil {
t.Fatal("dialing", err)
}
cc := closerConn{Conn: conn}
client, err := NewClient(newConfig(t, "/echo"), &cc)
if err != nil {
t.Fatalf("WebSocket handshake: %v", err)
}
// set the deadline to ten minutes ago, which will have expired by the time
// client.Close sends the close status frame.
conn.SetDeadline(time.Now().Add(-10 * time.Minute))
if err := client.Close(); err == nil {
t.Errorf("ws.Close(): expected error, got %v", err)
}
if cc.closed < 1 {
t.Fatalf("ws.Close(): expected underlying ws.rwc.Close to be called > 0 times, got: %v", cc.closed)
}
}
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