]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: document ResponseWriter read-vs-write concurrency rules
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 10 May 2016 23:09:16 +0000 (16:09 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 11 May 2016 16:54:01 +0000 (16:54 +0000)
Summary: Go's HTTP/1.x server closes the request body once writes are
flushed. Go's HTTP/2 server supports concurrent read & write.

Added a TODO to make the HTTP/1.x server also support concurrent
read+write. But for now, document it.

Updates #15527

Change-Id: I81f7354923d37bfc1632629679c75c06a62bb584
Reviewed-on: https://go-review.googlesource.com/23011
Reviewed-by: Andrew Gerrand <adg@golang.org>
src/net/http/server.go

index 23fb84fcdabf410ef3b1af208108acb052654e9b..e24777421cf34188ad6004ae1aa38352517ff369 100644 (file)
@@ -91,10 +91,24 @@ type ResponseWriter interface {
        Header() Header
 
        // Write writes the data to the connection as part of an HTTP reply.
-       // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
-       // before writing the data. If the Header does not contain a
-       // Content-Type line, Write adds a Content-Type set to the result of passing
-       // the initial 512 bytes of written data to DetectContentType.
+       //
+       // If WriteHeader has not yet been called, Write calls
+       // WriteHeader(http.StatusOK) before writing the data. If the Header
+       // does not contain a Content-Type line, Write adds a Content-Type set
+       // to the result of passing the initial 512 bytes of written data to
+       // DetectContentType.
+       //
+       // Depending on the HTTP protocol version and the client, calling
+       // Write or WriteHeader may prevent future reads on the
+       // Request.Body. For HTTP/1.x requests, handlers should read any
+       // needed request body data before writing the response. Once the
+       // headers have been flushed (due to either an explicit Flusher.Flush
+       // call or writing enough data to trigger a flush), the request body
+       // may be unavailable. For HTTP/2 requests, the Go HTTP server permits
+       // handlers to continue to read the request body while concurrently
+       // writing the response. However, such behavior may not be supported
+       // by all HTTP/2 clients. Handlers should read before writing if
+       // possible to maximize compatibility.
        Write([]byte) (int, error)
 
        // WriteHeader sends an HTTP response header with status code.
@@ -1027,6 +1041,9 @@ func (cw *chunkWriter) writeHeader(p []byte) {
        // replying, if the handler hasn't already done so. But we
        // don't want to do an unbounded amount of reading here for
        // DoS reasons, so we only try up to a threshold.
+       // TODO(bradfitz): where does RFC 2616 say that? See Issue 15527
+       // about HTTP/1.x Handlers concurrently reading and writing, like
+       // HTTP/2 handlers can do. Maybe this code should be relaxed?
        if w.req.ContentLength != 0 && !w.closeAfterReply {
                var discard, tooBig bool