aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/http/server.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2011-04-14 10:40:23 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-04-14 10:40:23 -0700
commite27702545ac2d1e5f545fa6b3e39dbcf36bdb023 (patch)
treef241dec11b498a2a563d9e4686ceb89b28d5629c /src/pkg/http/server.go
parente0533b044daae781ad7b3d01da12a9e68bb2045e (diff)
downloadgo-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.go15
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 {