2008-09-24 15:26:55 -07:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
2016-03-01 23:21:55 +00:00
|
|
|
// HTTP server. See RFC 2616.
|
2008-09-24 15:26:55 -07:00
|
|
|
|
|
|
|
|
package http
|
|
|
|
|
|
|
|
|
|
import (
|
2009-12-15 15:35:38 -08:00
|
|
|
"bufio"
|
2015-12-14 01:04:07 +00:00
|
|
|
"bytes"
|
2016-04-06 12:31:55 -07:00
|
|
|
"context"
|
2010-07-02 13:00:18 -04:00
|
|
|
"crypto/tls"
|
2011-11-01 22:04:37 -04:00
|
|
|
"errors"
|
2009-12-15 15:35:38 -08:00
|
|
|
"fmt"
|
|
|
|
|
"io"
|
2011-10-14 17:34:07 -07:00
|
|
|
"io/ioutil"
|
2009-12-15 15:35:38 -08:00
|
|
|
"log"
|
|
|
|
|
"net"
|
2014-12-29 19:32:07 -08:00
|
|
|
"net/textproto"
|
2011-11-08 15:41:54 -08:00
|
|
|
"net/url"
|
2013-08-08 14:02:54 -07:00
|
|
|
"os"
|
2009-12-15 15:35:38 -08:00
|
|
|
"path"
|
2012-11-22 08:18:45 +11:00
|
|
|
"runtime"
|
2009-12-15 15:35:38 -08:00
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
2011-04-15 12:53:32 -07:00
|
|
|
"sync"
|
2014-02-28 07:40:25 -08:00
|
|
|
"sync/atomic"
|
2010-07-02 13:00:18 -04:00
|
|
|
"time"
|
2016-05-19 02:13:36 +00:00
|
|
|
|
2016-07-13 10:49:48 -06:00
|
|
|
"golang_org/x/net/lex/httplex"
|
2008-09-24 15:26:55 -07:00
|
|
|
)
|
|
|
|
|
|
2016-04-30 20:11:34 -07:00
|
|
|
// Errors used by the HTTP server.
|
2009-03-11 12:51:10 -07:00
|
|
|
var (
|
2016-04-30 20:11:34 -07:00
|
|
|
// ErrBodyNotAllowed is returned by ResponseWriter.Write calls
|
|
|
|
|
// when the HTTP method or response code does not permit a
|
|
|
|
|
// body.
|
|
|
|
|
ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
|
|
|
|
|
|
|
|
|
|
// ErrHijacked is returned by ResponseWriter.Write calls when
|
|
|
|
|
// the underlying connection has been hijacked using the
|
2016-10-16 10:27:29 +01:00
|
|
|
// Hijacker interface. A zero-byte write on a hijacked
|
|
|
|
|
// connection will return ErrHijacked without any other side
|
|
|
|
|
// effects.
|
2016-04-30 20:11:34 -07:00
|
|
|
ErrHijacked = errors.New("http: connection has been hijacked")
|
|
|
|
|
|
|
|
|
|
// ErrContentLength is returned by ResponseWriter.Write calls
|
|
|
|
|
// when a Handler set a Content-Length response header with a
|
|
|
|
|
// declared size and then attempted to write more bytes than
|
|
|
|
|
// declared.
|
|
|
|
|
ErrContentLength = errors.New("http: wrote more than the declared Content-Length")
|
|
|
|
|
|
|
|
|
|
// Deprecated: ErrWriteAfterFlush is no longer used.
|
|
|
|
|
ErrWriteAfterFlush = errors.New("unused")
|
2009-03-11 12:51:10 -07:00
|
|
|
)
|
2009-02-02 18:01:32 -08:00
|
|
|
|
2015-12-17 20:53:41 +00:00
|
|
|
// A Handler responds to an HTTP request.
|
2010-02-12 14:27:44 -08:00
|
|
|
//
|
2010-09-29 14:30:12 +10:00
|
|
|
// ServeHTTP should write reply headers and data to the ResponseWriter
|
2015-12-17 20:53:41 +00:00
|
|
|
// and then return. Returning signals that the request is finished; it
|
|
|
|
|
// is not valid to use the ResponseWriter or read from the
|
|
|
|
|
// Request.Body after or concurrently with the completion of the
|
|
|
|
|
// ServeHTTP call.
|
|
|
|
|
//
|
|
|
|
|
// Depending on the HTTP client software, HTTP protocol version, and
|
|
|
|
|
// any intermediaries between the client and the Go server, it may not
|
|
|
|
|
// be possible to read from the Request.Body after writing to the
|
|
|
|
|
// ResponseWriter. Cautious handlers should read the Request.Body
|
|
|
|
|
// first, and then reply.
|
2014-09-19 13:53:33 -04:00
|
|
|
//
|
2016-04-05 15:59:55 +00:00
|
|
|
// Except for reading the body, handlers should not modify the
|
|
|
|
|
// provided Request.
|
|
|
|
|
//
|
2014-09-19 13:53:33 -04:00
|
|
|
// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes
|
|
|
|
|
// that the effect of the panic was isolated to the active request.
|
|
|
|
|
// It recovers the panic, logs a stack trace to the server error log,
|
2016-11-10 23:16:14 +00:00
|
|
|
// and hangs up the connection. To abort a handler so the client sees
|
|
|
|
|
// an interrupted response but the server doesn't log an error, panic
|
|
|
|
|
// with the value ErrAbortHandler.
|
2009-02-02 18:01:32 -08:00
|
|
|
type Handler interface {
|
2010-09-29 14:30:12 +10:00
|
|
|
ServeHTTP(ResponseWriter, *Request)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A ResponseWriter interface is used by an HTTP handler to
|
|
|
|
|
// construct an HTTP response.
|
2015-12-17 20:53:41 +00:00
|
|
|
//
|
|
|
|
|
// A ResponseWriter may not be used after the Handler.ServeHTTP method
|
|
|
|
|
// has returned.
|
2010-09-29 14:30:12 +10:00
|
|
|
type ResponseWriter interface {
|
2014-12-29 19:32:07 -08:00
|
|
|
// Header returns the header map that will be sent by
|
2016-11-01 15:24:11 +00:00
|
|
|
// WriteHeader. The Header map also is the mechanism with which
|
|
|
|
|
// Handlers can set HTTP trailers.
|
|
|
|
|
//
|
|
|
|
|
// Changing the header map after a call to WriteHeader (or
|
|
|
|
|
// Write) has no effect unless the modified headers are
|
|
|
|
|
// trailers.
|
|
|
|
|
//
|
|
|
|
|
// There are two ways to set Trailers. The preferred way is to
|
|
|
|
|
// predeclare in the headers which trailers you will later
|
|
|
|
|
// send by setting the "Trailer" header to the names of the
|
|
|
|
|
// trailer keys which will come later. In this case, those
|
|
|
|
|
// keys of the Header map are treated as if they were
|
|
|
|
|
// trailers. See the example. The second way, for trailer
|
|
|
|
|
// keys not known to the Handler until after the first Write,
|
|
|
|
|
// is to prefix the Header map keys with the TrailerPrefix
|
|
|
|
|
// constant value. See TrailerPrefix.
|
|
|
|
|
//
|
|
|
|
|
// To suppress implicit response headers (such as "Date"), set
|
|
|
|
|
// their value to nil.
|
2011-03-09 09:41:01 -08:00
|
|
|
Header() Header
|
2010-09-29 14:30:12 +10:00
|
|
|
|
|
|
|
|
// Write writes the data to the connection as part of an HTTP reply.
|
2016-05-10 16:09:16 -07:00
|
|
|
//
|
|
|
|
|
// 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.
|
2011-11-01 22:04:37 -04:00
|
|
|
Write([]byte) (int, error)
|
2010-09-29 14:30:12 +10:00
|
|
|
|
|
|
|
|
// WriteHeader sends an HTTP response header with status code.
|
|
|
|
|
// If WriteHeader is not called explicitly, the first call to Write
|
|
|
|
|
// will trigger an implicit WriteHeader(http.StatusOK).
|
|
|
|
|
// Thus explicit calls to WriteHeader are mainly used to
|
|
|
|
|
// send error codes.
|
|
|
|
|
WriteHeader(int)
|
2011-03-09 10:24:50 -08:00
|
|
|
}
|
2010-09-29 14:30:12 +10:00
|
|
|
|
2011-03-09 10:24:50 -08:00
|
|
|
// The Flusher interface is implemented by ResponseWriters that allow
|
|
|
|
|
// an HTTP handler to flush buffered data to the client.
|
|
|
|
|
//
|
2016-04-15 21:56:30 +00:00
|
|
|
// The default HTTP/1.x and HTTP/2 ResponseWriter implementations
|
|
|
|
|
// support Flusher, but ResponseWriter wrappers may not. Handlers
|
|
|
|
|
// should always test for this ability at runtime.
|
|
|
|
|
//
|
2011-03-09 10:24:50 -08:00
|
|
|
// Note that even for ResponseWriters that support Flush,
|
|
|
|
|
// if the client is connected through an HTTP proxy,
|
|
|
|
|
// the buffered data may not reach the client until the response
|
|
|
|
|
// completes.
|
|
|
|
|
type Flusher interface {
|
2010-09-29 14:30:12 +10:00
|
|
|
// Flush sends any buffered data to the client.
|
|
|
|
|
Flush()
|
2011-03-06 18:59:50 -08:00
|
|
|
}
|
2010-09-29 14:30:12 +10:00
|
|
|
|
2011-03-07 12:04:04 -08:00
|
|
|
// The Hijacker interface is implemented by ResponseWriters that allow
|
|
|
|
|
// an HTTP handler to take over the connection.
|
2016-04-15 21:56:30 +00:00
|
|
|
//
|
|
|
|
|
// The default ResponseWriter for HTTP/1.x connections supports
|
|
|
|
|
// Hijacker, but HTTP/2 connections intentionally do not.
|
|
|
|
|
// ResponseWriter wrappers may also not support Hijacker. Handlers
|
|
|
|
|
// should always test for this ability at runtime.
|
2011-03-06 18:59:50 -08:00
|
|
|
type Hijacker interface {
|
2010-09-29 14:30:12 +10:00
|
|
|
// Hijack lets the caller take over the connection.
|
2017-01-13 21:43:56 +00:00
|
|
|
// After a call to Hijack the HTTP server library
|
2010-09-29 14:30:12 +10:00
|
|
|
// will not do anything else with the connection.
|
2015-06-24 12:11:58 +02:00
|
|
|
//
|
2010-09-29 14:30:12 +10:00
|
|
|
// It becomes the caller's responsibility to manage
|
|
|
|
|
// and close the connection.
|
2015-06-24 12:11:58 +02:00
|
|
|
//
|
|
|
|
|
// The returned net.Conn may have read or write deadlines
|
|
|
|
|
// already set, depending on the configuration of the
|
|
|
|
|
// Server. It is the caller's responsibility to set
|
|
|
|
|
// or clear those deadlines as needed.
|
2017-01-13 21:43:56 +00:00
|
|
|
//
|
|
|
|
|
// The returned bufio.Reader may contain unprocessed buffered
|
|
|
|
|
// data from the client.
|
2011-11-01 22:04:37 -04:00
|
|
|
Hijack() (net.Conn, *bufio.ReadWriter, error)
|
2010-09-29 14:30:12 +10:00
|
|
|
}
|
|
|
|
|
|
2012-12-05 19:25:43 -08:00
|
|
|
// The CloseNotifier interface is implemented by ResponseWriters which
|
|
|
|
|
// allow detecting when the underlying connection has gone away.
|
|
|
|
|
//
|
|
|
|
|
// This mechanism can be used to cancel long operations on the server
|
|
|
|
|
// if the client has disconnected before the response is ready.
|
|
|
|
|
type CloseNotifier interface {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// CloseNotify returns a channel that receives at most a
|
|
|
|
|
// single value (true) when the client connection has gone
|
|
|
|
|
// away.
|
|
|
|
|
//
|
2016-01-04 20:38:20 +00:00
|
|
|
// CloseNotify may wait to notify until Request.Body has been
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// fully read.
|
|
|
|
|
//
|
|
|
|
|
// After the Handler has returned, there is no guarantee
|
|
|
|
|
// that the channel receives a value.
|
|
|
|
|
//
|
|
|
|
|
// If the protocol is HTTP/1.1 and CloseNotify is called while
|
|
|
|
|
// processing an idempotent request (such a GET) while
|
|
|
|
|
// HTTP/1.1 pipelining is in use, the arrival of a subsequent
|
2016-01-04 20:38:20 +00:00
|
|
|
// pipelined request may cause a value to be sent on the
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// returned channel. In practice HTTP/1.1 pipelining is not
|
|
|
|
|
// enabled in browsers and not seen often in the wild. If this
|
|
|
|
|
// is a problem, use HTTP/2 or only use CloseNotify on methods
|
|
|
|
|
// such as POST.
|
2012-12-05 19:25:43 -08:00
|
|
|
CloseNotify() <-chan bool
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 05:12:43 +00:00
|
|
|
var (
|
|
|
|
|
// ServerContextKey is a context key. It can be used in HTTP
|
|
|
|
|
// handlers with context.WithValue to access the server that
|
|
|
|
|
// started the handler. The associated value will be of
|
|
|
|
|
// type *Server.
|
|
|
|
|
ServerContextKey = &contextKey{"http-server"}
|
2016-04-30 21:11:26 -07:00
|
|
|
|
|
|
|
|
// LocalAddrContextKey is a context key. It can be used in
|
|
|
|
|
// HTTP handlers with context.WithValue to access the address
|
|
|
|
|
// the local address the connection arrived on.
|
|
|
|
|
// The associated value will be of type net.Addr.
|
|
|
|
|
LocalAddrContextKey = &contextKey{"local-addr"}
|
2016-04-11 05:12:43 +00:00
|
|
|
)
|
|
|
|
|
|
2010-09-29 14:30:12 +10:00
|
|
|
// A conn represents the server side of an HTTP connection.
|
|
|
|
|
type conn struct {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// server is the server on which the connection arrived.
|
|
|
|
|
// Immutable; never nil.
|
|
|
|
|
server *Server
|
|
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
// cancelCtx cancels the connection-level context.
|
|
|
|
|
cancelCtx context.CancelFunc
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// rwc is the underlying network connection.
|
|
|
|
|
// This is never wrapped by other types and is the value given out
|
|
|
|
|
// to CloseNotifier callers. It is usually of type *net.TCPConn or
|
|
|
|
|
// *tls.Conn.
|
|
|
|
|
rwc net.Conn
|
|
|
|
|
|
|
|
|
|
// remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously
|
|
|
|
|
// inside the Listener's Accept goroutine, as some implementations block.
|
|
|
|
|
// It is populated immediately inside the (*conn).serve goroutine.
|
|
|
|
|
// This is the value of a Handler's (*Request).RemoteAddr.
|
|
|
|
|
remoteAddr string
|
|
|
|
|
|
|
|
|
|
// tlsState is the TLS connection state when using TLS.
|
|
|
|
|
// nil means not TLS.
|
|
|
|
|
tlsState *tls.ConnectionState
|
|
|
|
|
|
|
|
|
|
// werr is set to the first write error to rwc.
|
|
|
|
|
// It is set via checkConnErrorWriter{w}, where bufw writes.
|
|
|
|
|
werr error
|
|
|
|
|
|
|
|
|
|
// r is bufr's read source. It's a wrapper around rwc that provides
|
|
|
|
|
// io.LimitedReader-style limiting (while reading request headers)
|
|
|
|
|
// and functionality to support CloseNotifier. See *connReader docs.
|
|
|
|
|
r *connReader
|
|
|
|
|
|
|
|
|
|
// bufr reads from r.
|
|
|
|
|
bufr *bufio.Reader
|
|
|
|
|
|
|
|
|
|
// bufw writes to checkConnErrorWriter{c}, which populates werr on error.
|
|
|
|
|
bufw *bufio.Writer
|
|
|
|
|
|
|
|
|
|
// lastMethod is the method of the most recent request
|
|
|
|
|
// on this connection, if any.
|
|
|
|
|
lastMethod string
|
|
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
curReq atomic.Value // of *response (which has a Request in it)
|
|
|
|
|
|
2016-11-04 03:33:44 +00:00
|
|
|
curState atomic.Value // of ConnState
|
2016-10-30 03:28:05 +00:00
|
|
|
|
2016-10-23 06:04:14 -07:00
|
|
|
// mu guards hijackedv
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// hijackedv is whether this connection has been hijacked
|
|
|
|
|
// by a Handler with the Hijacker interface.
|
|
|
|
|
// It is guarded by mu.
|
|
|
|
|
hijackedv bool
|
2012-12-05 19:25:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *conn) hijacked() bool {
|
|
|
|
|
c.mu.Lock()
|
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
|
return c.hijackedv
|
|
|
|
|
}
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// c.mu must be held.
|
|
|
|
|
func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
|
2012-12-05 19:25:43 -08:00
|
|
|
if c.hijackedv {
|
|
|
|
|
return nil, nil, ErrHijacked
|
|
|
|
|
}
|
2016-10-14 11:45:59 +01:00
|
|
|
c.r.abortPendingRead()
|
|
|
|
|
|
2012-12-05 19:25:43 -08:00
|
|
|
c.hijackedv = true
|
|
|
|
|
rwc = c.rwc
|
2016-10-14 11:45:59 +01:00
|
|
|
rwc.SetDeadline(time.Time{})
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
buf = bufio.NewReadWriter(c.bufr, bufio.NewWriter(rwc))
|
2017-01-13 21:43:56 +00:00
|
|
|
if c.r.hasByte {
|
|
|
|
|
if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {
|
|
|
|
|
return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-03-03 18:58:28 -08:00
|
|
|
c.setState(rwc, StateHijacked)
|
2012-12-05 19:25:43 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-11 10:03:43 -08:00
|
|
|
// This should be >= 512 bytes for DetectContentType,
|
|
|
|
|
// but otherwise it's somewhat arbitrary.
|
|
|
|
|
const bufferBeforeChunkingSize = 2048
|
|
|
|
|
|
|
|
|
|
// chunkWriter writes to a response's conn buffer, and is the writer
|
|
|
|
|
// wrapped by the response.bufw buffered writer.
|
|
|
|
|
//
|
|
|
|
|
// chunkWriter also is responsible for finalizing the Header, including
|
|
|
|
|
// conditionally setting the Content-Type and setting a Content-Length
|
|
|
|
|
// in cases where the handler's final output is smaller than the buffer
|
|
|
|
|
// size. It also conditionally adds chunk headers, when in chunking mode.
|
|
|
|
|
//
|
|
|
|
|
// See the comment above (*response).Write for the entire write flow.
|
|
|
|
|
type chunkWriter struct {
|
2013-03-28 11:35:24 -07:00
|
|
|
res *response
|
|
|
|
|
|
2013-04-02 16:27:23 -07:00
|
|
|
// header is either nil or a deep clone of res.handlerHeader
|
|
|
|
|
// at the time of res.WriteHeader, if res.WriteHeader is
|
|
|
|
|
// called and extra buffering is being done to calculate
|
|
|
|
|
// Content-Type and/or Content-Length.
|
2013-03-28 11:35:24 -07:00
|
|
|
header Header
|
|
|
|
|
|
|
|
|
|
// wroteHeader tells whether the header's been written to "the
|
|
|
|
|
// wire" (or rather: w.conn.buf). this is unlike
|
|
|
|
|
// (*response).wroteHeader, which tells only whether it was
|
|
|
|
|
// logically written.
|
|
|
|
|
wroteHeader bool
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
// set by the writeHeader method:
|
|
|
|
|
chunking bool // using chunked transfer encoding for reply body
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 16:27:23 -07:00
|
|
|
var (
|
|
|
|
|
crlf = []byte("\r\n")
|
|
|
|
|
colonSpace = []byte(": ")
|
|
|
|
|
)
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
func (cw *chunkWriter) Write(p []byte) (n int, err error) {
|
|
|
|
|
if !cw.wroteHeader {
|
|
|
|
|
cw.writeHeader(p)
|
|
|
|
|
}
|
net/http: treat HEAD requests like GET requests
A response to a HEAD request is supposed to look the same as a
response to a GET request, just without a body.
HEAD requests are incredibly rare in the wild.
The Go net/http package has so far treated HEAD requests
specially: a Write on our default ResponseWriter returned
ErrBodyNotAllowed, telling handlers that something was wrong.
This was to optimize the fast path for HEAD requests, but:
1) because HEAD requests are incredibly rare, they're not
worth having a fast path for.
2) Letting the http.Handler handle but do nop Writes is still
very fast.
3) this forces ugly error handling into the application.
e.g. https://code.google.com/p/go/source/detail?r=6f596be7a31e
and related.
4) The net/http package nowadays does Content-Type sniffing,
but you don't get that for HEAD.
5) The net/http package nowadays does Content-Length counting
for small (few KB) responses, but not for HEAD.
6) ErrBodyNotAllowed was useless. By the time you received it,
you had probably already done all your heavy computation
and I/O to calculate what to write.
So, this change makes HEAD requests like GET requests.
We now count content-length and sniff content-type for HEAD
requests. If you Write, it doesn't return an error.
If you want a fast-path in your code for HEAD, you have to do
it early and set all the response headers yourself. Just like
before. If you choose not to Write in HEAD requests, be sure
to set Content-Length if you know it. We won't write
"Content-Length: 0" because you might've just chosen to not
write (or you don't know your Content-Length in advance).
Fixes #5454
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/12583043
2013-08-06 18:33:03 -07:00
|
|
|
if cw.res.req.Method == "HEAD" {
|
|
|
|
|
// Eat writes.
|
|
|
|
|
return len(p), nil
|
|
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
if cw.chunking {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
_, err = fmt.Fprintf(cw.res.conn.bufw, "%x\r\n", len(p))
|
2013-01-11 10:03:43 -08:00
|
|
|
if err != nil {
|
2013-02-04 20:26:25 -08:00
|
|
|
cw.res.conn.rwc.Close()
|
2013-01-11 10:03:43 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
n, err = cw.res.conn.bufw.Write(p)
|
2013-01-11 10:03:43 -08:00
|
|
|
if cw.chunking && err == nil {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
_, err = cw.res.conn.bufw.Write(crlf)
|
2013-01-11 10:03:43 -08:00
|
|
|
}
|
2013-02-04 20:26:25 -08:00
|
|
|
if err != nil {
|
|
|
|
|
cw.res.conn.rwc.Close()
|
|
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (cw *chunkWriter) flush() {
|
|
|
|
|
if !cw.wroteHeader {
|
|
|
|
|
cw.writeHeader(nil)
|
|
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
cw.res.conn.bufw.Flush()
|
2013-01-11 10:03:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (cw *chunkWriter) close() {
|
|
|
|
|
if !cw.wroteHeader {
|
|
|
|
|
cw.writeHeader(nil)
|
|
|
|
|
}
|
|
|
|
|
if cw.chunking {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
bw := cw.res.conn.bufw // conn's bufio writer
|
2014-12-29 19:32:07 -08:00
|
|
|
// zero chunk to mark EOF
|
|
|
|
|
bw.WriteString("0\r\n")
|
2016-11-01 15:24:11 +00:00
|
|
|
if trailers := cw.res.finalTrailers(); trailers != nil {
|
2014-12-29 19:32:07 -08:00
|
|
|
trailers.Write(bw) // the writer handles noting errors
|
|
|
|
|
}
|
|
|
|
|
// final blank line after the trailers (whether
|
|
|
|
|
// present or not)
|
|
|
|
|
bw.WriteString("\r\n")
|
2013-01-11 10:03:43 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-29 14:30:12 +10:00
|
|
|
// A response represents the server side of an HTTP response.
|
|
|
|
|
type response struct {
|
2016-04-05 15:59:55 +00:00
|
|
|
conn *conn
|
|
|
|
|
req *Request // request for this response
|
|
|
|
|
reqBody io.ReadCloser
|
2016-04-06 12:31:55 -07:00
|
|
|
cancelCtx context.CancelFunc // when ServeHTTP exits
|
|
|
|
|
wroteHeader bool // reply header has been (logically) written
|
|
|
|
|
wroteContinue bool // 100 Continue response was written
|
|
|
|
|
wants10KeepAlive bool // HTTP/1.0 w/ Connection "keep-alive"
|
|
|
|
|
wantsClose bool // HTTP request has Connection "close"
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
w *bufio.Writer // buffers output in chunks to chunkWriter
|
2013-03-28 13:13:28 -07:00
|
|
|
cw chunkWriter
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
// handlerHeader is the Header that Handlers get access to,
|
|
|
|
|
// which may be retained and mutated even after WriteHeader.
|
|
|
|
|
// handlerHeader is copied into cw.header at WriteHeader
|
|
|
|
|
// time, and privately mutated thereafter.
|
|
|
|
|
handlerHeader Header
|
2013-03-28 11:35:24 -07:00
|
|
|
calledHeader bool // handler accessed handlerHeader via Header
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
written int64 // number of bytes written in body
|
|
|
|
|
contentLength int64 // explicitly-declared Content-Length; or -1
|
|
|
|
|
status int // status code passed to WriteHeader
|
2010-09-27 21:55:04 -04:00
|
|
|
|
|
|
|
|
// close connection after this reply. set on request and
|
|
|
|
|
// updated after response from handler if there's a
|
|
|
|
|
// "Connection: keep-alive" response header and a
|
|
|
|
|
// Content-Length.
|
|
|
|
|
closeAfterReply bool
|
2011-08-23 12:17:21 +04:00
|
|
|
|
|
|
|
|
// requestBodyLimitHit is set by requestTooLarge when
|
|
|
|
|
// maxBytesReader hits its max size. It is checked in
|
2012-11-22 02:58:24 +08:00
|
|
|
// WriteHeader, to make sure we don't consume the
|
2011-08-23 12:17:21 +04:00
|
|
|
// remaining request body to try to advance to the next HTTP
|
2012-05-29 12:40:13 -07:00
|
|
|
// request. Instead, when this is set, we stop reading
|
2011-08-23 12:17:21 +04:00
|
|
|
// subsequent requests on this connection and stop reading
|
|
|
|
|
// input from it.
|
|
|
|
|
requestBodyLimitHit bool
|
2013-01-11 10:03:43 -08:00
|
|
|
|
2014-12-29 19:32:07 -08:00
|
|
|
// trailers are the headers to be sent after the handler
|
2016-03-01 23:21:55 +00:00
|
|
|
// finishes writing the body. This field is initialized from
|
2014-12-29 19:32:07 -08:00
|
|
|
// the Trailer response header when the response header is
|
|
|
|
|
// written.
|
|
|
|
|
trailers []string
|
|
|
|
|
|
2016-01-18 11:43:32 -08:00
|
|
|
handlerDone atomicBool // set true when the handler exits
|
2013-05-19 20:15:40 -07:00
|
|
|
|
|
|
|
|
// Buffers for Date and Content-Length
|
|
|
|
|
dateBuf [len(TimeFormat)]byte
|
|
|
|
|
clenBuf [10]byte
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
// closeNotifyCh is the channel returned by CloseNotify.
|
|
|
|
|
// TODO(bradfitz): this is currently (for Go 1.8) always
|
2016-10-23 06:04:14 -07:00
|
|
|
// non-nil. Make this lazily-created again as it used to be?
|
2016-10-14 11:45:59 +01:00
|
|
|
closeNotifyCh chan bool
|
|
|
|
|
didCloseNotify int32 // atomic (only 0->1 winner should send)
|
2011-08-23 12:17:21 +04:00
|
|
|
}
|
|
|
|
|
|
2016-11-01 15:24:11 +00:00
|
|
|
// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
|
|
|
|
|
// that, if present, signals that the map entry is actually for
|
|
|
|
|
// the response trailers, and not the response headers. The prefix
|
|
|
|
|
// is stripped after the ServeHTTP call finishes and the values are
|
|
|
|
|
// sent in the trailers.
|
|
|
|
|
//
|
|
|
|
|
// This mechanism is intended only for trailers that are not known
|
|
|
|
|
// prior to the headers being written. If the set of trailers is fixed
|
|
|
|
|
// or known before the header is written, the normal Go trailers mechanism
|
|
|
|
|
// is preferred:
|
|
|
|
|
// https://golang.org/pkg/net/http/#ResponseWriter
|
|
|
|
|
// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
|
|
|
|
|
const TrailerPrefix = "Trailer:"
|
|
|
|
|
|
|
|
|
|
// finalTrailers is called after the Handler exits and returns a non-nil
|
|
|
|
|
// value if the Handler set any trailers.
|
|
|
|
|
func (w *response) finalTrailers() Header {
|
|
|
|
|
var t Header
|
|
|
|
|
for k, vv := range w.handlerHeader {
|
|
|
|
|
if strings.HasPrefix(k, TrailerPrefix) {
|
|
|
|
|
if t == nil {
|
|
|
|
|
t = make(Header)
|
|
|
|
|
}
|
|
|
|
|
t[strings.TrimPrefix(k, TrailerPrefix)] = vv
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, k := range w.trailers {
|
|
|
|
|
if t == nil {
|
|
|
|
|
t = make(Header)
|
|
|
|
|
}
|
|
|
|
|
for _, v := range w.handlerHeader[k] {
|
|
|
|
|
t.Add(k, v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-18 11:43:32 -08:00
|
|
|
type atomicBool int32
|
|
|
|
|
|
|
|
|
|
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
|
|
|
|
|
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
|
|
|
|
|
|
2014-12-29 19:32:07 -08:00
|
|
|
// declareTrailer is called for each Trailer header when the
|
|
|
|
|
// response header is written. It notes that a header will need to be
|
|
|
|
|
// written in the trailers at the end of the response.
|
|
|
|
|
func (w *response) declareTrailer(k string) {
|
|
|
|
|
k = CanonicalHeaderKey(k)
|
|
|
|
|
switch k {
|
|
|
|
|
case "Transfer-Encoding", "Content-Length", "Trailer":
|
|
|
|
|
// Forbidden by RFC 2616 14.40.
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
w.trailers = append(w.trailers, k)
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-23 12:17:21 +04:00
|
|
|
// requestTooLarge is called by maxBytesReader when too much input has
|
|
|
|
|
// been read from the client.
|
2011-10-14 17:34:07 -07:00
|
|
|
func (w *response) requestTooLarge() {
|
|
|
|
|
w.closeAfterReply = true
|
|
|
|
|
w.requestBodyLimitHit = true
|
|
|
|
|
if !w.wroteHeader {
|
|
|
|
|
w.Header().Set("Connection", "close")
|
2011-08-23 12:17:21 +04:00
|
|
|
}
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2013-07-23 11:59:49 +10:00
|
|
|
// needsSniff reports whether a Content-Type still needs to be sniffed.
|
2013-01-11 10:03:43 -08:00
|
|
|
func (w *response) needsSniff() bool {
|
2013-10-15 08:22:04 +11:00
|
|
|
_, haveType := w.handlerHeader["Content-Type"]
|
|
|
|
|
return !w.cw.wroteHeader && !haveType && w.written < sniffLen
|
2013-01-11 10:03:43 -08:00
|
|
|
}
|
|
|
|
|
|
2013-08-08 14:02:54 -07:00
|
|
|
// writerOnly hides an io.Writer value's optional ReadFrom method
|
|
|
|
|
// from io.Copy.
|
2011-05-25 10:15:26 -07:00
|
|
|
type writerOnly struct {
|
|
|
|
|
io.Writer
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-08 14:02:54 -07:00
|
|
|
func srcIsRegularFile(src io.Reader) (isRegular bool, err error) {
|
|
|
|
|
switch v := src.(type) {
|
|
|
|
|
case *os.File:
|
|
|
|
|
fi, err := v.Stat()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
return fi.Mode().IsRegular(), nil
|
|
|
|
|
case *io.LimitedReader:
|
|
|
|
|
return srcIsRegularFile(v.R)
|
|
|
|
|
default:
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadFrom is here to optimize copying from an *os.File regular file
|
|
|
|
|
// to a *net.TCPConn with sendfile.
|
2011-11-01 22:04:37 -04:00
|
|
|
func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
|
2013-08-08 14:02:54 -07:00
|
|
|
// Our underlying w.conn.rwc is usually a *TCPConn (with its
|
|
|
|
|
// own ReadFrom method). If not, or if our src isn't a regular
|
|
|
|
|
// file, just fall back to the normal copy method.
|
|
|
|
|
rf, ok := w.conn.rwc.(io.ReaderFrom)
|
|
|
|
|
regFile, err := srcIsRegularFile(src)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
if !ok || !regFile {
|
2015-09-03 01:19:51 +03:00
|
|
|
bufp := copyBufPool.Get().(*[]byte)
|
|
|
|
|
defer copyBufPool.Put(bufp)
|
|
|
|
|
return io.CopyBuffer(writerOnly{w}, src, *bufp)
|
2013-08-08 14:02:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// sendfile path:
|
|
|
|
|
|
2011-11-09 15:48:05 +11:00
|
|
|
if !w.wroteHeader {
|
|
|
|
|
w.WriteHeader(StatusOK)
|
|
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
if w.needsSniff() {
|
|
|
|
|
n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen))
|
|
|
|
|
n += n0
|
|
|
|
|
if err != nil {
|
|
|
|
|
return n, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
w.w.Flush() // get rid of any previous writes
|
|
|
|
|
w.cw.flush() // make sure Header is written; flush data to rwc
|
|
|
|
|
|
|
|
|
|
// Now that cw has been flushed, its chunking field is guaranteed initialized.
|
|
|
|
|
if !w.cw.chunking && w.bodyAllowed() {
|
2013-08-08 14:02:54 -07:00
|
|
|
n0, err := rf.ReadFrom(src)
|
|
|
|
|
n += n0
|
|
|
|
|
w.written += n0
|
|
|
|
|
return n, err
|
2011-05-25 10:15:26 -07:00
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
n0, err := io.Copy(writerOnly{w}, src)
|
|
|
|
|
n += n0
|
|
|
|
|
return n, err
|
2011-05-25 10:15:26 -07:00
|
|
|
}
|
|
|
|
|
|
net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
2012-11-26 13:31:02 -08:00
|
|
|
// debugServerConnections controls whether all server connections are wrapped
|
|
|
|
|
// with a verbose logging wrapper.
|
|
|
|
|
const debugServerConnections = false
|
|
|
|
|
|
2009-02-02 18:01:32 -08:00
|
|
|
// Create new connection from rwc.
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
func (srv *Server) newConn(rwc net.Conn) *conn {
|
|
|
|
|
c := &conn{
|
|
|
|
|
server: srv,
|
|
|
|
|
rwc: rwc,
|
|
|
|
|
}
|
net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
2012-11-26 13:31:02 -08:00
|
|
|
if debugServerConnections {
|
|
|
|
|
c.rwc = newLoggingConn("server", c.rwc)
|
|
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type readResult struct {
|
|
|
|
|
n int
|
|
|
|
|
err error
|
|
|
|
|
b byte // byte read, if n == 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// connReader is the io.Reader wrapper used by *conn. It combines a
|
|
|
|
|
// selectively-activated io.LimitedReader (to bound request header
|
|
|
|
|
// read sizes) with support for selectively keeping an io.Reader.Read
|
2015-12-23 23:56:47 +01:00
|
|
|
// call blocked in a background goroutine to wait for activity and
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// trigger a CloseNotifier channel.
|
|
|
|
|
type connReader struct {
|
2016-10-14 11:45:59 +01:00
|
|
|
conn *conn
|
|
|
|
|
|
|
|
|
|
mu sync.Mutex // guards following
|
|
|
|
|
hasByte bool
|
|
|
|
|
byteBuf [1]byte
|
|
|
|
|
bgErr error // non-nil means error happened on background read
|
|
|
|
|
cond *sync.Cond
|
|
|
|
|
inRead bool
|
|
|
|
|
aborted bool // set true before conn.rwc deadline is set to past
|
|
|
|
|
remain int64 // bytes remaining
|
|
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
func (cr *connReader) lock() {
|
|
|
|
|
cr.mu.Lock()
|
|
|
|
|
if cr.cond == nil {
|
|
|
|
|
cr.cond = sync.NewCond(&cr.mu)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (cr *connReader) unlock() { cr.mu.Unlock() }
|
|
|
|
|
|
|
|
|
|
func (cr *connReader) startBackgroundRead() {
|
|
|
|
|
cr.lock()
|
|
|
|
|
defer cr.unlock()
|
|
|
|
|
if cr.inRead {
|
|
|
|
|
panic("invalid concurrent Body.Read call")
|
|
|
|
|
}
|
2017-01-06 20:41:14 -08:00
|
|
|
if cr.hasByte {
|
|
|
|
|
return
|
|
|
|
|
}
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.inRead = true
|
2017-01-04 21:03:24 +00:00
|
|
|
cr.conn.rwc.SetReadDeadline(time.Time{})
|
2016-10-14 11:45:59 +01:00
|
|
|
go cr.backgroundRead()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (cr *connReader) backgroundRead() {
|
|
|
|
|
n, err := cr.conn.rwc.Read(cr.byteBuf[:])
|
|
|
|
|
cr.lock()
|
|
|
|
|
if n == 1 {
|
|
|
|
|
cr.hasByte = true
|
|
|
|
|
// We were at EOF already (since we wouldn't be in a
|
|
|
|
|
// background read otherwise), so this is a pipelined
|
|
|
|
|
// HTTP request.
|
|
|
|
|
cr.closeNotifyFromPipelinedRequest()
|
|
|
|
|
}
|
|
|
|
|
if ne, ok := err.(net.Error); ok && cr.aborted && ne.Timeout() {
|
|
|
|
|
// Ignore this error. It's the expected error from
|
|
|
|
|
// another goroutine calling abortPendingRead.
|
|
|
|
|
} else if err != nil {
|
|
|
|
|
cr.handleReadError(err)
|
|
|
|
|
}
|
|
|
|
|
cr.aborted = false
|
|
|
|
|
cr.inRead = false
|
|
|
|
|
cr.unlock()
|
|
|
|
|
cr.cond.Broadcast()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (cr *connReader) abortPendingRead() {
|
|
|
|
|
cr.lock()
|
|
|
|
|
defer cr.unlock()
|
|
|
|
|
if !cr.inRead {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
cr.aborted = true
|
|
|
|
|
cr.conn.rwc.SetReadDeadline(aLongTimeAgo)
|
|
|
|
|
for cr.inRead {
|
|
|
|
|
cr.cond.Wait()
|
|
|
|
|
}
|
|
|
|
|
cr.conn.rwc.SetReadDeadline(time.Time{})
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (cr *connReader) setReadLimit(remain int64) { cr.remain = remain }
|
2016-03-31 00:06:27 -07:00
|
|
|
func (cr *connReader) setInfiniteReadLimit() { cr.remain = maxInt64 }
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
func (cr *connReader) hitReadLimit() bool { return cr.remain <= 0 }
|
|
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
// may be called from multiple goroutines.
|
|
|
|
|
func (cr *connReader) handleReadError(err error) {
|
|
|
|
|
cr.conn.cancelCtx()
|
|
|
|
|
cr.closeNotify()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// closeNotifyFromPipelinedRequest simply calls closeNotify.
|
|
|
|
|
//
|
|
|
|
|
// This method wrapper is here for documentation. The callers are the
|
|
|
|
|
// cases where we send on the closenotify channel because of a
|
|
|
|
|
// pipelined HTTP request, per the previous Go behavior and
|
|
|
|
|
// documentation (that this "MAY" happen).
|
|
|
|
|
//
|
|
|
|
|
// TODO: consider changing this behavior and making context
|
|
|
|
|
// cancelation and closenotify work the same.
|
|
|
|
|
func (cr *connReader) closeNotifyFromPipelinedRequest() {
|
|
|
|
|
cr.closeNotify()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// may be called from multiple goroutines.
|
|
|
|
|
func (cr *connReader) closeNotify() {
|
|
|
|
|
res, _ := cr.conn.curReq.Load().(*response)
|
|
|
|
|
if res != nil {
|
|
|
|
|
if atomic.CompareAndSwapInt32(&res.didCloseNotify, 0, 1) {
|
|
|
|
|
res.closeNotifyCh <- true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
func (cr *connReader) Read(p []byte) (n int, err error) {
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.lock()
|
|
|
|
|
if cr.inRead {
|
|
|
|
|
cr.unlock()
|
|
|
|
|
panic("invalid concurrent Body.Read call")
|
|
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
if cr.hitReadLimit() {
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.unlock()
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
return 0, io.EOF
|
|
|
|
|
}
|
2016-10-14 11:45:59 +01:00
|
|
|
if cr.bgErr != nil {
|
|
|
|
|
err = cr.bgErr
|
|
|
|
|
cr.unlock()
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
if len(p) == 0 {
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.unlock()
|
|
|
|
|
return 0, nil
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
}
|
|
|
|
|
if int64(len(p)) > cr.remain {
|
|
|
|
|
p = p[:cr.remain]
|
|
|
|
|
}
|
2016-10-14 11:45:59 +01:00
|
|
|
if cr.hasByte {
|
|
|
|
|
p[0] = cr.byteBuf[0]
|
|
|
|
|
cr.hasByte = false
|
|
|
|
|
cr.unlock()
|
|
|
|
|
return 1, nil
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
}
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.inRead = true
|
|
|
|
|
cr.unlock()
|
|
|
|
|
n, err = cr.conn.rwc.Read(p)
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.lock()
|
|
|
|
|
cr.inRead = false
|
|
|
|
|
if err != nil {
|
|
|
|
|
cr.handleReadError(err)
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
}
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.remain -= int64(n)
|
|
|
|
|
cr.unlock()
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
cr.cond.Broadcast()
|
|
|
|
|
return n, err
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2013-03-21 20:02:01 -07:00
|
|
|
var (
|
2013-12-18 15:52:20 -08:00
|
|
|
bufioReaderPool sync.Pool
|
|
|
|
|
bufioWriter2kPool sync.Pool
|
|
|
|
|
bufioWriter4kPool sync.Pool
|
2013-03-21 20:02:01 -07:00
|
|
|
)
|
|
|
|
|
|
2015-09-03 01:19:51 +03:00
|
|
|
var copyBufPool = sync.Pool{
|
|
|
|
|
New: func() interface{} {
|
|
|
|
|
b := make([]byte, 32*1024)
|
|
|
|
|
return &b
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-18 15:52:20 -08:00
|
|
|
func bufioWriterPool(size int) *sync.Pool {
|
2013-03-27 13:35:49 -07:00
|
|
|
switch size {
|
|
|
|
|
case 2 << 10:
|
2013-12-18 15:52:20 -08:00
|
|
|
return &bufioWriter2kPool
|
2013-03-27 13:35:49 -07:00
|
|
|
case 4 << 10:
|
2013-12-18 15:52:20 -08:00
|
|
|
return &bufioWriter4kPool
|
2013-03-27 13:35:49 -07:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-10 19:22:44 -07:00
|
|
|
func newBufioReader(r io.Reader) *bufio.Reader {
|
2013-12-18 15:52:20 -08:00
|
|
|
if v := bufioReaderPool.Get(); v != nil {
|
|
|
|
|
br := v.(*bufio.Reader)
|
|
|
|
|
br.Reset(r)
|
|
|
|
|
return br
|
2013-03-21 20:02:01 -07:00
|
|
|
}
|
2016-10-09 21:03:00 -07:00
|
|
|
// Note: if this reader size is ever changed, update
|
2015-06-24 11:53:24 +02:00
|
|
|
// TestHandlerBodyClose's assumptions.
|
2013-12-18 15:52:20 -08:00
|
|
|
return bufio.NewReader(r)
|
2013-03-21 20:02:01 -07:00
|
|
|
}
|
|
|
|
|
|
2013-08-10 19:22:44 -07:00
|
|
|
func putBufioReader(br *bufio.Reader) {
|
|
|
|
|
br.Reset(nil)
|
2013-12-18 15:52:20 -08:00
|
|
|
bufioReaderPool.Put(br)
|
2013-03-21 20:02:01 -07:00
|
|
|
}
|
|
|
|
|
|
2013-08-10 19:22:44 -07:00
|
|
|
func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {
|
2013-12-18 15:52:20 -08:00
|
|
|
pool := bufioWriterPool(size)
|
|
|
|
|
if pool != nil {
|
|
|
|
|
if v := pool.Get(); v != nil {
|
|
|
|
|
bw := v.(*bufio.Writer)
|
|
|
|
|
bw.Reset(w)
|
|
|
|
|
return bw
|
|
|
|
|
}
|
2013-03-21 20:02:01 -07:00
|
|
|
}
|
2013-12-18 15:52:20 -08:00
|
|
|
return bufio.NewWriterSize(w, size)
|
2013-03-21 20:02:01 -07:00
|
|
|
}
|
|
|
|
|
|
2013-08-10 19:22:44 -07:00
|
|
|
func putBufioWriter(bw *bufio.Writer) {
|
|
|
|
|
bw.Reset(nil)
|
2013-12-18 15:52:20 -08:00
|
|
|
if pool := bufioWriterPool(bw.Available()); pool != nil {
|
|
|
|
|
pool.Put(bw)
|
2013-03-21 20:02:01 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-09 10:55:14 -07:00
|
|
|
// DefaultMaxHeaderBytes is the maximum permitted size of the headers
|
|
|
|
|
// in an HTTP request.
|
|
|
|
|
// This can be overridden by setting Server.MaxHeaderBytes.
|
|
|
|
|
const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
|
|
|
|
|
|
|
|
|
|
func (srv *Server) maxHeaderBytes() int {
|
|
|
|
|
if srv.MaxHeaderBytes > 0 {
|
|
|
|
|
return srv.MaxHeaderBytes
|
|
|
|
|
}
|
|
|
|
|
return DefaultMaxHeaderBytes
|
|
|
|
|
}
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
func (srv *Server) initialReadLimitSize() int64 {
|
2014-03-03 18:58:28 -08:00
|
|
|
return int64(srv.maxHeaderBytes()) + 4096 // bufio slop
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-17 00:50:41 +09:00
|
|
|
// wrapper around io.ReadCloser which on first read, sends an
|
2010-06-16 10:15:39 -07:00
|
|
|
// HTTP/1.1 100 Continue header
|
|
|
|
|
type expectContinueReader struct {
|
2010-09-29 14:30:12 +10:00
|
|
|
resp *response
|
2010-06-16 10:15:39 -07:00
|
|
|
readCloser io.ReadCloser
|
2011-04-14 10:40:23 -07:00
|
|
|
closed bool
|
2015-07-05 09:15:11 -07:00
|
|
|
sawEOF bool
|
2010-06-16 10:15:39 -07:00
|
|
|
}
|
|
|
|
|
|
2011-11-01 22:04:37 -04:00
|
|
|
func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
|
2011-04-14 10:40:23 -07:00
|
|
|
if ecr.closed {
|
2012-12-10 01:42:10 -05:00
|
|
|
return 0, ErrBodyReadAfterClose
|
2011-04-14 10:40:23 -07:00
|
|
|
}
|
2012-12-05 19:25:43 -08:00
|
|
|
if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked() {
|
2010-09-29 14:30:12 +10:00
|
|
|
ecr.resp.wroteContinue = true
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
ecr.resp.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
|
|
|
|
|
ecr.resp.conn.bufw.Flush()
|
2010-06-16 10:15:39 -07:00
|
|
|
}
|
2015-07-05 09:15:11 -07:00
|
|
|
n, err = ecr.readCloser.Read(p)
|
|
|
|
|
if err == io.EOF {
|
|
|
|
|
ecr.sawEOF = true
|
|
|
|
|
}
|
|
|
|
|
return
|
2010-06-16 10:15:39 -07:00
|
|
|
}
|
|
|
|
|
|
2011-11-01 22:04:37 -04:00
|
|
|
func (ecr *expectContinueReader) Close() error {
|
2011-04-14 10:40:23 -07:00
|
|
|
ecr.closed = true
|
2010-06-16 10:15:39 -07:00
|
|
|
return ecr.readCloser.Close()
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-26 18:55:35 +00:00
|
|
|
// TimeFormat is the time format to use when generating times in HTTP
|
|
|
|
|
// headers. It is like time.RFC1123 but hard-codes GMT as the time
|
|
|
|
|
// zone. The time being formatted must be in UTC for Format to
|
|
|
|
|
// generate the correct format.
|
|
|
|
|
//
|
|
|
|
|
// For parsing this time format, see ParseTime.
|
2010-09-02 14:21:11 -04:00
|
|
|
const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
|
|
|
|
|
|
2013-09-22 19:53:55 -07:00
|
|
|
// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))
|
2013-05-19 20:15:40 -07:00
|
|
|
func appendTime(b []byte, t time.Time) []byte {
|
|
|
|
|
const days = "SunMonTueWedThuFriSat"
|
|
|
|
|
const months = "JanFebMarAprMayJunJulAugSepOctNovDec"
|
|
|
|
|
|
2013-09-22 19:53:55 -07:00
|
|
|
t = t.UTC()
|
2013-05-19 20:15:40 -07:00
|
|
|
yy, mm, dd := t.Date()
|
|
|
|
|
hh, mn, ss := t.Clock()
|
|
|
|
|
day := days[3*t.Weekday():]
|
|
|
|
|
mon := months[3*(mm-1):]
|
|
|
|
|
|
|
|
|
|
return append(b,
|
|
|
|
|
day[0], day[1], day[2], ',', ' ',
|
|
|
|
|
byte('0'+dd/10), byte('0'+dd%10), ' ',
|
|
|
|
|
mon[0], mon[1], mon[2], ' ',
|
|
|
|
|
byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
|
|
|
|
|
byte('0'+hh/10), byte('0'+hh%10), ':',
|
|
|
|
|
byte('0'+mn/10), byte('0'+mn%10), ':',
|
|
|
|
|
byte('0'+ss/10), byte('0'+ss%10), ' ',
|
|
|
|
|
'G', 'M', 'T')
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-01 22:04:37 -04:00
|
|
|
var errTooLarge = errors.New("http: request too large")
|
2011-08-09 10:55:14 -07:00
|
|
|
|
2009-02-02 18:01:32 -08:00
|
|
|
// Read next request from connection.
|
2016-04-06 12:31:55 -07:00
|
|
|
func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
|
2012-12-05 19:25:43 -08:00
|
|
|
if c.hijacked() {
|
2009-11-09 12:07:39 -08:00
|
|
|
return nil, ErrHijacked
|
2009-02-03 14:16:22 -08:00
|
|
|
}
|
2013-02-04 13:52:45 -08:00
|
|
|
|
2016-10-23 06:04:14 -07:00
|
|
|
var (
|
|
|
|
|
wholeReqDeadline time.Time // or zero if none
|
|
|
|
|
hdrDeadline time.Time // or zero if none
|
|
|
|
|
)
|
|
|
|
|
t0 := time.Now()
|
|
|
|
|
if d := c.server.readHeaderTimeout(); d != 0 {
|
|
|
|
|
hdrDeadline = t0.Add(d)
|
|
|
|
|
}
|
2013-02-04 13:52:45 -08:00
|
|
|
if d := c.server.ReadTimeout; d != 0 {
|
2016-10-23 06:04:14 -07:00
|
|
|
wholeReqDeadline = t0.Add(d)
|
2013-02-04 13:52:45 -08:00
|
|
|
}
|
2016-10-23 06:04:14 -07:00
|
|
|
c.rwc.SetReadDeadline(hdrDeadline)
|
2013-02-04 13:52:45 -08:00
|
|
|
if d := c.server.WriteTimeout; d != 0 {
|
|
|
|
|
defer func() {
|
|
|
|
|
c.rwc.SetWriteDeadline(time.Now().Add(d))
|
|
|
|
|
}()
|
|
|
|
|
}
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
c.r.setReadLimit(c.server.initialReadLimitSize())
|
2015-06-25 11:31:37 +02:00
|
|
|
if c.lastMethod == "POST" {
|
|
|
|
|
// RFC 2616 section 4.1 tolerance for old buggy clients.
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
peek, _ := c.bufr.Peek(4) // ReadRequest will get err below
|
|
|
|
|
c.bufr.Discard(numLeadingCRorLF(peek))
|
2015-06-25 11:31:37 +02:00
|
|
|
}
|
2016-01-04 20:38:20 +00:00
|
|
|
req, err := readRequest(c.bufr, keepHostHeader)
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
if err != nil {
|
|
|
|
|
if c.r.hitReadLimit() {
|
2011-08-09 10:55:14 -07:00
|
|
|
return nil, errTooLarge
|
|
|
|
|
}
|
2009-11-09 12:07:39 -08:00
|
|
|
return nil, err
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2016-04-06 12:31:55 -07:00
|
|
|
|
2016-06-27 10:28:08 -07:00
|
|
|
if !http1ServerSupportsRequest(req) {
|
|
|
|
|
return nil, badRequestError("unsupported protocol version")
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-25 11:31:37 +02:00
|
|
|
c.lastMethod = req.Method
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
c.r.setInfiniteReadLimit()
|
2009-02-02 18:01:32 -08:00
|
|
|
|
2015-12-16 18:51:12 +00:00
|
|
|
hosts, haveHost := req.Header["Host"]
|
2016-03-30 22:11:41 -07:00
|
|
|
isH2Upgrade := req.isH2Upgrade()
|
|
|
|
|
if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade {
|
2015-12-16 18:51:12 +00:00
|
|
|
return nil, badRequestError("missing required Host header")
|
|
|
|
|
}
|
|
|
|
|
if len(hosts) > 1 {
|
|
|
|
|
return nil, badRequestError("too many Host headers")
|
|
|
|
|
}
|
2016-05-19 02:13:36 +00:00
|
|
|
if len(hosts) == 1 && !httplex.ValidHostHeader(hosts[0]) {
|
2015-12-16 18:51:12 +00:00
|
|
|
return nil, badRequestError("malformed Host header")
|
|
|
|
|
}
|
2015-12-17 19:25:51 +00:00
|
|
|
for k, vv := range req.Header {
|
2016-05-19 02:13:36 +00:00
|
|
|
if !httplex.ValidHeaderFieldName(k) {
|
2015-12-17 19:25:51 +00:00
|
|
|
return nil, badRequestError("invalid header name")
|
|
|
|
|
}
|
|
|
|
|
for _, v := range vv {
|
2016-05-19 02:13:36 +00:00
|
|
|
if !httplex.ValidHeaderFieldValue(v) {
|
2015-12-17 19:25:51 +00:00
|
|
|
return nil, badRequestError("invalid header value")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-16 18:51:12 +00:00
|
|
|
delete(req.Header, "Host")
|
|
|
|
|
|
2016-07-09 17:24:45 -07:00
|
|
|
ctx, cancelCtx := context.WithCancel(ctx)
|
|
|
|
|
req.ctx = ctx
|
2011-03-10 08:17:22 -08:00
|
|
|
req.RemoteAddr = c.remoteAddr
|
|
|
|
|
req.TLS = c.tlsState
|
2015-06-24 11:53:24 +02:00
|
|
|
if body, ok := req.Body.(*body); ok {
|
|
|
|
|
body.doEarlyClose = true
|
|
|
|
|
}
|
2011-03-10 08:17:22 -08:00
|
|
|
|
2016-10-23 06:04:14 -07:00
|
|
|
// Adjust the read deadline if necessary.
|
|
|
|
|
if !hdrDeadline.Equal(wholeReqDeadline) {
|
|
|
|
|
c.rwc.SetReadDeadline(wholeReqDeadline)
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-11 10:03:43 -08:00
|
|
|
w = &response{
|
|
|
|
|
conn: c,
|
2016-04-06 12:31:55 -07:00
|
|
|
cancelCtx: cancelCtx,
|
2013-01-11 10:03:43 -08:00
|
|
|
req: req,
|
2015-11-03 12:04:20 -08:00
|
|
|
reqBody: req.Body,
|
2013-01-11 10:03:43 -08:00
|
|
|
handlerHeader: make(Header),
|
|
|
|
|
contentLength: -1,
|
2016-10-14 11:45:59 +01:00
|
|
|
closeNotifyCh: make(chan bool, 1),
|
2016-04-05 15:59:55 +00:00
|
|
|
|
|
|
|
|
// We populate these ahead of time so we're not
|
|
|
|
|
// reading from req.Header after their Handler starts
|
|
|
|
|
// and maybe mutates it (Issue 14940)
|
|
|
|
|
wants10KeepAlive: req.wantsHttp10KeepAlive(),
|
|
|
|
|
wantsClose: req.wantsClose(),
|
2013-01-11 10:03:43 -08:00
|
|
|
}
|
2016-03-30 22:11:41 -07:00
|
|
|
if isH2Upgrade {
|
|
|
|
|
w.closeAfterReply = true
|
|
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
w.cw.res = w
|
2013-08-10 19:22:44 -07:00
|
|
|
w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
|
2010-09-29 14:30:12 +10:00
|
|
|
return w, nil
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2016-06-27 10:28:08 -07:00
|
|
|
// http1ServerSupportsRequest reports whether Go's HTTP/1.x server
|
|
|
|
|
// supports the given request.
|
|
|
|
|
func http1ServerSupportsRequest(req *Request) bool {
|
|
|
|
|
if req.ProtoMajor == 1 {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
// Accept "PRI * HTTP/2.0" upgrade requests, so Handlers can
|
|
|
|
|
// wire up their own HTTP/2 upgrades.
|
|
|
|
|
if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&
|
|
|
|
|
req.Method == "PRI" && req.RequestURI == "*" {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
// Reject HTTP/0.x, and all other HTTP/2+ requests (which
|
|
|
|
|
// aren't encoded in ASCII anyway).
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-09 09:41:01 -08:00
|
|
|
func (w *response) Header() Header {
|
2013-03-28 11:35:24 -07:00
|
|
|
if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
|
|
|
|
|
// Accessing the header between logically writing it
|
|
|
|
|
// and physically writing it means we need to allocate
|
|
|
|
|
// a clone to snapshot the logically written state.
|
|
|
|
|
w.cw.header = w.handlerHeader.clone()
|
|
|
|
|
}
|
|
|
|
|
w.calledHeader = true
|
2013-01-11 10:03:43 -08:00
|
|
|
return w.handlerHeader
|
2011-03-03 12:22:13 -08:00
|
|
|
}
|
2010-09-29 14:30:12 +10:00
|
|
|
|
2011-10-14 17:34:07 -07:00
|
|
|
// maxPostHandlerReadBytes is the max number of Request.Body bytes not
|
2011-12-10 13:02:23 +11:00
|
|
|
// consumed by a handler that the server will read from the client
|
2016-03-01 23:21:55 +00:00
|
|
|
// in order to keep a connection alive. If there are more bytes than
|
2011-10-14 17:34:07 -07:00
|
|
|
// this then the server to be paranoid instead sends a "Connection:
|
|
|
|
|
// close" response.
|
|
|
|
|
//
|
|
|
|
|
// This number is approximately what a typical machine's TCP buffer
|
|
|
|
|
// size is anyway. (if we have the bytes on the machine, we might as
|
|
|
|
|
// well read them)
|
|
|
|
|
const maxPostHandlerReadBytes = 256 << 10
|
|
|
|
|
|
2010-09-29 14:30:12 +10:00
|
|
|
func (w *response) WriteHeader(code int) {
|
2012-12-05 19:25:43 -08:00
|
|
|
if w.conn.hijacked() {
|
2014-02-28 12:12:51 -08:00
|
|
|
w.conn.server.logf("http: response.WriteHeader on hijacked connection")
|
2009-12-15 15:35:38 -08:00
|
|
|
return
|
2009-02-03 14:16:22 -08:00
|
|
|
}
|
2010-09-29 14:30:12 +10:00
|
|
|
if w.wroteHeader {
|
2014-02-28 12:12:51 -08:00
|
|
|
w.conn.server.logf("http: multiple response.WriteHeader calls")
|
2009-12-15 15:35:38 -08:00
|
|
|
return
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2011-10-14 17:34:07 -07:00
|
|
|
w.wroteHeader = true
|
|
|
|
|
w.status = code
|
|
|
|
|
|
2013-03-28 11:35:24 -07:00
|
|
|
if w.calledHeader && w.cw.header == nil {
|
|
|
|
|
w.cw.header = w.handlerHeader.clone()
|
|
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
|
2013-03-28 11:35:24 -07:00
|
|
|
if cl := w.handlerHeader.get("Content-Length"); cl != "" {
|
2013-01-11 10:03:43 -08:00
|
|
|
v, err := strconv.ParseInt(cl, 10, 64)
|
|
|
|
|
if err == nil && v >= 0 {
|
|
|
|
|
w.contentLength = v
|
2011-10-14 17:34:07 -07:00
|
|
|
} else {
|
2014-02-28 12:12:51 -08:00
|
|
|
w.conn.server.logf("http: invalid Content-Length of %q", cl)
|
2013-03-28 11:35:24 -07:00
|
|
|
w.handlerHeader.Del("Content-Length")
|
2013-01-11 10:03:43 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-02 16:27:23 -07:00
|
|
|
// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.
|
|
|
|
|
// This type is used to avoid extra allocations from cloning and/or populating
|
|
|
|
|
// the response Header map and all its 1-element slices.
|
|
|
|
|
type extraHeader struct {
|
|
|
|
|
contentType string
|
|
|
|
|
connection string
|
|
|
|
|
transferEncoding string
|
2013-05-19 20:15:40 -07:00
|
|
|
date []byte // written if not nil
|
|
|
|
|
contentLength []byte // written if not nil
|
2013-04-02 16:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sorted the same as extraHeader.Write's loop.
|
|
|
|
|
var extraHeaderKeys = [][]byte{
|
2013-05-19 20:15:40 -07:00
|
|
|
[]byte("Content-Type"),
|
|
|
|
|
[]byte("Connection"),
|
|
|
|
|
[]byte("Transfer-Encoding"),
|
2013-04-02 16:27:23 -07:00
|
|
|
}
|
|
|
|
|
|
2013-05-19 20:15:40 -07:00
|
|
|
var (
|
|
|
|
|
headerContentLength = []byte("Content-Length: ")
|
|
|
|
|
headerDate = []byte("Date: ")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Write writes the headers described in h to w.
|
|
|
|
|
//
|
|
|
|
|
// This method has a value receiver, despite the somewhat large size
|
|
|
|
|
// of h, because it prevents an allocation. The escape analysis isn't
|
|
|
|
|
// smart enough to realize this function doesn't mutate h.
|
|
|
|
|
func (h extraHeader) Write(w *bufio.Writer) {
|
|
|
|
|
if h.date != nil {
|
|
|
|
|
w.Write(headerDate)
|
|
|
|
|
w.Write(h.date)
|
|
|
|
|
w.Write(crlf)
|
|
|
|
|
}
|
|
|
|
|
if h.contentLength != nil {
|
|
|
|
|
w.Write(headerContentLength)
|
|
|
|
|
w.Write(h.contentLength)
|
|
|
|
|
w.Write(crlf)
|
|
|
|
|
}
|
|
|
|
|
for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
|
2013-04-02 16:27:23 -07:00
|
|
|
if v != "" {
|
|
|
|
|
w.Write(extraHeaderKeys[i])
|
|
|
|
|
w.Write(colonSpace)
|
2013-05-19 20:15:40 -07:00
|
|
|
w.WriteString(v)
|
2013-04-02 16:27:23 -07:00
|
|
|
w.Write(crlf)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-11 10:03:43 -08:00
|
|
|
// writeHeader finalizes the header sent to the client and writes it
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
// to cw.res.conn.bufw.
|
2013-01-11 10:03:43 -08:00
|
|
|
//
|
|
|
|
|
// p is not written by writeHeader, but is the first chunk of the body
|
2016-03-01 23:21:55 +00:00
|
|
|
// that will be written. It is sniffed for a Content-Type if none is
|
|
|
|
|
// set explicitly. It's also used to set the Content-Length, if the
|
2013-01-11 10:03:43 -08:00
|
|
|
// total body size was small and the handler has already finished
|
|
|
|
|
// running.
|
|
|
|
|
func (cw *chunkWriter) writeHeader(p []byte) {
|
|
|
|
|
if cw.wroteHeader {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
cw.wroteHeader = true
|
|
|
|
|
|
|
|
|
|
w := cw.res
|
2014-02-28 07:40:25 -08:00
|
|
|
keepAlivesEnabled := w.conn.server.doKeepAlives()
|
net/http: treat HEAD requests like GET requests
A response to a HEAD request is supposed to look the same as a
response to a GET request, just without a body.
HEAD requests are incredibly rare in the wild.
The Go net/http package has so far treated HEAD requests
specially: a Write on our default ResponseWriter returned
ErrBodyNotAllowed, telling handlers that something was wrong.
This was to optimize the fast path for HEAD requests, but:
1) because HEAD requests are incredibly rare, they're not
worth having a fast path for.
2) Letting the http.Handler handle but do nop Writes is still
very fast.
3) this forces ugly error handling into the application.
e.g. https://code.google.com/p/go/source/detail?r=6f596be7a31e
and related.
4) The net/http package nowadays does Content-Type sniffing,
but you don't get that for HEAD.
5) The net/http package nowadays does Content-Length counting
for small (few KB) responses, but not for HEAD.
6) ErrBodyNotAllowed was useless. By the time you received it,
you had probably already done all your heavy computation
and I/O to calculate what to write.
So, this change makes HEAD requests like GET requests.
We now count content-length and sniff content-type for HEAD
requests. If you Write, it doesn't return an error.
If you want a fast-path in your code for HEAD, you have to do
it early and set all the response headers yourself. Just like
before. If you choose not to Write in HEAD requests, be sure
to set Content-Length if you know it. We won't write
"Content-Length: 0" because you might've just chosen to not
write (or you don't know your Content-Length in advance).
Fixes #5454
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/12583043
2013-08-06 18:33:03 -07:00
|
|
|
isHEAD := w.req.Method == "HEAD"
|
2013-03-28 11:35:24 -07:00
|
|
|
|
2013-04-02 16:27:23 -07:00
|
|
|
// header is written out to w.conn.buf below. Depending on the
|
|
|
|
|
// state of the handler, we either own the map or not. If we
|
|
|
|
|
// don't own it, the exclude map is created lazily for
|
|
|
|
|
// WriteSubset to remove headers. The setHeader struct holds
|
|
|
|
|
// headers we need to add.
|
|
|
|
|
header := cw.header
|
|
|
|
|
owned := header != nil
|
|
|
|
|
if !owned {
|
|
|
|
|
header = w.handlerHeader
|
|
|
|
|
}
|
|
|
|
|
var excludeHeader map[string]bool
|
|
|
|
|
delHeader := func(key string) {
|
|
|
|
|
if owned {
|
|
|
|
|
header.Del(key)
|
|
|
|
|
return
|
2013-03-28 11:35:24 -07:00
|
|
|
}
|
2013-04-02 16:27:23 -07:00
|
|
|
if _, ok := header[key]; !ok {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if excludeHeader == nil {
|
|
|
|
|
excludeHeader = make(map[string]bool)
|
|
|
|
|
}
|
|
|
|
|
excludeHeader[key] = true
|
2013-03-28 11:35:24 -07:00
|
|
|
}
|
2013-04-02 16:27:23 -07:00
|
|
|
var setHeader extraHeader
|
2013-01-11 10:03:43 -08:00
|
|
|
|
2016-11-01 15:24:11 +00:00
|
|
|
// Don't write out the fake "Trailer:foo" keys. See TrailerPrefix.
|
2014-12-29 19:32:07 -08:00
|
|
|
trailers := false
|
2016-11-01 15:24:11 +00:00
|
|
|
for k := range cw.header {
|
|
|
|
|
if strings.HasPrefix(k, TrailerPrefix) {
|
|
|
|
|
if excludeHeader == nil {
|
|
|
|
|
excludeHeader = make(map[string]bool)
|
|
|
|
|
}
|
|
|
|
|
excludeHeader[k] = true
|
|
|
|
|
trailers = true
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-29 19:32:07 -08:00
|
|
|
for _, v := range cw.header["Trailer"] {
|
|
|
|
|
trailers = true
|
|
|
|
|
foreachHeaderElement(v, cw.res.declareTrailer)
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-01 07:02:36 -07:00
|
|
|
te := header.get("Transfer-Encoding")
|
|
|
|
|
hasTE := te != ""
|
|
|
|
|
|
2013-01-11 10:03:43 -08:00
|
|
|
// If the handler is done but never sent a Content-Length
|
|
|
|
|
// response header and this is our first (and last) write, set
|
|
|
|
|
// it, even to zero. This helps HTTP/1.0 clients keep their
|
|
|
|
|
// "keep-alive" connections alive.
|
2014-01-16 11:43:52 -08:00
|
|
|
// Exceptions: 304/204/1xx responses never get Content-Length, and if
|
2013-08-15 17:40:05 -07:00
|
|
|
// it was a HEAD request, we don't know the difference between
|
|
|
|
|
// 0 actual bytes and 0 bytes because the handler noticed it
|
2016-03-01 23:21:55 +00:00
|
|
|
// was a HEAD request and chose not to write anything. So for
|
2013-08-15 17:40:05 -07:00
|
|
|
// HEAD, the handler should either write the Content-Length or
|
2016-03-01 23:21:55 +00:00
|
|
|
// write non-zero bytes. If it's actually 0 bytes and the
|
2013-08-15 17:40:05 -07:00
|
|
|
// handler never looked at the Request.Method, we just don't
|
|
|
|
|
// send a Content-Length header.
|
2015-05-01 07:02:36 -07:00
|
|
|
// Further, we don't send an automatic Content-Length if they
|
|
|
|
|
// set a Transfer-Encoding, because they're generally incompatible.
|
2016-01-18 11:43:32 -08:00
|
|
|
if w.handlerDone.isSet() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
|
2013-01-11 10:03:43 -08:00
|
|
|
w.contentLength = int64(len(p))
|
2013-05-19 20:15:40 -07:00
|
|
|
setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
|
2013-01-11 10:03:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If this was an HTTP/1.0 request with keep-alive and we sent a
|
|
|
|
|
// Content-Length back, we can make this a keep-alive response ...
|
2016-04-05 15:59:55 +00:00
|
|
|
if w.wants10KeepAlive && keepAlivesEnabled {
|
2013-04-02 16:27:23 -07:00
|
|
|
sentLength := header.get("Content-Length") != ""
|
|
|
|
|
if sentLength && header.get("Connection") == "keep-alive" {
|
2013-01-11 10:03:43 -08:00
|
|
|
w.closeAfterReply = false
|
2011-10-14 17:34:07 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-11 10:03:43 -08:00
|
|
|
// Check for a explicit (and valid) Content-Length header.
|
|
|
|
|
hasCL := w.contentLength != -1
|
|
|
|
|
|
2016-05-11 15:01:28 -07:00
|
|
|
if w.wants10KeepAlive && (isHEAD || hasCL || !bodyAllowedForStatus(w.status)) {
|
2013-04-02 16:27:23 -07:00
|
|
|
_, connectionHeaderSet := header["Connection"]
|
2011-10-14 17:34:07 -07:00
|
|
|
if !connectionHeaderSet {
|
2013-04-02 16:27:23 -07:00
|
|
|
setHeader.connection = "keep-alive"
|
2011-10-14 17:34:07 -07:00
|
|
|
}
|
2016-04-05 15:59:55 +00:00
|
|
|
} else if !w.req.ProtoAtLeast(1, 1) || w.wantsClose {
|
2011-10-14 17:34:07 -07:00
|
|
|
w.closeAfterReply = true
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-28 07:40:25 -08:00
|
|
|
if header.get("Connection") == "close" || !keepAlivesEnabled {
|
2011-10-14 17:34:07 -07:00
|
|
|
w.closeAfterReply = true
|
|
|
|
|
}
|
2011-04-14 10:40:23 -07:00
|
|
|
|
2015-07-05 09:15:11 -07:00
|
|
|
// 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
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-14 10:40:23 -07:00
|
|
|
// Per RFC 2616, we should consume the request body before
|
2016-03-01 23:21:55 +00:00
|
|
|
// replying, if the handler hasn't already done so. But we
|
2011-10-14 17:34:07 -07:00
|
|
|
// don't want to do an unbounded amount of reading here for
|
|
|
|
|
// DoS reasons, so we only try up to a threshold.
|
2016-05-10 16:09:16 -07:00
|
|
|
// 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?
|
2011-10-14 17:34:07 -07:00
|
|
|
if w.req.ContentLength != 0 && !w.closeAfterReply {
|
2015-07-29 18:10:32 -07:00
|
|
|
var discard, tooBig bool
|
|
|
|
|
|
|
|
|
|
switch bdy := w.req.Body.(type) {
|
|
|
|
|
case *expectContinueReader:
|
|
|
|
|
if bdy.resp.wroteContinue {
|
|
|
|
|
discard = true
|
|
|
|
|
}
|
|
|
|
|
case *body:
|
2015-08-03 10:04:42 +02:00
|
|
|
bdy.mu.Lock()
|
2015-07-29 18:10:32 -07:00
|
|
|
switch {
|
|
|
|
|
case bdy.closed:
|
|
|
|
|
if !bdy.sawEOF {
|
|
|
|
|
// Body was closed in handler with non-EOF error.
|
|
|
|
|
w.closeAfterReply = true
|
|
|
|
|
}
|
2015-08-03 10:04:42 +02:00
|
|
|
case bdy.unreadDataSizeLocked() >= maxPostHandlerReadBytes:
|
2015-07-24 14:22:26 -07:00
|
|
|
tooBig = true
|
2015-07-29 18:10:32 -07:00
|
|
|
default:
|
|
|
|
|
discard = true
|
2015-07-24 14:22:26 -07:00
|
|
|
}
|
2015-08-03 10:04:42 +02:00
|
|
|
bdy.mu.Unlock()
|
2015-07-29 18:10:32 -07:00
|
|
|
default:
|
|
|
|
|
discard = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if discard {
|
2016-01-04 20:38:20 +00:00
|
|
|
_, err := io.CopyN(ioutil.Discard, w.reqBody, maxPostHandlerReadBytes+1)
|
2015-07-29 18:10:32 -07:00
|
|
|
switch err {
|
|
|
|
|
case nil:
|
|
|
|
|
// There must be even more data left over.
|
|
|
|
|
tooBig = true
|
|
|
|
|
case ErrBodyReadAfterClose:
|
|
|
|
|
// Body was already consumed and closed.
|
|
|
|
|
case io.EOF:
|
|
|
|
|
// The remaining body was just consumed, close it.
|
2016-01-04 20:38:20 +00:00
|
|
|
err = w.reqBody.Close()
|
2015-07-29 18:10:32 -07:00
|
|
|
if err != nil {
|
|
|
|
|
w.closeAfterReply = true
|
|
|
|
|
}
|
|
|
|
|
default:
|
2016-02-06 20:35:29 +09:00
|
|
|
// Some other kind of error occurred, like a read timeout, or
|
2015-07-29 18:10:32 -07:00
|
|
|
// corrupt chunked encoding. In any case, whatever remains
|
|
|
|
|
// on the wire must not be parsed as another HTTP request.
|
|
|
|
|
w.closeAfterReply = true
|
2011-10-14 17:34:07 -07:00
|
|
|
}
|
2011-04-14 10:40:23 -07:00
|
|
|
}
|
2015-07-29 18:10:32 -07:00
|
|
|
|
|
|
|
|
if tooBig {
|
|
|
|
|
w.requestTooLarge()
|
|
|
|
|
delHeader("Connection")
|
|
|
|
|
setHeader.connection = "close"
|
|
|
|
|
}
|
2011-04-14 10:40:23 -07:00
|
|
|
}
|
|
|
|
|
|
2013-03-28 11:35:24 -07:00
|
|
|
code := w.status
|
2014-05-16 15:39:59 -07:00
|
|
|
if bodyAllowedForStatus(code) {
|
2011-07-15 01:01:49 -04:00
|
|
|
// If no content type, apply sniffing algorithm to body.
|
2013-07-31 23:38:32 -07:00
|
|
|
_, haveType := header["Content-Type"]
|
2015-05-01 07:02:36 -07:00
|
|
|
if !haveType && !hasTE {
|
2013-04-02 16:27:23 -07:00
|
|
|
setHeader.contentType = DetectContentType(p)
|
2011-03-03 12:22:13 -08:00
|
|
|
}
|
2014-05-16 15:39:59 -07:00
|
|
|
} else {
|
|
|
|
|
for _, k := range suppressedHeaders(code) {
|
|
|
|
|
delHeader(k)
|
|
|
|
|
}
|
2011-03-03 12:22:13 -08:00
|
|
|
}
|
|
|
|
|
|
2013-04-02 16:27:23 -07:00
|
|
|
if _, ok := header["Date"]; !ok {
|
2013-05-19 20:15:40 -07:00
|
|
|
setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
|
2011-03-03 12:22:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if hasCL && hasTE && te != "identity" {
|
|
|
|
|
// TODO: return an error if WriteHeader gets a return parameter
|
|
|
|
|
// For now just ignore the Content-Length.
|
2014-02-28 12:12:51 -08:00
|
|
|
w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
|
2013-01-11 10:03:43 -08:00
|
|
|
te, w.contentLength)
|
2013-04-02 16:27:23 -07:00
|
|
|
delHeader("Content-Length")
|
2011-03-03 12:22:13 -08:00
|
|
|
hasCL = false
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-16 11:43:52 -08:00
|
|
|
if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) {
|
2011-03-03 12:22:13 -08:00
|
|
|
// do nothing
|
2012-11-29 18:00:51 -08:00
|
|
|
} else if code == StatusNoContent {
|
2013-04-02 16:27:23 -07:00
|
|
|
delHeader("Transfer-Encoding")
|
2011-03-03 12:22:13 -08:00
|
|
|
} else if hasCL {
|
2013-04-02 16:27:23 -07:00
|
|
|
delHeader("Transfer-Encoding")
|
2011-03-03 12:22:13 -08:00
|
|
|
} else if w.req.ProtoAtLeast(1, 1) {
|
2014-09-29 13:53:42 -07:00
|
|
|
// HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no
|
|
|
|
|
// content-length has been provided. The connection must be closed after the
|
|
|
|
|
// reply is written, and no chunking is to be done. This is the setup
|
|
|
|
|
// recommended in the Server-Sent Events candidate recommendation 11,
|
|
|
|
|
// section 8.
|
|
|
|
|
if hasTE && te == "identity" {
|
|
|
|
|
cw.chunking = false
|
|
|
|
|
w.closeAfterReply = true
|
|
|
|
|
} else {
|
|
|
|
|
// HTTP/1.1 or greater: use chunked transfer encoding
|
|
|
|
|
// to avoid closing the connection at EOF.
|
|
|
|
|
cw.chunking = true
|
|
|
|
|
setHeader.transferEncoding = "chunked"
|
2016-06-15 10:52:42 +10:00
|
|
|
if hasTE && te == "chunked" {
|
|
|
|
|
// We will send the chunked Transfer-Encoding header later.
|
|
|
|
|
delHeader("Transfer-Encoding")
|
|
|
|
|
}
|
2014-09-29 13:53:42 -07:00
|
|
|
}
|
2011-03-03 12:22:13 -08:00
|
|
|
} else {
|
|
|
|
|
// HTTP version < 1.1: cannot do chunked transfer
|
|
|
|
|
// encoding and we don't know the Content-Length so
|
|
|
|
|
// signal EOF by closing connection.
|
|
|
|
|
w.closeAfterReply = true
|
2013-04-02 16:27:23 -07:00
|
|
|
delHeader("Transfer-Encoding") // in case already set
|
2011-03-03 12:22:13 -08:00
|
|
|
}
|
|
|
|
|
|
2011-01-19 10:05:48 -05:00
|
|
|
// Cannot use Content-Length with non-identity Transfer-Encoding.
|
2013-01-11 10:03:43 -08:00
|
|
|
if cw.chunking {
|
2013-04-02 16:27:23 -07:00
|
|
|
delHeader("Content-Length")
|
2011-01-19 10:05:48 -05:00
|
|
|
}
|
2010-09-29 14:30:12 +10:00
|
|
|
if !w.req.ProtoAtLeast(1, 0) {
|
2009-11-09 12:07:39 -08:00
|
|
|
return
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2012-05-23 11:19:38 -07:00
|
|
|
|
2014-02-28 07:40:25 -08:00
|
|
|
if w.closeAfterReply && (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) {
|
2013-04-02 16:27:23 -07:00
|
|
|
delHeader("Connection")
|
2013-08-06 18:37:34 -07:00
|
|
|
if w.req.ProtoAtLeast(1, 1) {
|
|
|
|
|
setHeader.connection = "close"
|
|
|
|
|
}
|
2012-05-23 11:19:38 -07:00
|
|
|
}
|
|
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
w.conn.bufw.WriteString(statusLine(w.req, code))
|
|
|
|
|
cw.header.WriteSubset(w.conn.bufw, excludeHeader)
|
|
|
|
|
setHeader.Write(w.conn.bufw)
|
|
|
|
|
w.conn.bufw.Write(crlf)
|
2013-03-28 13:07:14 -07:00
|
|
|
}
|
|
|
|
|
|
2014-12-29 19:32:07 -08:00
|
|
|
// foreachHeaderElement splits v according to the "#rule" construction
|
|
|
|
|
// in RFC 2616 section 2.1 and calls fn for each non-empty element.
|
|
|
|
|
func foreachHeaderElement(v string, fn func(string)) {
|
|
|
|
|
v = textproto.TrimString(v)
|
|
|
|
|
if v == "" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if !strings.Contains(v, ",") {
|
|
|
|
|
fn(v)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
for _, f := range strings.Split(v, ",") {
|
|
|
|
|
if f = textproto.TrimString(f); f != "" {
|
|
|
|
|
fn(f)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-28 13:07:14 -07:00
|
|
|
// statusLines is a cache of Status-Line strings, keyed by code (for
|
|
|
|
|
// HTTP/1.1) or negative code (for HTTP/1.0). This is faster than a
|
|
|
|
|
// map keyed by struct of two fields. This map's max size is bounded
|
|
|
|
|
// by 2*len(statusText), two protocol types for each known official
|
|
|
|
|
// status code in the statusText map.
|
|
|
|
|
var (
|
|
|
|
|
statusMu sync.RWMutex
|
|
|
|
|
statusLines = make(map[int]string)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// statusLine returns a response Status-Line (RFC 2616 Section 6.1)
|
|
|
|
|
// for the given request and response status code.
|
|
|
|
|
func statusLine(req *Request, code int) string {
|
|
|
|
|
// Fast path:
|
|
|
|
|
key := code
|
|
|
|
|
proto11 := req.ProtoAtLeast(1, 1)
|
|
|
|
|
if !proto11 {
|
|
|
|
|
key = -key
|
|
|
|
|
}
|
|
|
|
|
statusMu.RLock()
|
|
|
|
|
line, ok := statusLines[key]
|
|
|
|
|
statusMu.RUnlock()
|
|
|
|
|
if ok {
|
|
|
|
|
return line
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Slow path:
|
2009-12-15 15:35:38 -08:00
|
|
|
proto := "HTTP/1.0"
|
2013-03-28 13:07:14 -07:00
|
|
|
if proto11 {
|
2009-11-09 12:07:39 -08:00
|
|
|
proto = "HTTP/1.1"
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2016-01-29 18:26:06 +00:00
|
|
|
codestring := fmt.Sprintf("%03d", code)
|
2009-12-15 15:35:38 -08:00
|
|
|
text, ok := statusText[code]
|
2009-02-02 18:01:32 -08:00
|
|
|
if !ok {
|
2009-11-09 12:07:39 -08:00
|
|
|
text = "status code " + codestring
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2013-03-28 13:07:14 -07:00
|
|
|
line = proto + " " + codestring + " " + text + "\r\n"
|
|
|
|
|
if ok {
|
|
|
|
|
statusMu.Lock()
|
|
|
|
|
defer statusMu.Unlock()
|
|
|
|
|
statusLines[key] = line
|
|
|
|
|
}
|
|
|
|
|
return line
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 15:44:42 -08:00
|
|
|
// bodyAllowed reports whether a Write is allowed for this response type.
|
2011-06-09 18:10:21 -07:00
|
|
|
// It's illegal to call this before the header has been flushed.
|
|
|
|
|
func (w *response) bodyAllowed() bool {
|
|
|
|
|
if !w.wroteHeader {
|
|
|
|
|
panic("")
|
|
|
|
|
}
|
2014-01-16 11:43:52 -08:00
|
|
|
return bodyAllowedForStatus(w.status)
|
2011-06-09 18:10:21 -07:00
|
|
|
}
|
|
|
|
|
|
2013-01-11 10:03:43 -08:00
|
|
|
// The Life Of A Write is like this:
|
|
|
|
|
//
|
|
|
|
|
// Handler starts. No header has been sent. The handler can either
|
2016-03-01 23:21:55 +00:00
|
|
|
// write a header, or just start writing. Writing before sending a header
|
2013-03-20 16:32:37 -07:00
|
|
|
// sends an implicitly empty 200 OK header.
|
2013-01-11 10:03:43 -08:00
|
|
|
//
|
|
|
|
|
// If the handler didn't declare a Content-Length up front, we either
|
|
|
|
|
// go into chunking mode or, if the handler finishes running before
|
|
|
|
|
// the chunking buffer size, we compute a Content-Length and send that
|
|
|
|
|
// in the header instead.
|
|
|
|
|
//
|
|
|
|
|
// Likewise, if the handler didn't set a Content-Type, we sniff that
|
|
|
|
|
// from the initial chunk of output.
|
|
|
|
|
//
|
|
|
|
|
// The Writers are wired together like:
|
|
|
|
|
//
|
|
|
|
|
// 1. *response (the ResponseWriter) ->
|
|
|
|
|
// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes
|
|
|
|
|
// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
|
|
|
|
|
// and which writes the chunk headers, if needed.
|
2014-10-15 17:51:12 +02:00
|
|
|
// 4. conn.buf, a bufio.Writer of default (4kB) bytes, writing to ->
|
|
|
|
|
// 5. checkConnErrorWriter{c}, which notes any non-nil error on Write
|
|
|
|
|
// and populates c.werr with it if so. but otherwise writes to:
|
|
|
|
|
// 6. the rwc, the net.Conn.
|
2013-01-11 10:03:43 -08:00
|
|
|
//
|
|
|
|
|
// TODO(bradfitz): short-circuit some of the buffering when the
|
|
|
|
|
// initial header contains both a Content-Type and Content-Length.
|
|
|
|
|
// Also short-circuit in (1) when the header's been sent and not in
|
|
|
|
|
// chunking mode, writing directly to (4) instead, if (2) has no
|
2016-03-01 23:21:55 +00:00
|
|
|
// buffered data. More generally, we could short-circuit from (1) to
|
2013-01-11 10:03:43 -08:00
|
|
|
// (3) even in chunking mode if the write size from (1) is over some
|
|
|
|
|
// threshold and nothing is in (2). The answer might be mostly making
|
|
|
|
|
// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal
|
|
|
|
|
// with this instead.
|
2011-11-01 22:04:37 -04:00
|
|
|
func (w *response) Write(data []byte) (n int, err error) {
|
2013-08-19 22:56:54 -07:00
|
|
|
return w.write(len(data), data, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *response) WriteString(data string) (n int, err error) {
|
|
|
|
|
return w.write(len(data), nil, data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// either dataB or dataS is non-zero.
|
|
|
|
|
func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
|
2012-12-05 19:25:43 -08:00
|
|
|
if w.conn.hijacked() {
|
2016-10-11 09:23:39 +00:00
|
|
|
if lenData > 0 {
|
|
|
|
|
w.conn.server.logf("http: response.Write on hijacked connection")
|
|
|
|
|
}
|
2009-12-15 15:35:38 -08:00
|
|
|
return 0, ErrHijacked
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2010-09-29 14:30:12 +10:00
|
|
|
if !w.wroteHeader {
|
|
|
|
|
w.WriteHeader(StatusOK)
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2013-08-19 22:56:54 -07:00
|
|
|
if lenData == 0 {
|
2009-11-09 12:07:39 -08:00
|
|
|
return 0, nil
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2011-06-09 18:10:21 -07:00
|
|
|
if !w.bodyAllowed() {
|
2010-06-03 16:09:37 -07:00
|
|
|
return 0, ErrBodyNotAllowed
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-19 22:56:54 -07:00
|
|
|
w.written += int64(lenData) // ignoring errors, for errorKludge
|
2011-03-03 12:22:13 -08:00
|
|
|
if w.contentLength != -1 && w.written > w.contentLength {
|
|
|
|
|
return 0, ErrContentLength
|
|
|
|
|
}
|
2013-08-19 22:56:54 -07:00
|
|
|
if dataB != nil {
|
|
|
|
|
return w.w.Write(dataB)
|
|
|
|
|
} else {
|
|
|
|
|
return w.w.WriteString(dataS)
|
|
|
|
|
}
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2010-09-29 14:30:12 +10:00
|
|
|
func (w *response) finishRequest() {
|
2016-01-18 11:43:32 -08:00
|
|
|
w.handlerDone.setTrue()
|
2013-01-11 10:03:43 -08:00
|
|
|
|
2010-09-29 14:30:12 +10:00
|
|
|
if !w.wroteHeader {
|
|
|
|
|
w.WriteHeader(StatusOK)
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
|
|
|
|
|
w.w.Flush()
|
2013-08-10 19:22:44 -07:00
|
|
|
putBufioWriter(w.w)
|
2013-01-11 10:03:43 -08:00
|
|
|
w.cw.close()
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
w.conn.bufw.Flush()
|
2013-01-11 10:03:43 -08:00
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
w.conn.r.abortPendingRead()
|
|
|
|
|
|
2014-01-14 09:46:40 -08:00
|
|
|
// Close the body (regardless of w.closeAfterReply) so we can
|
|
|
|
|
// re-use its bufio.Reader later safely.
|
2015-11-03 12:04:20 -08:00
|
|
|
w.reqBody.Close()
|
2014-01-14 09:46:40 -08:00
|
|
|
|
2011-04-28 15:21:54 +10:00
|
|
|
if w.req.MultipartForm != nil {
|
|
|
|
|
w.req.MultipartForm.RemoveAll()
|
|
|
|
|
}
|
2015-06-24 11:53:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shouldReuseConnection reports whether the underlying TCP connection can be reused.
|
|
|
|
|
// It must only be called after the handler is done executing.
|
|
|
|
|
func (w *response) shouldReuseConnection() bool {
|
|
|
|
|
if w.closeAfterReply {
|
|
|
|
|
// The request or something set while executing the
|
|
|
|
|
// handler indicated we shouldn't reuse this
|
|
|
|
|
// connection.
|
|
|
|
|
return false
|
|
|
|
|
}
|
2011-03-03 12:22:13 -08:00
|
|
|
|
net/http: treat HEAD requests like GET requests
A response to a HEAD request is supposed to look the same as a
response to a GET request, just without a body.
HEAD requests are incredibly rare in the wild.
The Go net/http package has so far treated HEAD requests
specially: a Write on our default ResponseWriter returned
ErrBodyNotAllowed, telling handlers that something was wrong.
This was to optimize the fast path for HEAD requests, but:
1) because HEAD requests are incredibly rare, they're not
worth having a fast path for.
2) Letting the http.Handler handle but do nop Writes is still
very fast.
3) this forces ugly error handling into the application.
e.g. https://code.google.com/p/go/source/detail?r=6f596be7a31e
and related.
4) The net/http package nowadays does Content-Type sniffing,
but you don't get that for HEAD.
5) The net/http package nowadays does Content-Length counting
for small (few KB) responses, but not for HEAD.
6) ErrBodyNotAllowed was useless. By the time you received it,
you had probably already done all your heavy computation
and I/O to calculate what to write.
So, this change makes HEAD requests like GET requests.
We now count content-length and sniff content-type for HEAD
requests. If you Write, it doesn't return an error.
If you want a fast-path in your code for HEAD, you have to do
it early and set all the response headers yourself. Just like
before. If you choose not to Write in HEAD requests, be sure
to set Content-Length if you know it. We won't write
"Content-Length: 0" because you might've just chosen to not
write (or you don't know your Content-Length in advance).
Fixes #5454
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/12583043
2013-08-06 18:33:03 -07:00
|
|
|
if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
|
2011-03-03 12:22:13 -08:00
|
|
|
// Did not write enough. Avoid getting out of sync.
|
2015-06-24 11:53:24 +02:00
|
|
|
return false
|
2011-03-03 12:22:13 -08:00
|
|
|
}
|
2014-10-15 17:51:12 +02:00
|
|
|
|
|
|
|
|
// There was some error writing to the underlying connection
|
|
|
|
|
// during the request, so don't re-use this conn.
|
|
|
|
|
if w.conn.werr != nil {
|
2015-06-24 11:53:24 +02:00
|
|
|
return false
|
2014-10-15 17:51:12 +02:00
|
|
|
}
|
2015-06-24 11:53:24 +02:00
|
|
|
|
2015-07-24 14:22:26 -07:00
|
|
|
if w.closedRequestBodyEarly() {
|
2015-06-24 11:53:24 +02:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2015-07-24 14:22:26 -07:00
|
|
|
func (w *response) closedRequestBodyEarly() bool {
|
|
|
|
|
body, ok := w.req.Body.(*body)
|
|
|
|
|
return ok && body.didEarlyClose()
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-29 14:30:12 +10:00
|
|
|
func (w *response) Flush() {
|
|
|
|
|
if !w.wroteHeader {
|
|
|
|
|
w.WriteHeader(StatusOK)
|
2009-11-13 18:06:47 -08:00
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
w.w.Flush()
|
|
|
|
|
w.cw.flush()
|
2009-11-13 18:06:47 -08:00
|
|
|
}
|
|
|
|
|
|
2012-05-29 12:40:13 -07:00
|
|
|
func (c *conn) finalFlush() {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
if c.bufr != nil {
|
2013-03-21 20:02:01 -07:00
|
|
|
// Steal the bufio.Reader (~4KB worth of memory) and its associated
|
|
|
|
|
// reader for a future connection.
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
putBufioReader(c.bufr)
|
|
|
|
|
c.bufr = nil
|
|
|
|
|
}
|
2013-03-21 20:02:01 -07:00
|
|
|
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
if c.bufw != nil {
|
|
|
|
|
c.bufw.Flush()
|
2013-03-21 20:02:01 -07:00
|
|
|
// Steal the bufio.Writer (~4KB worth of memory) and its associated
|
|
|
|
|
// writer for a future connection.
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
putBufioWriter(c.bufw)
|
|
|
|
|
c.bufw = nil
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2012-05-29 12:40:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close the connection.
|
|
|
|
|
func (c *conn) close() {
|
|
|
|
|
c.finalFlush()
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
c.rwc.Close()
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2012-11-12 15:20:18 -08:00
|
|
|
// rstAvoidanceDelay is the amount of time we sleep after closing the
|
|
|
|
|
// write side of a TCP connection before closing the entire socket.
|
|
|
|
|
// By sleeping, we increase the chances that the client sees our FIN
|
|
|
|
|
// and processes its final data before they process the subsequent RST
|
|
|
|
|
// from closing a connection with known unread data.
|
|
|
|
|
// This RST seems to occur mostly on BSD systems. (And Windows?)
|
|
|
|
|
// This timeout is somewhat arbitrary (~latency around the planet).
|
|
|
|
|
const rstAvoidanceDelay = 500 * time.Millisecond
|
|
|
|
|
|
2014-09-24 17:01:54 -07:00
|
|
|
type closeWriter interface {
|
|
|
|
|
CloseWrite() error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var _ closeWriter = (*net.TCPConn)(nil)
|
|
|
|
|
|
2012-11-12 15:20:18 -08:00
|
|
|
// closeWrite flushes any outstanding data and sends a FIN packet (if
|
2016-03-01 23:21:55 +00:00
|
|
|
// client is connected via TCP), signalling that we're done. We then
|
2014-09-24 17:01:54 -07:00
|
|
|
// pause for a bit, hoping the client processes it before any
|
2012-11-12 15:20:18 -08:00
|
|
|
// subsequent RST.
|
|
|
|
|
//
|
2015-07-10 17:17:11 -06:00
|
|
|
// See https://golang.org/issue/3595
|
2012-11-12 15:20:18 -08:00
|
|
|
func (c *conn) closeWriteAndWait() {
|
2012-05-29 12:40:13 -07:00
|
|
|
c.finalFlush()
|
2014-09-24 17:01:54 -07:00
|
|
|
if tcp, ok := c.rwc.(closeWriter); ok {
|
2012-05-29 12:40:13 -07:00
|
|
|
tcp.CloseWrite()
|
|
|
|
|
}
|
2012-11-12 15:20:18 -08:00
|
|
|
time.Sleep(rstAvoidanceDelay)
|
2012-05-29 12:40:13 -07:00
|
|
|
}
|
|
|
|
|
|
2013-07-23 11:59:49 +10:00
|
|
|
// validNPN reports whether the proto is not a blacklisted Next
|
2016-03-01 23:21:55 +00:00
|
|
|
// Protocol Negotiation protocol. Empty and built-in protocol types
|
2013-02-04 13:55:38 -08:00
|
|
|
// are blacklisted and can't be overridden with alternate
|
|
|
|
|
// implementations.
|
|
|
|
|
func validNPN(proto string) bool {
|
|
|
|
|
switch proto {
|
|
|
|
|
case "", "http/1.1", "http/1.0":
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-27 18:29:00 -08:00
|
|
|
func (c *conn) setState(nc net.Conn, state ConnState) {
|
2016-10-30 03:28:05 +00:00
|
|
|
srv := c.server
|
|
|
|
|
switch state {
|
|
|
|
|
case StateNew:
|
|
|
|
|
srv.trackConn(c, true)
|
|
|
|
|
case StateHijacked, StateClosed:
|
|
|
|
|
srv.trackConn(c, false)
|
|
|
|
|
}
|
|
|
|
|
c.curState.Store(connStateInterface[state])
|
|
|
|
|
if hook := srv.ConnState; hook != nil {
|
2014-02-27 18:29:00 -08:00
|
|
|
hook(nc, state)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-30 03:28:05 +00:00
|
|
|
// connStateInterface is an array of the interface{} versions of
|
|
|
|
|
// ConnState values, so we can use them in atomic.Values later without
|
|
|
|
|
// paying the cost of shoving their integers in an interface{}.
|
|
|
|
|
var connStateInterface = [...]interface{}{
|
|
|
|
|
StateNew: StateNew,
|
|
|
|
|
StateActive: StateActive,
|
|
|
|
|
StateIdle: StateIdle,
|
|
|
|
|
StateHijacked: StateHijacked,
|
|
|
|
|
StateClosed: StateClosed,
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-16 18:51:12 +00:00
|
|
|
// badRequestError is a literal string (used by in the server in HTML,
|
|
|
|
|
// unescaped) to tell the user why their request was bad. It should
|
2016-02-24 11:55:20 +01:00
|
|
|
// be plain text without user info or other embedded errors.
|
2015-12-16 18:51:12 +00:00
|
|
|
type badRequestError string
|
|
|
|
|
|
|
|
|
|
func (e badRequestError) Error() string { return "Bad Request: " + string(e) }
|
|
|
|
|
|
2016-11-10 22:49:16 +00:00
|
|
|
// ErrAbortHandler is a sentinel panic value to abort a handler.
|
|
|
|
|
// While any panic from ServeHTTP aborts the response to the client,
|
|
|
|
|
// panicking with ErrAbortHandler also suppresses logging of a stack
|
|
|
|
|
// trace to the server's error log.
|
|
|
|
|
var ErrAbortHandler = errors.New("net/http: abort Handler")
|
|
|
|
|
|
2016-08-26 22:21:00 +01:00
|
|
|
// isCommonNetReadError reports whether err is a common error
|
|
|
|
|
// encountered during reading a request off the network when the
|
|
|
|
|
// client has gone away or had its read fail somehow. This is used to
|
|
|
|
|
// determine which logs are interesting enough to log about.
|
|
|
|
|
func isCommonNetReadError(err error) bool {
|
|
|
|
|
if err == io.EOF {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-02 18:01:32 -08:00
|
|
|
// Serve a new connection.
|
2016-04-11 05:12:43 +00:00
|
|
|
func (c *conn) serve(ctx context.Context) {
|
2015-10-14 14:25:00 -07:00
|
|
|
c.remoteAddr = c.rwc.RemoteAddr().String()
|
2017-01-18 23:47:54 -05:00
|
|
|
ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())
|
2011-06-02 12:00:26 -07:00
|
|
|
defer func() {
|
2016-11-10 22:49:16 +00:00
|
|
|
if err := recover(); err != nil && err != ErrAbortHandler {
|
2014-02-14 10:15:38 +11:00
|
|
|
const size = 64 << 10
|
2012-12-21 15:14:38 +11:00
|
|
|
buf := make([]byte, size)
|
|
|
|
|
buf = buf[:runtime.Stack(buf, false)]
|
2014-02-28 12:12:51 -08:00
|
|
|
c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
|
2011-06-02 12:00:26 -07:00
|
|
|
}
|
2012-12-21 15:14:38 +11:00
|
|
|
if !c.hijacked() {
|
|
|
|
|
c.close()
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
c.setState(c.rwc, StateClosed)
|
2012-01-19 14:19:59 -08:00
|
|
|
}
|
2011-06-02 12:00:26 -07:00
|
|
|
}()
|
|
|
|
|
|
2011-09-19 19:56:51 -07:00
|
|
|
if tlsConn, ok := c.rwc.(*tls.Conn); ok {
|
2013-02-04 13:52:45 -08:00
|
|
|
if d := c.server.ReadTimeout; d != 0 {
|
|
|
|
|
c.rwc.SetReadDeadline(time.Now().Add(d))
|
|
|
|
|
}
|
|
|
|
|
if d := c.server.WriteTimeout; d != 0 {
|
|
|
|
|
c.rwc.SetWriteDeadline(time.Now().Add(d))
|
|
|
|
|
}
|
2011-10-18 12:59:32 -04:00
|
|
|
if err := tlsConn.Handshake(); err != nil {
|
2014-02-28 12:12:51 -08:00
|
|
|
c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
|
2011-10-18 12:59:32 -04:00
|
|
|
return
|
|
|
|
|
}
|
2011-09-19 19:56:51 -07:00
|
|
|
c.tlsState = new(tls.ConnectionState)
|
|
|
|
|
*c.tlsState = tlsConn.ConnectionState()
|
2013-02-04 13:55:38 -08:00
|
|
|
if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) {
|
|
|
|
|
if fn := c.server.TLSNextProto[proto]; fn != nil {
|
|
|
|
|
h := initNPNRequest{tlsConn, serverHandler{c.server}}
|
|
|
|
|
fn(c.server, tlsConn, h)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2011-09-19 19:56:51 -07:00
|
|
|
}
|
|
|
|
|
|
2016-04-06 12:31:55 -07:00
|
|
|
// HTTP/1.x from here on.
|
|
|
|
|
|
2016-04-11 05:12:43 +00:00
|
|
|
ctx, cancelCtx := context.WithCancel(ctx)
|
2016-10-14 11:45:59 +01:00
|
|
|
c.cancelCtx = cancelCtx
|
2016-04-06 12:31:55 -07:00
|
|
|
defer cancelCtx()
|
|
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
c.r = &connReader{conn: c}
|
|
|
|
|
c.bufr = newBufioReader(c.r)
|
|
|
|
|
c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
|
|
|
|
|
|
2008-09-24 15:26:55 -07:00
|
|
|
for {
|
2016-04-06 12:31:55 -07:00
|
|
|
w, err := c.readRequest(ctx)
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
if c.r.remain != c.server.initialReadLimitSize() {
|
2014-03-03 18:58:28 -08:00
|
|
|
// If we read any bytes off the wire, we're active.
|
|
|
|
|
c.setState(c.rwc, StateActive)
|
|
|
|
|
}
|
2008-09-24 15:26:55 -07:00
|
|
|
if err != nil {
|
2016-08-26 22:21:00 +01:00
|
|
|
const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
|
|
|
|
|
|
2011-08-09 10:55:14 -07:00
|
|
|
if err == errTooLarge {
|
|
|
|
|
// Their HTTP client may or may not be
|
|
|
|
|
// able to read this if we're
|
|
|
|
|
// responding to them and hanging up
|
|
|
|
|
// while they're still writing their
|
2016-03-01 23:21:55 +00:00
|
|
|
// request. Undefined behavior.
|
2016-08-26 22:21:00 +01:00
|
|
|
const publicErr = "431 Request Header Fields Too Large"
|
|
|
|
|
fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
|
2012-11-12 15:20:18 -08:00
|
|
|
c.closeWriteAndWait()
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
return
|
|
|
|
|
}
|
2016-08-26 22:21:00 +01:00
|
|
|
if isCommonNetReadError(err) {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
return // don't reply
|
|
|
|
|
}
|
2016-08-26 22:21:00 +01:00
|
|
|
|
|
|
|
|
publicErr := "400 Bad Request"
|
2015-12-16 18:51:12 +00:00
|
|
|
if v, ok := err.(badRequestError); ok {
|
2016-08-26 22:21:00 +01:00
|
|
|
publicErr = publicErr + ": " + string(v)
|
2015-12-16 18:51:12 +00:00
|
|
|
}
|
2016-08-26 22:21:00 +01:00
|
|
|
|
|
|
|
|
fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
return
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
2011-04-13 14:09:04 -07:00
|
|
|
|
|
|
|
|
// Expect 100 Continue support
|
|
|
|
|
req := w.req
|
|
|
|
|
if req.expectsContinue() {
|
2014-04-10 22:25:31 -07:00
|
|
|
if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
|
2011-04-13 14:09:04 -07:00
|
|
|
// Wrap the Body reader with one that replies on the connection
|
|
|
|
|
req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
|
|
|
|
|
}
|
2012-05-28 11:07:24 -07:00
|
|
|
} else if req.Header.get("Expect") != "" {
|
2012-12-05 19:25:43 -08:00
|
|
|
w.sendExpectationFailed()
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
return
|
2011-04-13 14:09:04 -07:00
|
|
|
}
|
|
|
|
|
|
2016-10-14 11:45:59 +01:00
|
|
|
c.curReq.Store(w)
|
|
|
|
|
|
|
|
|
|
if requestBodyRemains(req.Body) {
|
|
|
|
|
registerOnHitEOF(req.Body, w.conn.r.startBackgroundRead)
|
|
|
|
|
} else {
|
|
|
|
|
if w.conn.bufr.Buffered() > 0 {
|
|
|
|
|
w.conn.r.closeNotifyFromPipelinedRequest()
|
|
|
|
|
}
|
|
|
|
|
w.conn.r.startBackgroundRead()
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-27 21:55:04 -04:00
|
|
|
// HTTP cannot have multiple simultaneous active requests.[*]
|
2009-02-02 18:01:32 -08:00
|
|
|
// Until the server replies to this request, it can't read another,
|
2009-04-07 00:40:07 -07:00
|
|
|
// so we might as well run the handler in this goroutine.
|
2016-03-01 23:21:55 +00:00
|
|
|
// [*] Not strictly true: HTTP pipelining. We could let them all process
|
2010-09-27 21:55:04 -04:00
|
|
|
// in parallel even if their responses need to be serialized.
|
2016-10-14 11:45:59 +01:00
|
|
|
// But we're not going to implement HTTP pipelining because it
|
|
|
|
|
// was never deployed in the wild and the answer is HTTP/2.
|
2013-02-04 13:55:38 -08:00
|
|
|
serverHandler{c.server}.ServeHTTP(w, w.req)
|
2016-04-06 12:31:55 -07:00
|
|
|
w.cancelCtx()
|
2012-12-05 19:25:43 -08:00
|
|
|
if c.hijacked() {
|
2009-11-09 12:07:39 -08:00
|
|
|
return
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2010-09-29 14:30:12 +10:00
|
|
|
w.finishRequest()
|
2015-06-24 11:53:24 +02:00
|
|
|
if !w.shouldReuseConnection() {
|
2015-07-24 14:22:26 -07:00
|
|
|
if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
|
2012-11-12 15:20:18 -08:00
|
|
|
c.closeWriteAndWait()
|
2012-05-29 12:40:13 -07:00
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
return
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
2014-02-27 18:29:00 -08:00
|
|
|
c.setState(c.rwc, StateIdle)
|
2016-10-14 11:45:59 +01:00
|
|
|
c.curReq.Store((*response)(nil))
|
2016-10-23 06:04:14 -07:00
|
|
|
|
2016-11-11 18:43:39 +00:00
|
|
|
if !w.conn.server.doKeepAlives() {
|
|
|
|
|
// We're in shutdown mode. We might've replied
|
|
|
|
|
// to the user without "Connection: close" and
|
|
|
|
|
// they might think they can send another
|
|
|
|
|
// request, but such is life with HTTP/1.1.
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-23 06:04:14 -07:00
|
|
|
if d := c.server.idleTimeout(); d != 0 {
|
|
|
|
|
c.rwc.SetReadDeadline(time.Now().Add(d))
|
|
|
|
|
if _, err := c.bufr.Peek(4); err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
c.rwc.SetReadDeadline(time.Time{})
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
2009-02-03 14:16:22 -08:00
|
|
|
}
|
|
|
|
|
|
2012-12-05 19:25:43 -08:00
|
|
|
func (w *response) sendExpectationFailed() {
|
|
|
|
|
// TODO(bradfitz): let ServeHTTP handlers handle
|
|
|
|
|
// requests with non-standard expectation[s]? Seems
|
|
|
|
|
// theoretical at best, and doesn't fit into the
|
2016-03-01 23:21:55 +00:00
|
|
|
// current ServeHTTP model anyway. We'd need to
|
2012-12-05 19:25:43 -08:00
|
|
|
// make the ResponseWriter an optional
|
|
|
|
|
// "ExpectReplier" interface or something.
|
|
|
|
|
//
|
|
|
|
|
// For now we'll just obey RFC 2616 14.20 which says
|
|
|
|
|
// "If a server receives a request containing an
|
|
|
|
|
// Expect field that includes an expectation-
|
|
|
|
|
// extension that it does not support, it MUST
|
|
|
|
|
// respond with a 417 (Expectation Failed) status."
|
|
|
|
|
w.Header().Set("Connection", "close")
|
|
|
|
|
w.WriteHeader(StatusExpectationFailed)
|
|
|
|
|
w.finishRequest()
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 12:04:04 -08:00
|
|
|
// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
|
|
|
|
|
// and a Hijacker.
|
2011-11-01 22:04:37 -04:00
|
|
|
func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
|
2016-01-18 11:43:32 -08:00
|
|
|
if w.handlerDone.isSet() {
|
|
|
|
|
panic("net/http: Hijack called after ServeHTTP finished")
|
|
|
|
|
}
|
2013-01-11 10:03:43 -08:00
|
|
|
if w.wroteHeader {
|
|
|
|
|
w.cw.flush()
|
|
|
|
|
}
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
|
|
|
|
|
c := w.conn
|
|
|
|
|
c.mu.Lock()
|
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
|
|
2013-12-26 11:52:14 -08:00
|
|
|
// Release the bufioWriter that writes to the chunk writer, it is not
|
|
|
|
|
// used after a connection has been hijacked.
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
rwc, buf, err = c.hijackLocked()
|
2013-12-26 11:52:14 -08:00
|
|
|
if err == nil {
|
|
|
|
|
putBufioWriter(w.w)
|
|
|
|
|
w.w = nil
|
|
|
|
|
}
|
|
|
|
|
return rwc, buf, err
|
2012-12-05 19:25:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *response) CloseNotify() <-chan bool {
|
2016-01-18 11:43:32 -08:00
|
|
|
if w.handlerDone.isSet() {
|
|
|
|
|
panic("net/http: CloseNotify called after ServeHTTP finished")
|
|
|
|
|
}
|
2016-10-14 11:45:59 +01:00
|
|
|
return w.closeNotifyCh
|
2016-01-04 20:38:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func registerOnHitEOF(rc io.ReadCloser, fn func()) {
|
|
|
|
|
switch v := rc.(type) {
|
|
|
|
|
case *expectContinueReader:
|
|
|
|
|
registerOnHitEOF(v.readCloser, fn)
|
|
|
|
|
case *body:
|
|
|
|
|
v.registerOnHitEOF(fn)
|
|
|
|
|
default:
|
|
|
|
|
panic("unexpected type " + fmt.Sprintf("%T", rc))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// requestBodyRemains reports whether future calls to Read
|
|
|
|
|
// on rc might yield more data.
|
|
|
|
|
func requestBodyRemains(rc io.ReadCloser) bool {
|
2016-10-22 09:47:05 -07:00
|
|
|
if rc == NoBody {
|
2016-01-04 20:38:20 +00:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
switch v := rc.(type) {
|
|
|
|
|
case *expectContinueReader:
|
|
|
|
|
return requestBodyRemains(v.readCloser)
|
|
|
|
|
case *body:
|
|
|
|
|
return v.bodyRemains()
|
|
|
|
|
default:
|
|
|
|
|
panic("unexpected type " + fmt.Sprintf("%T", rc))
|
|
|
|
|
}
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
|
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// The HandlerFunc type is an adapter to allow the use of
|
2016-03-01 23:21:55 +00:00
|
|
|
// ordinary functions as HTTP handlers. If f is a function
|
2009-03-11 12:51:10 -07:00
|
|
|
// with the appropriate signature, HandlerFunc(f) is a
|
2015-12-17 20:53:41 +00:00
|
|
|
// Handler that calls f.
|
2010-09-29 14:30:12 +10:00
|
|
|
type HandlerFunc func(ResponseWriter, *Request)
|
2009-03-11 12:51:10 -07:00
|
|
|
|
2011-06-18 21:53:18 +10:00
|
|
|
// ServeHTTP calls f(w, r).
|
2010-09-29 14:30:12 +10:00
|
|
|
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
|
|
|
|
|
f(w, r)
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper handlers
|
|
|
|
|
|
2010-03-20 10:22:09 +11:00
|
|
|
// Error replies to the request with the specified error message and HTTP code.
|
2016-04-11 11:15:00 -03:00
|
|
|
// It does not otherwise end the request; the caller should ensure no further
|
|
|
|
|
// writes are done to w.
|
2013-08-01 12:05:05 -07:00
|
|
|
// The error message should be plain text.
|
2010-09-29 14:30:12 +10:00
|
|
|
func Error(w ResponseWriter, error string, code int) {
|
2011-03-09 09:41:01 -08:00
|
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
2015-06-02 11:01:56 -07:00
|
|
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
2010-09-29 14:30:12 +10:00
|
|
|
w.WriteHeader(code)
|
|
|
|
|
fmt.Fprintln(w, error)
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2010-03-20 10:22:09 +11:00
|
|
|
// NotFound replies to the request with an HTTP 404 not found error.
|
2010-09-29 14:30:12 +10:00
|
|
|
func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
|
2010-03-20 10:22:09 +11:00
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// NotFoundHandler returns a simple request handler
|
|
|
|
|
// that replies to each request with a ``404 page not found'' reply.
|
2009-12-15 15:35:38 -08:00
|
|
|
func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
|
2009-02-02 18:01:32 -08:00
|
|
|
|
2011-06-27 11:03:43 -07:00
|
|
|
// StripPrefix returns a handler that serves HTTP requests
|
|
|
|
|
// by removing the given prefix from the request URL's Path
|
|
|
|
|
// and invoking the handler h. StripPrefix handles a
|
|
|
|
|
// request for a path that doesn't begin with prefix by
|
|
|
|
|
// replying with an HTTP 404 not found error.
|
|
|
|
|
func StripPrefix(prefix string, h Handler) Handler {
|
2013-03-18 13:44:20 -07:00
|
|
|
if prefix == "" {
|
|
|
|
|
return h
|
|
|
|
|
}
|
2011-06-27 11:03:43 -07:00
|
|
|
return HandlerFunc(func(w ResponseWriter, r *Request) {
|
2013-03-18 13:44:20 -07:00
|
|
|
if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {
|
2017-02-07 10:57:33 -05:00
|
|
|
r2 := new(Request)
|
|
|
|
|
*r2 = *r
|
|
|
|
|
r2.URL = new(url.URL)
|
|
|
|
|
*r2.URL = *r.URL
|
|
|
|
|
r2.URL.Path = p
|
|
|
|
|
h.ServeHTTP(w, r2)
|
2013-03-18 13:44:20 -07:00
|
|
|
} else {
|
2011-06-27 11:03:43 -07:00
|
|
|
NotFound(w, r)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-14 20:31:31 -07:00
|
|
|
// Redirect replies to the request with a redirect to url,
|
|
|
|
|
// which may be a path relative to the request path.
|
2015-10-16 13:26:20 +03:00
|
|
|
//
|
|
|
|
|
// The provided code should be in the 3xx range and is usually
|
|
|
|
|
// StatusMovedPermanently, StatusFound or StatusSeeOther.
|
2011-08-17 13:36:02 +10:00
|
|
|
func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
|
|
|
|
|
if u, err := url.Parse(urlStr); err == nil {
|
2011-01-11 17:15:28 -05:00
|
|
|
// If url was relative, make absolute by
|
|
|
|
|
// combining with request path.
|
|
|
|
|
// The browser would probably do this for us,
|
|
|
|
|
// but doing it ourselves is more reliable.
|
|
|
|
|
|
|
|
|
|
// NOTE(rsc): RFC 2616 says that the Location
|
|
|
|
|
// line must be an absolute URI, like
|
|
|
|
|
// "http://www.google.com/redirect/",
|
|
|
|
|
// not a path like "/redirect/".
|
|
|
|
|
// Unfortunately, we don't know what to
|
|
|
|
|
// put in the host name section to get the
|
|
|
|
|
// client to connect to us again, so we can't
|
|
|
|
|
// know the right absolute URI to send back.
|
|
|
|
|
// Because of this problem, no one pays attention
|
|
|
|
|
// to the RFC; they all send back just a new path.
|
|
|
|
|
// So do we.
|
2015-09-02 13:40:34 +03:00
|
|
|
if u.Scheme == "" && u.Host == "" {
|
|
|
|
|
oldpath := r.URL.Path
|
|
|
|
|
if oldpath == "" { // should not happen, but avoid a crash if it does
|
|
|
|
|
oldpath = "/"
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-11 17:15:28 -05:00
|
|
|
// no leading http://server
|
2011-08-17 13:36:02 +10:00
|
|
|
if urlStr == "" || urlStr[0] != '/' {
|
2011-01-11 17:15:28 -05:00
|
|
|
// make relative path absolute
|
|
|
|
|
olddir, _ := path.Split(oldpath)
|
2011-08-17 13:36:02 +10:00
|
|
|
urlStr = olddir + urlStr
|
2011-01-11 17:15:28 -05:00
|
|
|
}
|
2009-04-15 18:40:55 -07:00
|
|
|
|
2011-05-11 04:30:05 -07:00
|
|
|
var query string
|
2013-08-05 16:27:24 -07:00
|
|
|
if i := strings.Index(urlStr, "?"); i != -1 {
|
2011-08-17 13:36:02 +10:00
|
|
|
urlStr, query = urlStr[:i], urlStr[i:]
|
2011-05-11 04:30:05 -07:00
|
|
|
}
|
|
|
|
|
|
2011-01-11 17:15:28 -05:00
|
|
|
// clean up but preserve trailing slash
|
2013-04-20 17:20:14 -07:00
|
|
|
trailing := strings.HasSuffix(urlStr, "/")
|
2011-08-17 13:36:02 +10:00
|
|
|
urlStr = path.Clean(urlStr)
|
2013-04-20 17:20:14 -07:00
|
|
|
if trailing && !strings.HasSuffix(urlStr, "/") {
|
2011-08-17 13:36:02 +10:00
|
|
|
urlStr += "/"
|
2011-01-11 17:15:28 -05:00
|
|
|
}
|
2011-08-17 13:36:02 +10:00
|
|
|
urlStr += query
|
2009-04-15 18:40:55 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-21 11:43:12 -07:00
|
|
|
w.Header().Set("Location", hexEscapeNonASCII(urlStr))
|
2010-09-29 14:30:12 +10:00
|
|
|
w.WriteHeader(code)
|
2011-01-11 17:15:28 -05:00
|
|
|
|
2016-04-12 16:58:56 -03:00
|
|
|
// RFC 2616 recommends that a short note "SHOULD" be included in the
|
2011-01-11 17:15:28 -05:00
|
|
|
// response because older user agents may not understand 301/307.
|
2011-01-13 14:34:31 -05:00
|
|
|
// Shouldn't send the response for POST or HEAD; that leaves GET.
|
|
|
|
|
if r.Method == "GET" {
|
2011-08-17 13:36:02 +10:00
|
|
|
note := "<a href=\"" + htmlEscape(urlStr) + "\">" + statusText[code] + "</a>.\n"
|
2011-01-13 14:34:31 -05:00
|
|
|
fmt.Fprintln(w, note)
|
2011-01-11 17:15:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-03 15:19:04 -07:00
|
|
|
var htmlReplacer = strings.NewReplacer(
|
|
|
|
|
"&", "&",
|
|
|
|
|
"<", "<",
|
|
|
|
|
">", ">",
|
2012-04-12 09:35:43 +10:00
|
|
|
// """ is shorter than """.
|
|
|
|
|
`"`, """,
|
|
|
|
|
// "'" is shorter than "'" and apos was not in HTML until HTML5.
|
|
|
|
|
"'", "'",
|
2011-10-03 15:19:04 -07:00
|
|
|
)
|
|
|
|
|
|
2011-01-11 17:15:28 -05:00
|
|
|
func htmlEscape(s string) string {
|
2011-10-03 15:19:04 -07:00
|
|
|
return htmlReplacer.Replace(s)
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2009-04-14 20:31:31 -07:00
|
|
|
// Redirect to a fixed URL
|
2009-05-12 15:41:19 -07:00
|
|
|
type redirectHandler struct {
|
2009-12-15 15:35:38 -08:00
|
|
|
url string
|
|
|
|
|
code int
|
2009-05-12 15:41:19 -07:00
|
|
|
}
|
2009-10-06 19:41:51 -07:00
|
|
|
|
2010-09-29 14:30:12 +10:00
|
|
|
func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
|
|
|
|
|
Redirect(w, r, rh.url, rh.code)
|
2009-04-14 20:31:31 -07:00
|
|
|
}
|
|
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// RedirectHandler returns a request handler that redirects
|
2009-05-12 15:41:19 -07:00
|
|
|
// each request it receives to the given url using the given
|
|
|
|
|
// status code.
|
2015-10-16 13:26:20 +03:00
|
|
|
//
|
|
|
|
|
// The provided code should be in the 3xx range and is usually
|
|
|
|
|
// StatusMovedPermanently, StatusFound or StatusSeeOther.
|
2009-05-12 15:41:19 -07:00
|
|
|
func RedirectHandler(url string, code int) Handler {
|
2009-11-09 12:07:39 -08:00
|
|
|
return &redirectHandler{url, code}
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// ServeMux is an HTTP request multiplexer.
|
|
|
|
|
// It matches the URL of each incoming request against a list of registered
|
|
|
|
|
// patterns and calls the handler for the pattern that
|
|
|
|
|
// most closely matches the URL.
|
|
|
|
|
//
|
2012-06-28 15:18:35 -07:00
|
|
|
// Patterns name fixed, rooted paths, like "/favicon.ico",
|
2011-02-01 13:58:59 -05:00
|
|
|
// or rooted subtrees, like "/images/" (note the trailing slash).
|
2009-03-11 12:51:10 -07:00
|
|
|
// Longer patterns take precedence over shorter ones, so that
|
|
|
|
|
// if there are handlers registered for both "/images/"
|
|
|
|
|
// and "/images/thumbnails/", the latter handler will be
|
|
|
|
|
// called for paths beginning "/images/thumbnails/" and the
|
2012-06-28 15:18:35 -07:00
|
|
|
// former will receive requests for any other paths in the
|
2009-03-11 12:51:10 -07:00
|
|
|
// "/images/" subtree.
|
|
|
|
|
//
|
2013-09-12 11:20:16 +01:00
|
|
|
// Note that since a pattern ending in a slash names a rooted subtree,
|
|
|
|
|
// the pattern "/" matches all paths not matched by other registered
|
|
|
|
|
// patterns, not just the URL with Path == "/".
|
|
|
|
|
//
|
2015-12-17 02:34:29 -05:00
|
|
|
// If a subtree has been registered and a request is received naming the
|
|
|
|
|
// subtree root without its trailing slash, ServeMux redirects that
|
|
|
|
|
// request to the subtree root (adding the trailing slash). This behavior can
|
|
|
|
|
// be overridden with a separate registration for the path without
|
|
|
|
|
// the trailing slash. For example, registering "/images/" causes ServeMux
|
|
|
|
|
// to redirect a request for "/images" to "/images/", unless "/images" has
|
|
|
|
|
// been registered separately.
|
|
|
|
|
//
|
2011-02-01 13:58:59 -05:00
|
|
|
// Patterns may optionally begin with a host name, restricting matches to
|
2016-03-01 23:21:55 +00:00
|
|
|
// URLs on that host only. Host-specific patterns take precedence over
|
2011-02-01 13:58:59 -05:00
|
|
|
// general patterns, so that a handler might register for the two patterns
|
|
|
|
|
// "/codesearch" and "codesearch.google.com/" without also taking over
|
|
|
|
|
// requests for "http://www.google.com/".
|
2009-04-07 00:40:07 -07:00
|
|
|
//
|
|
|
|
|
// ServeMux also takes care of sanitizing the URL request path,
|
2015-12-17 02:34:29 -05:00
|
|
|
// redirecting any request containing . or .. elements or repeated slashes
|
|
|
|
|
// to an equivalent, cleaner URL.
|
2009-02-02 18:01:32 -08:00
|
|
|
type ServeMux struct {
|
2012-05-28 10:58:49 -07:00
|
|
|
mu sync.RWMutex
|
|
|
|
|
m map[string]muxEntry
|
|
|
|
|
hosts bool // whether any patterns contain hostnames
|
2012-02-08 13:50:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type muxEntry struct {
|
|
|
|
|
explicit bool
|
|
|
|
|
h Handler
|
2012-08-31 12:16:31 -04:00
|
|
|
pattern string
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// NewServeMux allocates and returns a new ServeMux.
|
2016-03-16 20:14:13 +00:00
|
|
|
func NewServeMux() *ServeMux { return new(ServeMux) }
|
2009-02-02 18:01:32 -08:00
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// DefaultServeMux is the default ServeMux used by Serve.
|
2016-03-16 20:14:13 +00:00
|
|
|
var DefaultServeMux = &defaultServeMux
|
|
|
|
|
|
|
|
|
|
var defaultServeMux ServeMux
|
2009-02-02 18:01:32 -08:00
|
|
|
|
|
|
|
|
// Does path match pattern?
|
|
|
|
|
func pathMatch(pattern, path string) bool {
|
|
|
|
|
if len(pattern) == 0 {
|
|
|
|
|
// should not happen
|
2009-11-09 12:07:39 -08:00
|
|
|
return false
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2009-12-15 15:35:38 -08:00
|
|
|
n := len(pattern)
|
2009-02-02 18:01:32 -08:00
|
|
|
if pattern[n-1] != '/' {
|
2009-11-09 12:07:39 -08:00
|
|
|
return pattern == path
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
2009-12-15 15:35:38 -08:00
|
|
|
return len(path) >= n && path[0:n] == pattern
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
|
2009-04-07 00:40:07 -07:00
|
|
|
// Return the canonical path for p, eliminating . and .. elements.
|
|
|
|
|
func cleanPath(p string) string {
|
|
|
|
|
if p == "" {
|
2009-11-09 12:07:39 -08:00
|
|
|
return "/"
|
2009-04-07 00:40:07 -07:00
|
|
|
}
|
|
|
|
|
if p[0] != '/' {
|
2009-11-09 21:23:52 -08:00
|
|
|
p = "/" + p
|
2009-04-07 00:40:07 -07:00
|
|
|
}
|
2009-12-15 15:35:38 -08:00
|
|
|
np := path.Clean(p)
|
2009-04-07 00:40:07 -07:00
|
|
|
// path.Clean removes trailing slash except for root;
|
|
|
|
|
// put the trailing slash back if necessary.
|
|
|
|
|
if p[len(p)-1] == '/' && np != "/" {
|
2009-11-09 12:07:39 -08:00
|
|
|
np += "/"
|
2009-04-07 00:40:07 -07:00
|
|
|
}
|
2009-12-15 15:35:38 -08:00
|
|
|
return np
|
2009-04-07 00:40:07 -07:00
|
|
|
}
|
|
|
|
|
|
2017-03-15 21:55:04 +00:00
|
|
|
// stripHostPort returns h without any trailing ":<port>".
|
|
|
|
|
func stripHostPort(h string) string {
|
|
|
|
|
// If no port on host, return unchanged
|
|
|
|
|
if strings.IndexByte(h, ':') == -1 {
|
|
|
|
|
return h
|
|
|
|
|
}
|
|
|
|
|
host, _, err := net.SplitHostPort(h)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return h // on error, return unchanged
|
|
|
|
|
}
|
|
|
|
|
return host
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-12 10:02:47 +00:00
|
|
|
// Find a handler on a handler map given a path string.
|
|
|
|
|
// Most-specific (longest) pattern wins.
|
2012-08-31 12:16:31 -04:00
|
|
|
func (mux *ServeMux) match(path string) (h Handler, pattern string) {
|
2017-03-12 10:02:47 +00:00
|
|
|
// Check for exact match first.
|
|
|
|
|
v, ok := mux.m[path]
|
|
|
|
|
if ok {
|
|
|
|
|
return v.h, v.pattern
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for longest valid match.
|
2009-12-15 15:35:38 -08:00
|
|
|
var n = 0
|
2009-02-02 18:01:32 -08:00
|
|
|
for k, v := range mux.m {
|
2011-02-01 13:58:59 -05:00
|
|
|
if !pathMatch(k, path) {
|
2009-11-09 12:07:39 -08:00
|
|
|
continue
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
if h == nil || len(k) > n {
|
2009-12-15 15:35:38 -08:00
|
|
|
n = len(k)
|
2012-02-08 13:50:00 -05:00
|
|
|
h = v.h
|
2012-08-31 12:16:31 -04:00
|
|
|
pattern = v.pattern
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
}
|
2012-08-31 12:16:31 -04:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handler returns the handler to use for the given request,
|
|
|
|
|
// consulting r.Method, r.Host, and r.URL.Path. It always returns
|
|
|
|
|
// a non-nil handler. If the path is not in its canonical form, the
|
|
|
|
|
// handler will be an internally-generated handler that redirects
|
2017-03-15 21:55:04 +00:00
|
|
|
// to the canonical path. If the host contains a port, it is ignored
|
|
|
|
|
// when matching handlers.
|
|
|
|
|
//
|
|
|
|
|
// The path and host are used unchanged for CONNECT requests.
|
2012-08-31 12:16:31 -04:00
|
|
|
//
|
|
|
|
|
// Handler also returns the registered pattern that matches the
|
|
|
|
|
// request or, in the case of internally-generated redirects,
|
|
|
|
|
// the pattern that will match after following the redirect.
|
|
|
|
|
//
|
|
|
|
|
// If there is no registered handler that applies to the request,
|
|
|
|
|
// Handler returns a ``page not found'' handler and an empty pattern.
|
|
|
|
|
func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
|
2017-03-15 21:55:04 +00:00
|
|
|
|
|
|
|
|
// CONNECT requests are not canonicalized.
|
|
|
|
|
if r.Method == "CONNECT" {
|
|
|
|
|
return mux.handler(r.Host, r.URL.Path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// All other requests have any port stripped and path cleaned
|
|
|
|
|
// before passing to mux.handler.
|
|
|
|
|
host := stripHostPort(r.Host)
|
|
|
|
|
path := cleanPath(r.URL.Path)
|
|
|
|
|
if path != r.URL.Path {
|
|
|
|
|
_, pattern = mux.handler(host, path)
|
|
|
|
|
url := *r.URL
|
|
|
|
|
url.Path = path
|
|
|
|
|
return RedirectHandler(url.String(), StatusMovedPermanently), pattern
|
2012-08-31 12:16:31 -04:00
|
|
|
}
|
|
|
|
|
|
2017-03-15 21:55:04 +00:00
|
|
|
return mux.handler(host, r.URL.Path)
|
2011-02-01 13:58:59 -05:00
|
|
|
}
|
|
|
|
|
|
2012-08-31 12:16:31 -04:00
|
|
|
// handler is the main implementation of Handler.
|
|
|
|
|
// The path is known to be in canonical form, except for CONNECT methods.
|
|
|
|
|
func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
|
2012-02-08 13:50:00 -05:00
|
|
|
mux.mu.RLock()
|
|
|
|
|
defer mux.mu.RUnlock()
|
|
|
|
|
|
|
|
|
|
// Host-specific pattern takes precedence over generic ones
|
2012-05-28 10:58:49 -07:00
|
|
|
if mux.hosts {
|
2012-08-31 12:16:31 -04:00
|
|
|
h, pattern = mux.match(host + path)
|
2012-05-28 10:58:49 -07:00
|
|
|
}
|
2012-02-08 13:50:00 -05:00
|
|
|
if h == nil {
|
2012-08-31 12:16:31 -04:00
|
|
|
h, pattern = mux.match(path)
|
2012-02-08 13:50:00 -05:00
|
|
|
}
|
|
|
|
|
if h == nil {
|
2012-08-31 12:16:31 -04:00
|
|
|
h, pattern = NotFoundHandler(), ""
|
2012-02-08 13:50:00 -05:00
|
|
|
}
|
2012-08-31 12:16:31 -04:00
|
|
|
return
|
2012-02-08 13:50:00 -05:00
|
|
|
}
|
|
|
|
|
|
2011-02-01 13:58:59 -05:00
|
|
|
// ServeHTTP dispatches the request to the handler whose
|
|
|
|
|
// pattern most closely matches the request URL.
|
|
|
|
|
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
|
2012-12-11 12:07:27 -05:00
|
|
|
if r.RequestURI == "*" {
|
2013-08-06 18:37:34 -07:00
|
|
|
if r.ProtoAtLeast(1, 1) {
|
|
|
|
|
w.Header().Set("Connection", "close")
|
|
|
|
|
}
|
2012-12-11 12:07:27 -05:00
|
|
|
w.WriteHeader(StatusBadRequest)
|
|
|
|
|
return
|
|
|
|
|
}
|
2012-08-31 12:16:31 -04:00
|
|
|
h, _ := mux.Handler(r)
|
|
|
|
|
h.ServeHTTP(w, r)
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2008-09-24 15:26:55 -07:00
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// Handle registers the handler for the given pattern.
|
2012-02-08 13:50:00 -05:00
|
|
|
// If a handler already exists for pattern, Handle panics.
|
2009-02-02 18:01:32 -08:00
|
|
|
func (mux *ServeMux) Handle(pattern string, handler Handler) {
|
2012-02-08 13:50:00 -05:00
|
|
|
mux.mu.Lock()
|
|
|
|
|
defer mux.mu.Unlock()
|
|
|
|
|
|
2011-02-01 13:58:59 -05:00
|
|
|
if pattern == "" {
|
2010-03-24 16:46:53 -07:00
|
|
|
panic("http: invalid pattern " + pattern)
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
2012-02-08 13:50:00 -05:00
|
|
|
if handler == nil {
|
|
|
|
|
panic("http: nil handler")
|
|
|
|
|
}
|
|
|
|
|
if mux.m[pattern].explicit {
|
|
|
|
|
panic("http: multiple registrations for " + pattern)
|
|
|
|
|
}
|
2009-02-02 18:01:32 -08:00
|
|
|
|
2016-03-16 20:14:13 +00:00
|
|
|
if mux.m == nil {
|
|
|
|
|
mux.m = make(map[string]muxEntry)
|
|
|
|
|
}
|
2012-08-31 12:16:31 -04:00
|
|
|
mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}
|
2009-02-02 18:01:32 -08:00
|
|
|
|
2012-05-28 10:58:49 -07:00
|
|
|
if pattern[0] != '/' {
|
|
|
|
|
mux.hosts = true
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-02 18:01:32 -08:00
|
|
|
// Helpful behavior:
|
2012-02-08 13:50:00 -05:00
|
|
|
// If pattern is /tree/, insert an implicit permanent redirect for /tree.
|
|
|
|
|
// It can be overridden by an explicit registration.
|
2009-12-15 15:35:38 -08:00
|
|
|
n := len(pattern)
|
2012-02-08 13:50:00 -05:00
|
|
|
if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
|
2012-08-31 12:00:01 -04:00
|
|
|
// If pattern contains a host name, strip it and use remaining
|
|
|
|
|
// path for redirect.
|
|
|
|
|
path := pattern
|
|
|
|
|
if pattern[0] != '/' {
|
|
|
|
|
// In pattern, at least the last character is a '/', so
|
|
|
|
|
// strings.Index can't be -1.
|
2013-08-05 16:27:24 -07:00
|
|
|
path = pattern[strings.Index(pattern, "/"):]
|
2012-08-31 12:00:01 -04:00
|
|
|
}
|
2015-04-24 21:47:25 +03:00
|
|
|
url := &url.URL{Path: path}
|
|
|
|
|
mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern}
|
2009-02-02 18:01:32 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-29 10:02:37 +11:00
|
|
|
// HandleFunc registers the handler function for the given pattern.
|
2010-09-29 14:30:12 +10:00
|
|
|
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
|
2010-03-29 10:02:37 +11:00
|
|
|
mux.Handle(pattern, HandlerFunc(handler))
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// Handle registers the handler for the given pattern
|
|
|
|
|
// in the DefaultServeMux.
|
2011-02-22 11:16:25 +11:00
|
|
|
// The documentation for ServeMux explains how patterns are matched.
|
2009-12-15 15:35:38 -08:00
|
|
|
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
|
2009-02-02 18:01:32 -08:00
|
|
|
|
2010-03-29 10:02:37 +11:00
|
|
|
// HandleFunc registers the handler function for the given pattern
|
|
|
|
|
// in the DefaultServeMux.
|
2011-02-22 11:16:25 +11:00
|
|
|
// The documentation for ServeMux explains how patterns are matched.
|
2010-09-29 14:30:12 +10:00
|
|
|
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
|
2010-03-29 10:02:37 +11:00
|
|
|
DefaultServeMux.HandleFunc(pattern, handler)
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// Serve accepts incoming HTTP connections on the listener l,
|
2016-03-01 23:21:55 +00:00
|
|
|
// creating a new service goroutine for each. The service goroutines
|
2009-03-11 12:51:10 -07:00
|
|
|
// read requests and then call handler to reply to them.
|
|
|
|
|
// Handler is typically nil, in which case the DefaultServeMux is used.
|
2011-11-01 22:04:37 -04:00
|
|
|
func Serve(l net.Listener, handler Handler) error {
|
2011-02-10 14:36:22 -08:00
|
|
|
srv := &Server{Handler: handler}
|
|
|
|
|
return srv.Serve(l)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A Server defines parameters for running an HTTP server.
|
2014-02-28 07:40:25 -08:00
|
|
|
// The zero value for Server is a valid configuration.
|
2011-02-10 14:36:22 -08:00
|
|
|
type Server struct {
|
2016-10-23 06:04:14 -07:00
|
|
|
Addr string // TCP address to listen on, ":http" if empty
|
|
|
|
|
Handler Handler // handler to invoke, http.DefaultServeMux if nil
|
|
|
|
|
TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS
|
|
|
|
|
|
|
|
|
|
// ReadTimeout is the maximum duration for reading the entire
|
|
|
|
|
// request, including the body.
|
|
|
|
|
//
|
|
|
|
|
// Because ReadTimeout does not let Handlers make per-request
|
|
|
|
|
// decisions on each request body's acceptable deadline or
|
|
|
|
|
// upload rate, most users will prefer to use
|
|
|
|
|
// ReadHeaderTimeout. It is valid to use them both.
|
|
|
|
|
ReadTimeout time.Duration
|
|
|
|
|
|
|
|
|
|
// ReadHeaderTimeout is the amount of time allowed to read
|
|
|
|
|
// request headers. The connection's read deadline is reset
|
|
|
|
|
// after reading the headers and the Handler can decide what
|
|
|
|
|
// is considered too slow for the body.
|
|
|
|
|
ReadHeaderTimeout time.Duration
|
|
|
|
|
|
|
|
|
|
// WriteTimeout is the maximum duration before timing out
|
|
|
|
|
// writes of the response. It is reset whenever a new
|
|
|
|
|
// request's header is read. Like ReadTimeout, it does not
|
|
|
|
|
// let Handlers make decisions on a per-request basis.
|
|
|
|
|
WriteTimeout time.Duration
|
|
|
|
|
|
|
|
|
|
// IdleTimeout is the maximum amount of time to wait for the
|
|
|
|
|
// next request when keep-alives are enabled. If IdleTimeout
|
|
|
|
|
// is zero, the value of ReadTimeout is used. If both are
|
|
|
|
|
// zero, there is no timeout.
|
|
|
|
|
IdleTimeout time.Duration
|
2016-04-30 17:29:28 -05:00
|
|
|
|
|
|
|
|
// MaxHeaderBytes controls the maximum number of bytes the
|
|
|
|
|
// server will read parsing the request header's keys and
|
|
|
|
|
// values, including the request line. It does not limit the
|
|
|
|
|
// size of the request body.
|
|
|
|
|
// If zero, DefaultMaxHeaderBytes is used.
|
|
|
|
|
MaxHeaderBytes int
|
2013-02-04 13:55:38 -08:00
|
|
|
|
|
|
|
|
// TLSNextProto optionally specifies a function to take over
|
2016-05-16 10:11:59 -03:00
|
|
|
// ownership of the provided TLS connection when an NPN/ALPN
|
2016-03-01 23:21:55 +00:00
|
|
|
// protocol upgrade has occurred. The map key is the protocol
|
2013-02-04 13:55:38 -08:00
|
|
|
// name negotiated. The Handler argument should be used to
|
|
|
|
|
// handle HTTP requests and will initialize the Request's TLS
|
2016-03-01 23:21:55 +00:00
|
|
|
// and RemoteAddr if not already set. The connection is
|
2013-02-04 13:55:38 -08:00
|
|
|
// automatically closed when the function returns.
|
2016-11-10 20:28:14 +00:00
|
|
|
// If TLSNextProto is not nil, HTTP/2 support is not enabled
|
|
|
|
|
// automatically.
|
2013-02-04 13:55:38 -08:00
|
|
|
TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
|
2014-02-27 18:29:00 -08:00
|
|
|
|
|
|
|
|
// ConnState specifies an optional callback function that is
|
|
|
|
|
// called when a client connection changes state. See the
|
|
|
|
|
// ConnState type and associated constants for details.
|
|
|
|
|
ConnState func(net.Conn, ConnState)
|
2014-02-28 07:40:25 -08:00
|
|
|
|
2014-02-28 12:12:51 -08:00
|
|
|
// ErrorLog specifies an optional logger for errors accepting
|
|
|
|
|
// connections and unexpected behavior from handlers.
|
|
|
|
|
// If nil, logging goes to os.Stderr via the log package's
|
|
|
|
|
// standard logger.
|
|
|
|
|
ErrorLog *log.Logger
|
|
|
|
|
|
2015-10-14 20:41:36 +00:00
|
|
|
disableKeepAlives int32 // accessed atomically.
|
2016-10-30 03:28:05 +00:00
|
|
|
inShutdown int32 // accessed atomically (non-zero means we're in Shutdown)
|
2016-07-26 23:44:00 +02:00
|
|
|
nextProtoOnce sync.Once // guards setupHTTP2_* init
|
|
|
|
|
nextProtoErr error // result of http2.ConfigureServer if used
|
2016-10-30 03:28:05 +00:00
|
|
|
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
listeners map[net.Listener]struct{}
|
|
|
|
|
activeConn map[*conn]struct{}
|
|
|
|
|
doneChan chan struct{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) getDoneChan() <-chan struct{} {
|
|
|
|
|
s.mu.Lock()
|
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
|
return s.getDoneChanLocked()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) getDoneChanLocked() chan struct{} {
|
|
|
|
|
if s.doneChan == nil {
|
|
|
|
|
s.doneChan = make(chan struct{})
|
|
|
|
|
}
|
|
|
|
|
return s.doneChan
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) closeDoneChanLocked() {
|
|
|
|
|
ch := s.getDoneChanLocked()
|
|
|
|
|
select {
|
|
|
|
|
case <-ch:
|
|
|
|
|
// Already closed. Don't close again.
|
|
|
|
|
default:
|
|
|
|
|
// Safe to close here. We're the only closer, guarded
|
|
|
|
|
// by s.mu.
|
|
|
|
|
close(ch)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-10 21:35:01 +00:00
|
|
|
// Close immediately closes all active net.Listeners and any
|
|
|
|
|
// connections in state StateNew, StateActive, or StateIdle. For a
|
|
|
|
|
// graceful shutdown, use Shutdown.
|
|
|
|
|
//
|
|
|
|
|
// Close does not attempt to close (and does not even know about)
|
|
|
|
|
// any hijacked connections, such as WebSockets.
|
|
|
|
|
//
|
|
|
|
|
// Close returns any error returned from closing the Server's
|
|
|
|
|
// underlying Listener(s).
|
2016-11-23 16:29:51 -07:00
|
|
|
func (srv *Server) Close() error {
|
|
|
|
|
srv.mu.Lock()
|
|
|
|
|
defer srv.mu.Unlock()
|
|
|
|
|
srv.closeDoneChanLocked()
|
|
|
|
|
err := srv.closeListenersLocked()
|
|
|
|
|
for c := range srv.activeConn {
|
2016-10-30 03:28:05 +00:00
|
|
|
c.rwc.Close()
|
2016-11-23 16:29:51 -07:00
|
|
|
delete(srv.activeConn, c)
|
2016-10-30 03:28:05 +00:00
|
|
|
}
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shutdownPollInterval is how often we poll for quiescence
|
|
|
|
|
// during Server.Shutdown. This is lower during tests, to
|
|
|
|
|
// speed up tests.
|
|
|
|
|
// Ideally we could find a solution that doesn't involve polling,
|
|
|
|
|
// but which also doesn't have a high runtime cost (and doesn't
|
|
|
|
|
// involve any contentious mutexes), but that is left as an
|
|
|
|
|
// exercise for the reader.
|
|
|
|
|
var shutdownPollInterval = 500 * time.Millisecond
|
|
|
|
|
|
|
|
|
|
// Shutdown gracefully shuts down the server without interrupting any
|
|
|
|
|
// active connections. Shutdown works by first closing all open
|
|
|
|
|
// listeners, then closing all idle connections, and then waiting
|
|
|
|
|
// indefinitely for connections to return to idle and then shut down.
|
|
|
|
|
// If the provided context expires before the shutdown is complete,
|
2017-02-17 11:57:46 -05:00
|
|
|
// Shutdown returns the context's error, otherwise it returns any
|
|
|
|
|
// error returned from closing the Server's underlying Listener(s).
|
|
|
|
|
//
|
|
|
|
|
// When Shutdown is called, Serve, ListenAndServe, and
|
|
|
|
|
// ListenAndServeTLS immediately return ErrServerClosed. Make sure the
|
|
|
|
|
// program doesn't exit and waits instead for Shutdown to return.
|
2016-11-10 21:35:01 +00:00
|
|
|
//
|
|
|
|
|
// Shutdown does not attempt to close nor wait for hijacked
|
|
|
|
|
// connections such as WebSockets. The caller of Shutdown should
|
|
|
|
|
// separately notify such long-lived connections of shutdown and wait
|
|
|
|
|
// for them to close, if desired.
|
2016-11-23 16:29:51 -07:00
|
|
|
func (srv *Server) Shutdown(ctx context.Context) error {
|
|
|
|
|
atomic.AddInt32(&srv.inShutdown, 1)
|
|
|
|
|
defer atomic.AddInt32(&srv.inShutdown, -1)
|
2016-10-30 03:28:05 +00:00
|
|
|
|
2016-11-23 16:29:51 -07:00
|
|
|
srv.mu.Lock()
|
|
|
|
|
lnerr := srv.closeListenersLocked()
|
|
|
|
|
srv.closeDoneChanLocked()
|
|
|
|
|
srv.mu.Unlock()
|
2016-10-30 03:28:05 +00:00
|
|
|
|
|
|
|
|
ticker := time.NewTicker(shutdownPollInterval)
|
|
|
|
|
defer ticker.Stop()
|
|
|
|
|
for {
|
2016-11-23 16:29:51 -07:00
|
|
|
if srv.closeIdleConns() {
|
2016-10-30 03:28:05 +00:00
|
|
|
return lnerr
|
|
|
|
|
}
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
|
|
|
|
return ctx.Err()
|
|
|
|
|
case <-ticker.C:
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// closeIdleConns closes all idle connections and reports whether the
|
|
|
|
|
// server is quiescent.
|
|
|
|
|
func (s *Server) closeIdleConns() bool {
|
|
|
|
|
s.mu.Lock()
|
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
|
quiescent := true
|
|
|
|
|
for c := range s.activeConn {
|
|
|
|
|
st, ok := c.curState.Load().(ConnState)
|
|
|
|
|
if !ok || st != StateIdle {
|
|
|
|
|
quiescent = false
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
c.rwc.Close()
|
|
|
|
|
delete(s.activeConn, c)
|
|
|
|
|
}
|
|
|
|
|
return quiescent
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) closeListenersLocked() error {
|
|
|
|
|
var err error
|
|
|
|
|
for ln := range s.listeners {
|
|
|
|
|
if cerr := ln.Close(); cerr != nil && err == nil {
|
|
|
|
|
err = cerr
|
|
|
|
|
}
|
|
|
|
|
delete(s.listeners, ln)
|
|
|
|
|
}
|
|
|
|
|
return err
|
2014-02-27 18:29:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A ConnState represents the state of a client connection to a server.
|
|
|
|
|
// It's used by the optional Server.ConnState hook.
|
|
|
|
|
type ConnState int
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
// StateNew represents a new connection that is expected to
|
|
|
|
|
// send a request immediately. Connections begin at this
|
|
|
|
|
// state and then transition to either StateActive or
|
|
|
|
|
// StateClosed.
|
|
|
|
|
StateNew ConnState = iota
|
|
|
|
|
|
|
|
|
|
// StateActive represents a connection that has read 1 or more
|
|
|
|
|
// bytes of a request. The Server.ConnState hook for
|
|
|
|
|
// StateActive fires before the request has entered a handler
|
|
|
|
|
// and doesn't fire again until the request has been
|
|
|
|
|
// handled. After the request is handled, the state
|
|
|
|
|
// transitions to StateClosed, StateHijacked, or StateIdle.
|
2016-01-13 19:36:51 +00:00
|
|
|
// For HTTP/2, StateActive fires on the transition from zero
|
|
|
|
|
// to one active request, and only transitions away once all
|
|
|
|
|
// active requests are complete. That means that ConnState
|
2016-01-27 12:49:13 -08:00
|
|
|
// cannot be used to do per-request work; ConnState only notes
|
2016-01-13 19:36:51 +00:00
|
|
|
// the overall state of the connection.
|
2014-02-27 18:29:00 -08:00
|
|
|
StateActive
|
|
|
|
|
|
|
|
|
|
// StateIdle represents a connection that has finished
|
|
|
|
|
// handling a request and is in the keep-alive state, waiting
|
|
|
|
|
// for a new request. Connections transition from StateIdle
|
|
|
|
|
// to either StateActive or StateClosed.
|
|
|
|
|
StateIdle
|
|
|
|
|
|
|
|
|
|
// StateHijacked represents a hijacked connection.
|
|
|
|
|
// This is a terminal state. It does not transition to StateClosed.
|
|
|
|
|
StateHijacked
|
|
|
|
|
|
|
|
|
|
// StateClosed represents a closed connection.
|
|
|
|
|
// This is a terminal state. Hijacked connections do not
|
|
|
|
|
// transition to StateClosed.
|
|
|
|
|
StateClosed
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var stateName = map[ConnState]string{
|
|
|
|
|
StateNew: "new",
|
|
|
|
|
StateActive: "active",
|
|
|
|
|
StateIdle: "idle",
|
|
|
|
|
StateHijacked: "hijacked",
|
|
|
|
|
StateClosed: "closed",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c ConnState) String() string {
|
|
|
|
|
return stateName[c]
|
2013-02-04 13:55:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// serverHandler delegates to either the server's Handler or
|
|
|
|
|
// DefaultServeMux and also handles "OPTIONS *" requests.
|
|
|
|
|
type serverHandler struct {
|
|
|
|
|
srv *Server
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
|
|
|
|
|
handler := sh.srv.Handler
|
|
|
|
|
if handler == nil {
|
|
|
|
|
handler = DefaultServeMux
|
|
|
|
|
}
|
|
|
|
|
if req.RequestURI == "*" && req.Method == "OPTIONS" {
|
|
|
|
|
handler = globalOptionsHandler{}
|
|
|
|
|
}
|
|
|
|
|
handler.ServeHTTP(rw, req)
|
2011-02-10 14:36:22 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ListenAndServe listens on the TCP network address srv.Addr and then
|
2015-08-20 11:56:24 +00:00
|
|
|
// calls Serve to handle requests on incoming connections.
|
2015-12-09 17:41:44 +00:00
|
|
|
// Accepted connections are configured to enable TCP keep-alives.
|
2015-08-20 11:56:24 +00:00
|
|
|
// If srv.Addr is blank, ":http" is used.
|
|
|
|
|
// ListenAndServe always returns a non-nil error.
|
2011-11-01 22:04:37 -04:00
|
|
|
func (srv *Server) ListenAndServe() error {
|
2011-02-10 14:36:22 -08:00
|
|
|
addr := srv.Addr
|
|
|
|
|
if addr == "" {
|
|
|
|
|
addr = ":http"
|
|
|
|
|
}
|
2014-01-09 15:05:09 -08:00
|
|
|
ln, err := net.Listen("tcp", addr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
2011-02-10 14:36:22 -08:00
|
|
|
}
|
2014-01-09 15:05:09 -08:00
|
|
|
return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
|
2011-02-10 14:36:22 -08:00
|
|
|
}
|
|
|
|
|
|
2015-11-03 11:00:37 -08:00
|
|
|
var testHookServerServe func(*Server, net.Listener) // used if non-nil
|
|
|
|
|
|
2016-06-27 16:39:40 -07:00
|
|
|
// shouldDoServeHTTP2 reports whether Server.Serve should configure
|
|
|
|
|
// automatic HTTP/2. (which sets up the srv.TLSNextProto map)
|
|
|
|
|
func (srv *Server) shouldConfigureHTTP2ForServe() bool {
|
|
|
|
|
if srv.TLSConfig == nil {
|
|
|
|
|
// Compatibility with Go 1.6:
|
|
|
|
|
// If there's no TLSConfig, it's possible that the user just
|
|
|
|
|
// didn't set it on the http.Server, but did pass it to
|
|
|
|
|
// tls.NewListener and passed that listener to Serve.
|
|
|
|
|
// So we should configure HTTP/2 (to set up srv.TLSNextProto)
|
|
|
|
|
// in case the listener returns an "h2" *tls.Conn.
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
// The user specified a TLSConfig on their http.Server.
|
|
|
|
|
// In this, case, only configure HTTP/2 if their tls.Config
|
|
|
|
|
// explicitly mentions "h2". Otherwise http2.ConfigureServer
|
|
|
|
|
// would modify the tls.Config to add it, but they probably already
|
|
|
|
|
// passed this tls.Config to tls.NewListener. And if they did,
|
|
|
|
|
// it's too late anyway to fix it. It would only be potentially racy.
|
|
|
|
|
// See Issue 15908.
|
|
|
|
|
return strSliceContains(srv.TLSConfig.NextProtos, http2NextProtoTLS)
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-14 08:11:07 -08:00
|
|
|
// ErrServerClosed is returned by the Server's Serve, ListenAndServe,
|
|
|
|
|
// and ListenAndServeTLS methods after a call to Shutdown or Close.
|
2016-10-30 03:28:05 +00:00
|
|
|
var ErrServerClosed = errors.New("http: Server closed")
|
|
|
|
|
|
2011-02-10 14:36:22 -08:00
|
|
|
// Serve accepts incoming connections on the Listener l, creating a
|
2015-08-20 11:56:24 +00:00
|
|
|
// new service goroutine for each. The service goroutines read requests and
|
2011-02-10 14:36:22 -08:00
|
|
|
// then call srv.Handler to reply to them.
|
2016-06-27 16:39:40 -07:00
|
|
|
//
|
|
|
|
|
// For HTTP/2 support, srv.TLSConfig should be initialized to the
|
|
|
|
|
// provided listener's TLS Config before calling Serve. If
|
|
|
|
|
// srv.TLSConfig is non-nil and doesn't include the string "h2" in
|
|
|
|
|
// Config.NextProtos, HTTP/2 support is not enabled.
|
|
|
|
|
//
|
2016-10-30 03:28:05 +00:00
|
|
|
// Serve always returns a non-nil error. After Shutdown or Close, the
|
|
|
|
|
// returned error is ErrServerClosed.
|
2011-11-01 22:04:37 -04:00
|
|
|
func (srv *Server) Serve(l net.Listener) error {
|
2011-02-10 14:36:22 -08:00
|
|
|
defer l.Close()
|
2015-11-03 11:00:37 -08:00
|
|
|
if fn := testHookServerServe; fn != nil {
|
|
|
|
|
fn(srv, l)
|
|
|
|
|
}
|
2012-02-14 15:04:29 +11:00
|
|
|
var tempDelay time.Duration // how long to sleep on accept failure
|
2016-06-27 16:39:40 -07:00
|
|
|
|
2016-07-26 23:44:00 +02:00
|
|
|
if err := srv.setupHTTP2_Serve(); err != nil {
|
|
|
|
|
return err
|
2015-10-20 22:57:12 +00:00
|
|
|
}
|
2016-06-27 16:39:40 -07:00
|
|
|
|
2016-10-30 03:28:05 +00:00
|
|
|
srv.trackListener(l, true)
|
|
|
|
|
defer srv.trackListener(l, false)
|
|
|
|
|
|
2016-09-29 19:35:43 -07:00
|
|
|
baseCtx := context.Background() // base is always background, per Issue 16220
|
2016-04-11 05:12:43 +00:00
|
|
|
ctx := context.WithValue(baseCtx, ServerContextKey, srv)
|
2008-09-24 15:26:55 -07:00
|
|
|
for {
|
2009-12-15 15:35:38 -08:00
|
|
|
rw, e := l.Accept()
|
2008-09-24 15:26:55 -07:00
|
|
|
if e != nil {
|
2016-10-30 03:28:05 +00:00
|
|
|
select {
|
|
|
|
|
case <-srv.getDoneChan():
|
|
|
|
|
return ErrServerClosed
|
|
|
|
|
default:
|
|
|
|
|
}
|
2011-06-03 12:23:50 -07:00
|
|
|
if ne, ok := e.(net.Error); ok && ne.Temporary() {
|
2012-02-14 15:04:29 +11:00
|
|
|
if tempDelay == 0 {
|
|
|
|
|
tempDelay = 5 * time.Millisecond
|
|
|
|
|
} else {
|
|
|
|
|
tempDelay *= 2
|
|
|
|
|
}
|
|
|
|
|
if max := 1 * time.Second; tempDelay > max {
|
|
|
|
|
tempDelay = max
|
|
|
|
|
}
|
2014-02-28 12:12:51 -08:00
|
|
|
srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
|
2012-02-14 15:04:29 +11:00
|
|
|
time.Sleep(tempDelay)
|
2011-06-03 12:23:50 -07:00
|
|
|
continue
|
|
|
|
|
}
|
2009-11-09 12:07:39 -08:00
|
|
|
return e
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
2012-02-14 15:04:29 +11:00
|
|
|
tempDelay = 0
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
c := srv.newConn(rw)
|
2014-03-01 20:32:42 -08:00
|
|
|
c.setState(c.rwc, StateNew) // before Serve can return
|
2016-04-11 05:12:43 +00:00
|
|
|
go c.serve(ctx)
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-30 03:28:05 +00:00
|
|
|
func (s *Server) trackListener(ln net.Listener, add bool) {
|
|
|
|
|
s.mu.Lock()
|
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
|
if s.listeners == nil {
|
|
|
|
|
s.listeners = make(map[net.Listener]struct{})
|
|
|
|
|
}
|
|
|
|
|
if add {
|
|
|
|
|
// If the *Server is being reused after a previous
|
|
|
|
|
// Close or Shutdown, reset its doneChan:
|
|
|
|
|
if len(s.listeners) == 0 && len(s.activeConn) == 0 {
|
|
|
|
|
s.doneChan = nil
|
|
|
|
|
}
|
|
|
|
|
s.listeners[ln] = struct{}{}
|
|
|
|
|
} else {
|
|
|
|
|
delete(s.listeners, ln)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) trackConn(c *conn, add bool) {
|
|
|
|
|
s.mu.Lock()
|
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
|
if s.activeConn == nil {
|
|
|
|
|
s.activeConn = make(map[*conn]struct{})
|
|
|
|
|
}
|
|
|
|
|
if add {
|
|
|
|
|
s.activeConn[c] = struct{}{}
|
|
|
|
|
} else {
|
|
|
|
|
delete(s.activeConn, c)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-23 06:04:14 -07:00
|
|
|
func (s *Server) idleTimeout() time.Duration {
|
|
|
|
|
if s.IdleTimeout != 0 {
|
|
|
|
|
return s.IdleTimeout
|
|
|
|
|
}
|
|
|
|
|
return s.ReadTimeout
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) readHeaderTimeout() time.Duration {
|
|
|
|
|
if s.ReadHeaderTimeout != 0 {
|
|
|
|
|
return s.ReadHeaderTimeout
|
|
|
|
|
}
|
|
|
|
|
return s.ReadTimeout
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-28 07:40:25 -08:00
|
|
|
func (s *Server) doKeepAlives() bool {
|
2016-10-30 03:28:05 +00:00
|
|
|
return atomic.LoadInt32(&s.disableKeepAlives) == 0 && !s.shuttingDown()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) shuttingDown() bool {
|
|
|
|
|
return atomic.LoadInt32(&s.inShutdown) != 0
|
2014-02-28 07:40:25 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
|
|
|
|
|
// By default, keep-alives are always enabled. Only very
|
|
|
|
|
// resource-constrained environments or servers in the process of
|
|
|
|
|
// shutting down should disable them.
|
2015-07-31 23:25:48 -07:00
|
|
|
func (srv *Server) SetKeepAlivesEnabled(v bool) {
|
2014-02-28 07:40:25 -08:00
|
|
|
if v {
|
2015-07-31 23:25:48 -07:00
|
|
|
atomic.StoreInt32(&srv.disableKeepAlives, 0)
|
2016-10-30 03:28:05 +00:00
|
|
|
return
|
2014-02-28 07:40:25 -08:00
|
|
|
}
|
2016-10-30 03:28:05 +00:00
|
|
|
atomic.StoreInt32(&srv.disableKeepAlives, 1)
|
|
|
|
|
|
|
|
|
|
// Close idle HTTP/1 conns:
|
|
|
|
|
srv.closeIdleConns()
|
|
|
|
|
|
|
|
|
|
// Close HTTP/2 conns, as soon as they become idle, but reset
|
|
|
|
|
// the chan so future conns (if the listener is still active)
|
|
|
|
|
// still work and don't get a GOAWAY immediately, before their
|
|
|
|
|
// first request:
|
|
|
|
|
srv.mu.Lock()
|
|
|
|
|
defer srv.mu.Unlock()
|
|
|
|
|
srv.closeDoneChanLocked() // closes http2 conns
|
|
|
|
|
srv.doneChan = nil
|
2014-02-28 07:40:25 -08:00
|
|
|
}
|
|
|
|
|
|
2014-02-28 12:12:51 -08:00
|
|
|
func (s *Server) logf(format string, args ...interface{}) {
|
|
|
|
|
if s.ErrorLog != nil {
|
|
|
|
|
s.ErrorLog.Printf(format, args...)
|
|
|
|
|
} else {
|
|
|
|
|
log.Printf(format, args...)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-11 12:51:10 -07:00
|
|
|
// ListenAndServe listens on the TCP network address addr
|
|
|
|
|
// and then calls Serve with handler to handle requests
|
2015-12-09 17:41:44 +00:00
|
|
|
// on incoming connections.
|
|
|
|
|
// Accepted connections are configured to enable TCP keep-alives.
|
|
|
|
|
// Handler is typically nil, in which case the DefaultServeMux is
|
|
|
|
|
// used.
|
2009-03-11 12:51:10 -07:00
|
|
|
//
|
|
|
|
|
// A trivial example server is:
|
|
|
|
|
//
|
|
|
|
|
// package main
|
|
|
|
|
//
|
|
|
|
|
// import (
|
2010-04-05 22:55:05 -07:00
|
|
|
// "io"
|
2011-11-18 18:33:44 -05:00
|
|
|
// "net/http"
|
2010-04-05 22:55:05 -07:00
|
|
|
// "log"
|
2009-03-11 12:51:10 -07:00
|
|
|
// )
|
|
|
|
|
//
|
|
|
|
|
// // hello world, the web server
|
2010-09-29 14:30:12 +10:00
|
|
|
// func HelloServer(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
// io.WriteString(w, "hello, world!\n")
|
2009-03-11 12:51:10 -07:00
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// func main() {
|
2010-04-05 22:55:05 -07:00
|
|
|
// http.HandleFunc("/hello", HelloServer)
|
2015-08-20 11:56:24 +00:00
|
|
|
// log.Fatal(http.ListenAndServe(":12345", nil))
|
2009-03-11 12:51:10 -07:00
|
|
|
// }
|
2015-08-20 11:56:24 +00:00
|
|
|
//
|
|
|
|
|
// ListenAndServe always returns a non-nil error.
|
2011-11-01 22:04:37 -04:00
|
|
|
func ListenAndServe(addr string, handler Handler) error {
|
2011-02-10 14:36:22 -08:00
|
|
|
server := &Server{Addr: addr, Handler: handler}
|
|
|
|
|
return server.ListenAndServe()
|
2008-09-24 15:26:55 -07:00
|
|
|
}
|
2010-07-02 13:00:18 -04:00
|
|
|
|
2010-07-02 16:43:48 -04:00
|
|
|
// ListenAndServeTLS acts identically to ListenAndServe, except that it
|
|
|
|
|
// expects HTTPS connections. Additionally, files containing a certificate and
|
2011-06-20 12:19:26 -07:00
|
|
|
// matching private key for the server must be provided. If the certificate
|
|
|
|
|
// is signed by a certificate authority, the certFile should be the concatenation
|
2015-06-24 13:57:33 +02:00
|
|
|
// of the server's certificate, any intermediates, and the CA's certificate.
|
2010-07-02 13:00:18 -04:00
|
|
|
//
|
|
|
|
|
// A trivial example server is:
|
|
|
|
|
//
|
|
|
|
|
// import (
|
|
|
|
|
// "log"
|
2011-11-18 18:33:44 -05:00
|
|
|
// "net/http"
|
2010-07-02 13:00:18 -04:00
|
|
|
// )
|
|
|
|
|
//
|
2010-09-29 14:30:12 +10:00
|
|
|
// func handler(w http.ResponseWriter, req *http.Request) {
|
2011-03-09 09:41:01 -08:00
|
|
|
// w.Header().Set("Content-Type", "text/plain")
|
2010-09-29 14:30:12 +10:00
|
|
|
// w.Write([]byte("This is an example server.\n"))
|
2010-07-02 13:00:18 -04:00
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// func main() {
|
|
|
|
|
// http.HandleFunc("/", handler)
|
log: new interface
New logging interface simplifies and generalizes.
1) Loggers now have only one output.
2) log.Stdout, Stderr, Crash and friends are gone.
Logging is now always to standard error by default.
3) log.Panic* replaces log.Crash*.
4) Exiting and panicking are not part of the logger's state; instead
the functions Exit* and Panic* simply call Exit or panic after
printing.
5) There is now one 'standard logger'. Instead of calling Stderr,
use Print etc. There are now triples, by analogy with fmt:
Print, Println, Printf
What was log.Stderr is now best represented by log.Println,
since there are now separate Print and Println functions
(and methods).
6) New functions SetOutput, SetFlags, and SetPrefix allow global
editing of the standard logger's properties. This is new
functionality. For instance, one can call
log.SetFlags(log.Lshortfile|log.Ltime|log.Lmicroseconds)
to get all logging output to show file name, line number, and
time stamp.
In short, for most purposes
log.Stderr -> log.Println or log.Print
log.Stderrf -> log.Printf
log.Crash -> log.Panicln or log.Panic
log.Crashf -> log.Panicf
log.Exit -> log.Exitln or log.Exit
log.Exitf -> log.Exitf (no change)
This has a slight breakage: since loggers now write only to one
output, existing calls to log.New() need to delete the second argument.
Also, custom loggers with exit or panic properties will need to be
reworked.
All package code updated to new interface.
The test has been reworked somewhat.
The old interface will be removed after the new release.
For now, its elements are marked 'deprecated' in their comments.
Fixes #1184.
R=rsc
CC=golang-dev
https://golang.org/cl/2419042
2010-10-12 12:59:18 -07:00
|
|
|
// log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
|
2010-08-16 11:22:22 -04:00
|
|
|
// err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
|
2015-08-20 11:56:24 +00:00
|
|
|
// log.Fatal(err)
|
2010-07-02 13:00:18 -04:00
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
|
2015-08-20 11:56:24 +00:00
|
|
|
//
|
|
|
|
|
// ListenAndServeTLS always returns a non-nil error.
|
2015-12-09 17:41:44 +00:00
|
|
|
func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
|
2011-06-20 12:19:26 -07:00
|
|
|
server := &Server{Addr: addr, Handler: handler}
|
|
|
|
|
return server.ListenAndServeTLS(certFile, keyFile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ListenAndServeTLS listens on the TCP network address srv.Addr and
|
|
|
|
|
// then calls Serve to handle requests on incoming TLS connections.
|
2015-12-09 17:41:44 +00:00
|
|
|
// Accepted connections are configured to enable TCP keep-alives.
|
2011-06-20 12:19:26 -07:00
|
|
|
//
|
2015-06-24 13:57:33 +02:00
|
|
|
// Filenames containing a certificate and matching private key for the
|
2016-02-08 23:23:36 +00:00
|
|
|
// server must be provided if neither the Server's TLSConfig.Certificates
|
|
|
|
|
// nor TLSConfig.GetCertificate are populated. If the certificate is
|
|
|
|
|
// signed by a certificate authority, the certFile should be the
|
|
|
|
|
// concatenation of the server's certificate, any intermediates, and
|
|
|
|
|
// the CA's certificate.
|
2011-06-20 12:19:26 -07:00
|
|
|
//
|
|
|
|
|
// If srv.Addr is blank, ":https" is used.
|
2015-08-20 11:56:24 +00:00
|
|
|
//
|
|
|
|
|
// ListenAndServeTLS always returns a non-nil error.
|
2012-01-30 11:58:49 -08:00
|
|
|
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
|
|
|
|
|
addr := srv.Addr
|
2011-06-20 12:19:26 -07:00
|
|
|
if addr == "" {
|
|
|
|
|
addr = ":https"
|
|
|
|
|
}
|
2015-11-03 11:00:37 -08:00
|
|
|
|
|
|
|
|
// Setup HTTP/2 before srv.Serve, to initialize srv.TLSConfig
|
|
|
|
|
// before we clone it and create the TLS Listener.
|
2016-07-26 23:44:00 +02:00
|
|
|
if err := srv.setupHTTP2_ListenAndServeTLS(); err != nil {
|
2015-11-03 11:00:37 -08:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
net/http: fix races cloning TLS config
Found in a Google program running under the race detector.
No test, but verified that this fixes the race with go run -race of:
package main
import (
"crypto/tls"
"fmt"
"net"
"net/http"
"net/http/httptest"
)
func main() {
for {
ts := httptest.NewTLSServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {}))
conf := &tls.Config{} // non-nil
a, b := net.Pipe()
go func() {
sconn := tls.Server(a, conf)
sconn.Handshake()
}()
tr := &http.Transport{
TLSClientConfig: conf,
}
req, _ := http.NewRequest("GET", ts.URL, nil)
_, err := tr.RoundTrip(req)
println(fmt.Sprint(err))
a.Close()
b.Close()
ts.Close()
}
}
Also modified cmd/vet to report the copy-of-mutex bug statically
in CL 13646, and fixed two other instances in the code found by vet.
But vet could not have told us about cloneTLSConfig vs cloneTLSClientConfig.
Confirmed that original report is also fixed by this.
Fixes #12099.
Change-Id: Iba0171549e01852a5ec3438c25a1951c98524dec
Reviewed-on: https://go-review.googlesource.com/13453
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
2015-08-11 23:22:57 +03:00
|
|
|
config := cloneTLSConfig(srv.TLSConfig)
|
2015-11-03 11:00:37 -08:00
|
|
|
if !strSliceContains(config.NextProtos, "http/1.1") {
|
|
|
|
|
config.NextProtos = append(config.NextProtos, "http/1.1")
|
2010-07-02 13:00:18 -04:00
|
|
|
}
|
|
|
|
|
|
2016-02-08 23:23:36 +00:00
|
|
|
configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil
|
|
|
|
|
if !configHasCert || certFile != "" || keyFile != "" {
|
2015-06-24 13:57:33 +02:00
|
|
|
var err error
|
|
|
|
|
config.Certificates = make([]tls.Certificate, 1)
|
|
|
|
|
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2010-07-02 13:00:18 -04:00
|
|
|
}
|
|
|
|
|
|
2014-01-09 15:05:09 -08:00
|
|
|
ln, err := net.Listen("tcp", addr)
|
2010-07-02 13:00:18 -04:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-09 15:05:09 -08:00
|
|
|
tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
|
2012-01-30 11:58:49 -08:00
|
|
|
return srv.Serve(tlsListener)
|
2010-07-02 13:00:18 -04:00
|
|
|
}
|
2011-04-15 12:53:32 -07:00
|
|
|
|
2016-07-26 23:44:00 +02:00
|
|
|
// setupHTTP2_ListenAndServeTLS conditionally configures HTTP/2 on
|
|
|
|
|
// srv and returns whether there was an error setting it up. If it is
|
|
|
|
|
// not configured for policy reasons, nil is returned.
|
|
|
|
|
func (srv *Server) setupHTTP2_ListenAndServeTLS() error {
|
2015-11-03 11:00:37 -08:00
|
|
|
srv.nextProtoOnce.Do(srv.onceSetNextProtoDefaults)
|
|
|
|
|
return srv.nextProtoErr
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-26 23:44:00 +02:00
|
|
|
// setupHTTP2_Serve is called from (*Server).Serve and conditionally
|
|
|
|
|
// configures HTTP/2 on srv using a more conservative policy than
|
|
|
|
|
// setupHTTP2_ListenAndServeTLS because Serve may be called
|
|
|
|
|
// concurrently.
|
|
|
|
|
//
|
|
|
|
|
// The tests named TestTransportAutomaticHTTP2* and
|
|
|
|
|
// TestConcurrentServerServe in server_test.go demonstrate some
|
|
|
|
|
// of the supported use cases and motivations.
|
|
|
|
|
func (srv *Server) setupHTTP2_Serve() error {
|
|
|
|
|
srv.nextProtoOnce.Do(srv.onceSetNextProtoDefaults_Serve)
|
|
|
|
|
return srv.nextProtoErr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (srv *Server) onceSetNextProtoDefaults_Serve() {
|
|
|
|
|
if srv.shouldConfigureHTTP2ForServe() {
|
|
|
|
|
srv.onceSetNextProtoDefaults()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-03 11:00:37 -08:00
|
|
|
// onceSetNextProtoDefaults configures HTTP/2, if the user hasn't
|
|
|
|
|
// configured otherwise. (by setting srv.TLSNextProto non-nil)
|
2016-07-26 23:44:00 +02:00
|
|
|
// It must only be called via srv.nextProtoOnce (use srv.setupHTTP2_*).
|
2015-11-03 11:00:37 -08:00
|
|
|
func (srv *Server) onceSetNextProtoDefaults() {
|
2016-01-07 23:43:52 +00:00
|
|
|
if strings.Contains(os.Getenv("GODEBUG"), "http2server=0") {
|
|
|
|
|
return
|
|
|
|
|
}
|
2015-10-14 20:41:36 +00:00
|
|
|
// Enable HTTP/2 by default if the user hasn't otherwise
|
|
|
|
|
// configured their TLSNextProto map.
|
|
|
|
|
if srv.TLSNextProto == nil {
|
2015-10-20 22:57:12 +00:00
|
|
|
srv.nextProtoErr = http2ConfigureServer(srv, nil)
|
2015-10-14 20:41:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-15 12:53:32 -07:00
|
|
|
// TimeoutHandler returns a Handler that runs h with the given time limit.
|
|
|
|
|
//
|
|
|
|
|
// The new Handler calls h.ServeHTTP to handle each request, but if a
|
2013-01-03 10:06:04 -08:00
|
|
|
// call runs for longer than its time limit, the handler responds with
|
2011-04-15 12:53:32 -07:00
|
|
|
// a 503 Service Unavailable error and the given message in its body.
|
|
|
|
|
// (If msg is empty, a suitable default message will be sent.)
|
|
|
|
|
// After such a timeout, writes by h to its ResponseWriter will return
|
|
|
|
|
// ErrHandlerTimeout.
|
2015-12-14 01:04:07 +00:00
|
|
|
//
|
|
|
|
|
// TimeoutHandler buffers all Handler writes to memory and does not
|
|
|
|
|
// support the Hijacker or Flusher interfaces.
|
2011-11-30 12:01:46 -05:00
|
|
|
func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
|
2015-12-14 01:04:07 +00:00
|
|
|
return &timeoutHandler{
|
|
|
|
|
handler: h,
|
|
|
|
|
body: msg,
|
2016-02-29 12:06:57 -03:00
|
|
|
dt: dt,
|
2011-04-15 12:53:32 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErrHandlerTimeout is returned on ResponseWriter Write calls
|
|
|
|
|
// in handlers which have timed out.
|
2011-11-01 22:04:37 -04:00
|
|
|
var ErrHandlerTimeout = errors.New("http: Handler timeout")
|
2011-04-15 12:53:32 -07:00
|
|
|
|
|
|
|
|
type timeoutHandler struct {
|
|
|
|
|
handler Handler
|
|
|
|
|
body string
|
2016-02-29 12:06:57 -03:00
|
|
|
dt time.Duration
|
2015-12-14 01:04:07 +00:00
|
|
|
|
2016-02-29 12:06:57 -03:00
|
|
|
// When set, no timer will be created and this channel will
|
|
|
|
|
// be used instead.
|
|
|
|
|
testTimeout <-chan time.Time
|
2011-04-15 12:53:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *timeoutHandler) errorBody() string {
|
|
|
|
|
if h.body != "" {
|
|
|
|
|
return h.body
|
|
|
|
|
}
|
|
|
|
|
return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
|
2016-02-29 12:06:57 -03:00
|
|
|
var t *time.Timer
|
|
|
|
|
timeout := h.testTimeout
|
|
|
|
|
if timeout == nil {
|
|
|
|
|
t = time.NewTimer(h.dt)
|
|
|
|
|
timeout = t.C
|
|
|
|
|
}
|
2015-12-14 01:04:07 +00:00
|
|
|
done := make(chan struct{})
|
|
|
|
|
tw := &timeoutWriter{
|
|
|
|
|
w: w,
|
|
|
|
|
h: make(Header),
|
|
|
|
|
}
|
2011-04-15 12:53:32 -07:00
|
|
|
go func() {
|
|
|
|
|
h.handler.ServeHTTP(tw, r)
|
2015-12-14 01:04:07 +00:00
|
|
|
close(done)
|
2011-04-15 12:53:32 -07:00
|
|
|
}()
|
|
|
|
|
select {
|
|
|
|
|
case <-done:
|
|
|
|
|
tw.mu.Lock()
|
|
|
|
|
defer tw.mu.Unlock()
|
2015-12-14 01:04:07 +00:00
|
|
|
dst := w.Header()
|
|
|
|
|
for k, vv := range tw.h {
|
|
|
|
|
dst[k] = vv
|
2011-04-15 12:53:32 -07:00
|
|
|
}
|
2016-06-06 10:23:49 +10:00
|
|
|
if !tw.wroteHeader {
|
|
|
|
|
tw.code = StatusOK
|
|
|
|
|
}
|
2015-12-14 01:04:07 +00:00
|
|
|
w.WriteHeader(tw.code)
|
|
|
|
|
w.Write(tw.wbuf.Bytes())
|
2016-02-29 12:06:57 -03:00
|
|
|
if t != nil {
|
|
|
|
|
t.Stop()
|
2015-12-14 01:04:07 +00:00
|
|
|
}
|
2016-02-29 12:06:57 -03:00
|
|
|
case <-timeout:
|
2015-12-14 01:04:07 +00:00
|
|
|
tw.mu.Lock()
|
|
|
|
|
defer tw.mu.Unlock()
|
|
|
|
|
w.WriteHeader(StatusServiceUnavailable)
|
|
|
|
|
io.WriteString(w, h.errorBody())
|
2011-04-15 12:53:32 -07:00
|
|
|
tw.timedOut = true
|
2015-12-14 01:04:07 +00:00
|
|
|
return
|
2011-04-15 12:53:32 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type timeoutWriter struct {
|
2015-12-14 01:04:07 +00:00
|
|
|
w ResponseWriter
|
|
|
|
|
h Header
|
|
|
|
|
wbuf bytes.Buffer
|
2011-04-15 12:53:32 -07:00
|
|
|
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
timedOut bool
|
|
|
|
|
wroteHeader bool
|
2015-12-14 01:04:07 +00:00
|
|
|
code int
|
2011-04-15 12:53:32 -07:00
|
|
|
}
|
|
|
|
|
|
2015-12-14 01:04:07 +00:00
|
|
|
func (tw *timeoutWriter) Header() Header { return tw.h }
|
2011-04-15 12:53:32 -07:00
|
|
|
|
2011-11-01 22:04:37 -04:00
|
|
|
func (tw *timeoutWriter) Write(p []byte) (int, error) {
|
2011-04-15 12:53:32 -07:00
|
|
|
tw.mu.Lock()
|
2014-08-19 18:45:05 -07:00
|
|
|
defer tw.mu.Unlock()
|
|
|
|
|
if tw.timedOut {
|
2011-04-15 12:53:32 -07:00
|
|
|
return 0, ErrHandlerTimeout
|
|
|
|
|
}
|
2015-12-14 01:04:07 +00:00
|
|
|
if !tw.wroteHeader {
|
|
|
|
|
tw.writeHeader(StatusOK)
|
|
|
|
|
}
|
|
|
|
|
return tw.wbuf.Write(p)
|
2011-04-15 12:53:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (tw *timeoutWriter) WriteHeader(code int) {
|
|
|
|
|
tw.mu.Lock()
|
2014-08-19 18:45:05 -07:00
|
|
|
defer tw.mu.Unlock()
|
2011-04-15 12:53:32 -07:00
|
|
|
if tw.timedOut || tw.wroteHeader {
|
|
|
|
|
return
|
|
|
|
|
}
|
2015-12-14 01:04:07 +00:00
|
|
|
tw.writeHeader(code)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (tw *timeoutWriter) writeHeader(code int) {
|
2011-04-15 12:53:32 -07:00
|
|
|
tw.wroteHeader = true
|
2015-12-14 01:04:07 +00:00
|
|
|
tw.code = code
|
2011-04-15 12:53:32 -07:00
|
|
|
}
|
net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
2012-11-26 13:31:02 -08:00
|
|
|
|
2014-01-09 15:05:09 -08:00
|
|
|
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
|
|
|
|
|
// connections. It's used by ListenAndServe and ListenAndServeTLS so
|
|
|
|
|
// dead TCP connections (e.g. closing laptop mid-download) eventually
|
|
|
|
|
// go away.
|
|
|
|
|
type tcpKeepAliveListener struct {
|
|
|
|
|
*net.TCPListener
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
|
|
|
|
|
tc, err := ln.AcceptTCP()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
tc.SetKeepAlive(true)
|
|
|
|
|
tc.SetKeepAlivePeriod(3 * time.Minute)
|
|
|
|
|
return tc, nil
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-11 12:07:27 -05:00
|
|
|
// globalOptionsHandler responds to "OPTIONS *" requests.
|
|
|
|
|
type globalOptionsHandler struct{}
|
|
|
|
|
|
|
|
|
|
func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
|
|
|
|
|
w.Header().Set("Content-Length", "0")
|
|
|
|
|
if r.ContentLength != 0 {
|
|
|
|
|
// Read up to 4KB of OPTIONS body (as mentioned in the
|
|
|
|
|
// spec as being reserved for future use), but anything
|
|
|
|
|
// over that is considered a waste of server resources
|
|
|
|
|
// (or an attack) and we abort and close the connection,
|
|
|
|
|
// courtesy of MaxBytesReader's EOF behavior.
|
|
|
|
|
mb := MaxBytesReader(w, r.Body, 4<<10)
|
|
|
|
|
io.Copy(ioutil.Discard, mb)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-04 13:55:38 -08:00
|
|
|
// initNPNRequest is an HTTP handler that initializes certain
|
|
|
|
|
// uninitialized fields in its *Request. Such partially-initialized
|
|
|
|
|
// Requests come from NPN protocol handlers.
|
|
|
|
|
type initNPNRequest struct {
|
|
|
|
|
c *tls.Conn
|
|
|
|
|
h serverHandler
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h initNPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
|
|
|
|
|
if req.TLS == nil {
|
|
|
|
|
req.TLS = &tls.ConnectionState{}
|
|
|
|
|
*req.TLS = h.c.ConnectionState()
|
|
|
|
|
}
|
|
|
|
|
if req.Body == nil {
|
2016-10-22 09:47:05 -07:00
|
|
|
req.Body = NoBody
|
2013-02-04 13:55:38 -08:00
|
|
|
}
|
|
|
|
|
if req.RemoteAddr == "" {
|
|
|
|
|
req.RemoteAddr = h.c.RemoteAddr().String()
|
|
|
|
|
}
|
|
|
|
|
h.h.ServeHTTP(rw, req)
|
|
|
|
|
}
|
|
|
|
|
|
net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
2012-11-26 13:31:02 -08:00
|
|
|
// loggingConn is used for debugging.
|
|
|
|
|
type loggingConn struct {
|
|
|
|
|
name string
|
|
|
|
|
net.Conn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
uniqNameMu sync.Mutex
|
|
|
|
|
uniqNameNext = make(map[string]int)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func newLoggingConn(baseName string, c net.Conn) net.Conn {
|
|
|
|
|
uniqNameMu.Lock()
|
|
|
|
|
defer uniqNameMu.Unlock()
|
|
|
|
|
uniqNameNext[baseName]++
|
|
|
|
|
return &loggingConn{
|
|
|
|
|
name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
|
|
|
|
|
Conn: c,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *loggingConn) Write(p []byte) (n int, err error) {
|
|
|
|
|
log.Printf("%s.Write(%d) = ....", c.name, len(p))
|
|
|
|
|
n, err = c.Conn.Write(p)
|
|
|
|
|
log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *loggingConn) Read(p []byte) (n int, err error) {
|
|
|
|
|
log.Printf("%s.Read(%d) = ....", c.name, len(p))
|
|
|
|
|
n, err = c.Conn.Read(p)
|
|
|
|
|
log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *loggingConn) Close() (err error) {
|
|
|
|
|
log.Printf("%s.Close() = ...", c.name)
|
|
|
|
|
err = c.Conn.Close()
|
|
|
|
|
log.Printf("%s.Close() = %v", c.name, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
2014-10-15 17:51:12 +02:00
|
|
|
|
|
|
|
|
// checkConnErrorWriter writes to c.rwc and records any write errors to c.werr.
|
|
|
|
|
// It only contains one field (and a pointer field at that), so it
|
|
|
|
|
// fits in an interface value without an extra allocation.
|
|
|
|
|
type checkConnErrorWriter struct {
|
|
|
|
|
c *conn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
|
net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads. The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-01 19:07:41 +00:00
|
|
|
n, err = w.c.rwc.Write(p)
|
2014-10-15 17:51:12 +02:00
|
|
|
if err != nil && w.c.werr == nil {
|
|
|
|
|
w.c.werr = err
|
2016-10-14 11:45:59 +01:00
|
|
|
w.c.cancelCtx()
|
2014-10-15 17:51:12 +02:00
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2015-06-25 11:31:37 +02:00
|
|
|
|
|
|
|
|
func numLeadingCRorLF(v []byte) (n int) {
|
|
|
|
|
for _, b := range v {
|
|
|
|
|
if b == '\r' || b == '\n' {
|
|
|
|
|
n++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
}
|
2015-11-03 11:00:37 -08:00
|
|
|
|
|
|
|
|
func strSliceContains(ss []string, s string) bool {
|
|
|
|
|
for _, v := range ss {
|
|
|
|
|
if v == s {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|