diff options
author | Brad Fitzpatrick <bradfitz@golang.org> | 2014-09-24 17:01:54 -0700 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2014-09-24 17:01:54 -0700 |
commit | 3b1a43e8e4876c75afea231b2707e0c61d8a9e2a (patch) | |
tree | d6f424d3f12932fb3e6413f040ae36a4acfa8409 /src/net | |
parent | af596d6b57a372038e3b1245c80532229d1a9db6 (diff) | |
download | go-3b1a43e8e4876c75afea231b2707e0c61d8a9e2a.tar.gz |
net/http: check for CloseWrite interface, not TCPConn implementation
Fixes Issue 8724
LGTM=adg
R=adg
CC=golang-codereviews
https://codereview.appspot.com/148040043
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/http/export_test.go | 4 | ||||
-rw-r--r-- | src/net/http/serve_test.go | 23 | ||||
-rw-r--r-- | src/net/http/server.go | 10 |
3 files changed, 35 insertions, 2 deletions
diff --git a/src/net/http/export_test.go b/src/net/http/export_test.go index f8cc835b2..e5bc02afa 100644 --- a/src/net/http/export_test.go +++ b/src/net/http/export_test.go @@ -77,3 +77,7 @@ var DefaultUserAgent = defaultUserAgent func SetPendingDialHooks(before, after func()) { prePendingDial, postPendingDial = before, after } + +var ExportServerNewConn = (*Server).newConn + +var ExportCloseWriteAndWait = (*conn).closeWriteAndWait diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index ee4f20499..a690ae469 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -2607,6 +2607,29 @@ func TestServerConnStateNew(t *testing.T) { } } +type closeWriteTestConn struct { + rwTestConn + didCloseWrite bool +} + +func (c *closeWriteTestConn) CloseWrite() error { + c.didCloseWrite = true + return nil +} + +func TestCloseWrite(t *testing.T) { + var srv Server + var testConn closeWriteTestConn + c, err := ExportServerNewConn(&srv, &testConn) + if err != nil { + t.Fatal(err) + } + ExportCloseWriteAndWait(c) + if !testConn.didCloseWrite { + t.Error("didn't see CloseWrite call") + } +} + func BenchmarkClientServer(b *testing.B) { b.ReportAllocs() b.StopTimer() diff --git a/src/net/http/server.go b/src/net/http/server.go index 8f2b777b2..7ad0bcbc2 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -1064,15 +1064,21 @@ func (c *conn) close() { // This timeout is somewhat arbitrary (~latency around the planet). const rstAvoidanceDelay = 500 * time.Millisecond +type closeWriter interface { + CloseWrite() error +} + +var _ closeWriter = (*net.TCPConn)(nil) + // closeWrite flushes any outstanding data and sends a FIN packet (if // client is connected via TCP), signalling that we're done. We then -// pause for a bit, hoping the client processes it before `any +// pause for a bit, hoping the client processes it before any // subsequent RST. // // See http://golang.org/issue/3595 func (c *conn) closeWriteAndWait() { c.finalFlush() - if tcp, ok := c.rwc.(*net.TCPConn); ok { + if tcp, ok := c.rwc.(closeWriter); ok { tcp.CloseWrite() } time.Sleep(rstAvoidanceDelay) |