mirror of https://github.com/golang/go.git
net/http: check for CloseWrite interface, not TCPConn implementation
Fixes #8724 LGTM=adg R=adg CC=golang-codereviews https://golang.org/cl/148040043
This commit is contained in:
parent
e6f21be3f4
commit
446524269e
|
|
@ -77,3 +77,7 @@ var DefaultUserAgent = defaultUserAgent
|
|||
func SetPendingDialHooks(before, after func()) {
|
||||
prePendingDial, postPendingDial = before, after
|
||||
}
|
||||
|
||||
var ExportServerNewConn = (*Server).newConn
|
||||
|
||||
var ExportCloseWriteAndWait = (*conn).closeWriteAndWait
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue