summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2014-09-24 17:01:54 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2014-09-24 17:01:54 -0700
commit3b1a43e8e4876c75afea231b2707e0c61d8a9e2a (patch)
treed6f424d3f12932fb3e6413f040ae36a4acfa8409 /src/net
parentaf596d6b57a372038e3b1245c80532229d1a9db6 (diff)
downloadgo-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.go4
-rw-r--r--src/net/http/serve_test.go23
-rw-r--r--src/net/http/server.go10
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)