1
0
mirror of https://github.com/golang/go synced 2024-09-25 03:10:12 -06:00

net/http: Release reference to chunkWriter's bufio.Writer on hijack

When a connection is hijacked, release the reference to the bufio.Writer
that is used with the chunkWriter.  The chunkWriter is not used after
the connection is hijacked.

Also add a test to check that double Hijack calls do something sensible.

benchmark                old ns/op    new ns/op    delta
BenchmarkServerHijack        24137        20629  -14.53%

benchmark               old allocs   new allocs    delta
BenchmarkServerHijack           21           19   -9.52%

benchmark                old bytes    new bytes    delta
BenchmarkServerHijack        11774         9667  -17.90%

R=bradfitz, dave, chris.cahoon
CC=golang-codereviews
https://golang.org/cl/39440044
This commit is contained in:
John Newlin 2013-12-26 11:52:14 -08:00 committed by Brad Fitzpatrick
parent 499d2167fc
commit 92b5e16147
2 changed files with 33 additions and 1 deletions

View File

@ -1934,6 +1934,31 @@ func TestWriteAfterHijack(t *testing.T) {
}
}
func TestDoubleHijack(t *testing.T) {
req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
var buf bytes.Buffer
conn := &rwTestConn{
Reader: bytes.NewReader(req),
Writer: &buf,
closec: make(chan bool, 1),
}
handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
conn, _, err := rw.(Hijacker).Hijack()
if err != nil {
t.Error(err)
return
}
_, _, err = rw.(Hijacker).Hijack()
if err == nil {
t.Errorf("got err = nil; want err != nil")
}
conn.Close()
})
ln := &oneConnListener{conn: conn}
go Serve(ln, handler)
<-conn.closec
}
// http://code.google.com/p/go/issues/detail?id=5955
// Note that this does not test the "request too large"
// exit path from the http server. This is intentional;

View File

@ -1198,7 +1198,14 @@ func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
if w.wroteHeader {
w.cw.flush()
}
return w.conn.hijack()
// Release the bufioWriter that writes to the chunk writer, it is not
// used after a connection has been hijacked.
rwc, buf, err = w.conn.hijack()
if err == nil {
putBufioWriter(w.w)
w.w = nil
}
return rwc, buf, err
}
func (w *response) CloseNotify() <-chan bool {