From 88fc3587ec24bf9890f9fbc1be33e313c5d99bbc Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sun, 5 Jul 2015 09:15:11 -0700 Subject: net/http: don't reuse conns after incomplete 100-continue requests If we receive an HTTP request with "Expect: 100-continue" and the Handler never read to EOF, the conn is in an unknown state. Don't reuse that connection. Fixes #11549 Change-Id: I5be93e7a54e899d615b05f72bdcf12b25304bc60 Reviewed-on: https://go-review.googlesource.com/12262 Reviewed-by: Andrew Gerrand Run-TryBot: Brad Fitzpatrick --- src/net/http/server.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/net/http/server.go') diff --git a/src/net/http/server.go b/src/net/http/server.go index 882c352144..fda26bad1d 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -554,6 +554,7 @@ type expectContinueReader struct { resp *response readCloser io.ReadCloser closed bool + sawEOF bool } func (ecr *expectContinueReader) Read(p []byte) (n int, err error) { @@ -565,7 +566,11 @@ func (ecr *expectContinueReader) Read(p []byte) (n int, err error) { ecr.resp.conn.buf.WriteString("HTTP/1.1 100 Continue\r\n\r\n") ecr.resp.conn.buf.Flush() } - return ecr.readCloser.Read(p) + n, err = ecr.readCloser.Read(p) + if err == io.EOF { + ecr.sawEOF = true + } + return } func (ecr *expectContinueReader) Close() error { @@ -846,6 +851,22 @@ func (cw *chunkWriter) writeHeader(p []byte) { w.closeAfterReply = true } + // If the client wanted a 100-continue but we never sent it to + // them (or, more strictly: we never finished reading their + // request body), don't reuse this connection because it's now + // in an unknown state: we might be sending this response at + // the same time the client is now sending its request body + // after a timeout. (Some HTTP clients send Expect: + // 100-continue but knowing that some servers don't support + // it, the clients set a timer and send the body later anyway) + // If we haven't seen EOF, we can't skip over the unread body + // because we don't know if the next bytes on the wire will be + // the body-following-the-timer or the subsequent request. + // See Issue 11549. + if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF { + w.closeAfterReply = true + } + // Per RFC 2616, we should consume the request body before // replying, if the handler hasn't already done so. But we // don't want to do an unbounded amount of reading here for -- cgit v1.3-5-g9baa