net/http: fix server connection leak on Handler's panic(nil)

If a handler did a panic(nil), the connection was never closed.

Fixes #4050

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/6971049
This commit is contained in:
Brad Fitzpatrick 2012-12-19 15:39:19 -08:00
parent 07e706f8ce
commit 91934ff5d8
2 changed files with 14 additions and 6 deletions

View File

@ -918,15 +918,19 @@ func TestZeroLengthPostAndResponse(t *testing.T) {
}
}
func TestHandlerPanicNil(t *testing.T) {
testHandlerPanic(t, false, nil)
}
func TestHandlerPanic(t *testing.T) {
testHandlerPanic(t, false)
testHandlerPanic(t, false, "intentional death for testing")
}
func TestHandlerPanicWithHijack(t *testing.T) {
testHandlerPanic(t, true)
testHandlerPanic(t, true, "intentional death for testing")
}
func testHandlerPanic(t *testing.T, withHijack bool) {
func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
// Unlike the other tests that set the log output to ioutil.Discard
// to quiet the output, this test uses a pipe. The pipe serves three
// purposes:
@ -955,7 +959,7 @@ func testHandlerPanic(t *testing.T, withHijack bool) {
}
defer rwc.Close()
}
panic("intentional death for testing")
panic(panicValue)
}))
defer ts.Close()
@ -968,7 +972,7 @@ func testHandlerPanic(t *testing.T, withHijack bool) {
_, err := pr.Read(buf)
pr.Close()
if err != nil {
t.Fatal(err)
t.Error(err)
}
done <- true
}()
@ -978,6 +982,10 @@ func testHandlerPanic(t *testing.T, withHijack bool) {
t.Logf("expected an error")
}
if panicValue == nil {
return
}
select {
case <-done:
return

View File

@ -716,6 +716,7 @@ func (c *conn) serve() {
c.rwc.Close()
}
}()
defer c.close()
if tlsConn, ok := c.rwc.(*tls.Conn); ok {
if err := tlsConn.Handshake(); err != nil {
@ -791,7 +792,6 @@ func (c *conn) serve() {
break
}
}
c.close()
}
func (w *response) sendExpectationFailed() {