diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2011-04-14 10:40:23 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2011-04-14 10:40:23 -0700 |
| commit | e27702545ac2d1e5f545fa6b3e39dbcf36bdb023 (patch) | |
| tree | f241dec11b498a2a563d9e4686ceb89b28d5629c /src/pkg/http/server.go | |
| parent | e0533b044daae781ad7b3d01da12a9e68bb2045e (diff) | |
| download | go-e27702545ac2d1e5f545fa6b3e39dbcf36bdb023.tar.xz | |
http: consume request bodies before replying
This fixes our http behavior (even if Handlers forget to
consume a request body, we do it for them before we send
their response header), fixes the racy TestServerExpect,
and adds TestServerConsumesRequestBody.
With GOMAXPROCS>1, the http tests now seem race-free.
R=rsc
CC=golang-dev
https://golang.org/cl/4419042
Diffstat (limited to 'src/pkg/http/server.go')
| -rw-r--r-- | src/pkg/http/server.go | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/pkg/http/server.go b/src/pkg/http/server.go index 3291de1017..aa4dc29422 100644 --- a/src/pkg/http/server.go +++ b/src/pkg/http/server.go @@ -141,9 +141,13 @@ func newConn(rwc net.Conn, handler Handler) (c *conn, err os.Error) { type expectContinueReader struct { resp *response readCloser io.ReadCloser + closed bool } func (ecr *expectContinueReader) Read(p []byte) (n int, err os.Error) { + if ecr.closed { + return 0, os.NewError("http: Read after Close on request Body") + } if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked { ecr.resp.wroteContinue = true io.WriteString(ecr.resp.conn.buf, "HTTP/1.1 100 Continue\r\n\r\n") @@ -153,6 +157,7 @@ func (ecr *expectContinueReader) Read(p []byte) (n int, err os.Error) { } func (ecr *expectContinueReader) Close() os.Error { + ecr.closed = true return ecr.readCloser.Close() } @@ -196,6 +201,16 @@ func (w *response) WriteHeader(code int) { log.Print("http: multiple response.WriteHeader calls") return } + + // Per RFC 2616, we should consume the request body before + // replying, if the handler hasn't already done so. + if w.req.ContentLength != 0 { + ecr, isExpecter := w.req.Body.(*expectContinueReader) + if !isExpecter || ecr.resp.wroteContinue { + w.req.Body.Close() + } + } + w.wroteHeader = true w.status = code if code == StatusNotModified { |
