1// Copyright 2009 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45// HTTP server. See RFC 7230 through 7235.67package http89import (10 "bufio"11 "bytes"12 "context"13 "crypto/tls"14 "errors"15 "fmt"16 "internal/godebug"17 "io"18 "log"19 "maps"20 "math/rand/v2"21 "net"22 "net/http/internal"23 "net/textproto"24 "net/url"25 urlpkg "net/url"26 "path"27 "runtime"28 "slices"29 "strconv"30 "strings"31 "sync"32 "sync/atomic"33 "time"34 _ "unsafe" // for linkname3536 "golang.org/x/net/http/httpguts"37)3839// Errors used by the HTTP server.40var (41 // ErrBodyNotAllowed is returned by ResponseWriter.Write calls42 // when the HTTP method or response code does not permit a43 // body.44 ErrBodyNotAllowed = internal.ErrBodyNotAllowed4546 // ErrHijacked is returned by ResponseWriter.Write calls when47 // the underlying connection has been hijacked using the48 // Hijacker interface. A zero-byte write on a hijacked49 // connection will return ErrHijacked without any other side50 // effects.51 ErrHijacked = errors.New("http: connection has been hijacked")5253 // ErrContentLength is returned by ResponseWriter.Write calls54 // when a Handler set a Content-Length response header with a55 // declared size and then attempted to write more bytes than56 // declared.57 ErrContentLength = errors.New("http: wrote more than the declared Content-Length")5859 // Deprecated: ErrWriteAfterFlush is no longer returned by60 // anything in the net/http package. Callers should not61 // compare errors against this variable.62 ErrWriteAfterFlush = errors.New("unused")63)6465// A Handler responds to an HTTP request.66//67// [Handler.ServeHTTP] should write reply headers and data to the [ResponseWriter]68// and then return. Returning signals that the request is finished; it69// is not valid to use the [ResponseWriter] or read from the70// [Request.Body] after or concurrently with the completion of the71// ServeHTTP call.72//73// Depending on the HTTP client software, HTTP protocol version, and74// any intermediaries between the client and the Go server, it may not75// be possible to read from the [Request.Body] after writing to the76// [ResponseWriter]. Cautious handlers should read the [Request.Body]77// first, and then reply.78//79// Except for reading the body, handlers should not modify the80// provided Request.81//82// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes83// that the effect of the panic was isolated to the active request.84// It recovers the panic, logs a stack trace to the server error log,85// and either closes the network connection or sends an HTTP/286// RST_STREAM, depending on the HTTP protocol. To abort a handler so87// the client sees an interrupted response but the server doesn't log88// an error, panic with the value [ErrAbortHandler].89type Handler interface {90 ServeHTTP(ResponseWriter, *Request)91}9293// A ResponseWriter interface is used by an HTTP handler to94// construct an HTTP response.95//96// A ResponseWriter may not be used after [Handler.ServeHTTP] has returned.97type ResponseWriter interface {98 // Header returns the header map that will be sent by99 // [ResponseWriter.WriteHeader]. The [Header] map also is the mechanism with which100 // [Handler] implementations can set HTTP trailers.101 //102 // Changing the header map after a call to [ResponseWriter.WriteHeader] (or103 // [ResponseWriter.Write]) has no effect unless the HTTP status code was of the104 // 1xx class or the modified headers are trailers.105 //106 // There are two ways to set Trailers. The preferred way is to107 // predeclare in the headers which trailers you will later108 // send by setting the "Trailer" header to the names of the109 // trailer keys which will come later. In this case, those110 // keys of the Header map are treated as if they were111 // trailers. See the example. The second way, for trailer112 // keys not known to the [Handler] until after the first [ResponseWriter.Write],113 // is to prefix the [Header] map keys with the [TrailerPrefix]114 // constant value.115 //116 // To suppress automatic response headers (such as "Date"), set117 // their value to nil.118 Header() Header119120 // Write writes the data to the connection as part of an HTTP reply.121 //122 // If [ResponseWriter.WriteHeader] has not yet been called, Write calls123 // WriteHeader(http.StatusOK) before writing the data. If the Header124 // does not contain a Content-Type line, Write adds a Content-Type set125 // to the result of passing the initial 512 bytes of written data to126 // [DetectContentType]. Additionally, if the total size of all written127 // data is under a few KB and there are no Flush calls, the128 // Content-Length header is added automatically.129 //130 // Depending on the HTTP protocol version and the client, calling131 // Write or WriteHeader may prevent future reads on the132 // Request.Body. For HTTP/1.x requests, handlers should read any133 // needed request body data before writing the response. Once the134 // headers have been flushed (due to either an explicit Flusher.Flush135 // call or writing enough data to trigger a flush), the request body136 // may be unavailable. For HTTP/2 requests, the Go HTTP server permits137 // handlers to continue to read the request body while concurrently138 // writing the response. However, such behavior may not be supported139 // by all HTTP/2 clients. Handlers should read before writing if140 // possible to maximize compatibility.141 Write([]byte) (int, error)142143 // WriteHeader sends an HTTP response header with the provided144 // status code.145 //146 // If WriteHeader is not called explicitly, the first call to Write147 // will trigger an implicit WriteHeader(http.StatusOK).148 // Thus explicit calls to WriteHeader are mainly used to149 // send error codes or 1xx informational responses.150 //151 // The provided code must be a valid HTTP 1xx-5xx status code.152 // Any number of 1xx headers may be written, followed by at most153 // one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx154 // headers may be buffered. Use the Flusher interface to send155 // buffered data. The header map is cleared when 2xx-5xx headers are156 // sent, but not with 1xx headers.157 //158 // The server will automatically send a 100 (Continue) header159 // on the first read from the request body if the request has160 // an "Expect: 100-continue" header.161 WriteHeader(statusCode int)162}163164// The Flusher interface is implemented by ResponseWriters that allow165// an HTTP handler to flush buffered data to the client.166//167// The default HTTP/1.x and HTTP/2 [ResponseWriter] implementations168// support [Flusher], but ResponseWriter wrappers may not. Handlers169// should always test for this ability at runtime.170//171// Note that even for ResponseWriters that support Flush,172// if the client is connected through an HTTP proxy,173// the buffered data may not reach the client until the response174// completes.175type Flusher interface {176 // Flush sends any buffered data to the client.177 Flush()178}179180// The Hijacker interface is implemented by ResponseWriters that allow181// an HTTP handler to take over the connection.182//183// The default [ResponseWriter] for HTTP/1.x connections supports184// Hijacker, but HTTP/2 connections intentionally do not.185// ResponseWriter wrappers may also not support Hijacker. Handlers186// should always test for this ability at runtime.187type Hijacker interface {188 // Hijack lets the caller take over the connection.189 // After a call to Hijack the HTTP server library190 // will not do anything else with the connection.191 //192 // It becomes the caller's responsibility to manage193 // and close the connection.194 //195 // The returned net.Conn may have read or write deadlines196 // already set, depending on the configuration of the197 // Server. It is the caller's responsibility to set198 // or clear those deadlines as needed.199 //200 // The returned bufio.Reader may contain unprocessed buffered201 // data from the client.202 //203 // After a call to Hijack, the original Request.Body must not204 // be used. The original Request's Context remains valid and205 // is not canceled until the Request's ServeHTTP method206 // returns.207 Hijack() (net.Conn, *bufio.ReadWriter, error)208}209210// The CloseNotifier interface is implemented by ResponseWriters which211// allow detecting when the underlying connection has gone away.212//213// This mechanism can be used to cancel long operations on the server214// if the client has disconnected before the response is ready.215//216// Deprecated: the CloseNotifier interface predates Go's context package.217// New code should use [Request.Context] instead.218type CloseNotifier interface {219 // CloseNotify returns a channel that receives at most a220 // single value (true) when the client connection has gone221 // away.222 //223 // CloseNotify may wait to notify until Request.Body has been224 // fully read.225 //226 // After the Handler has returned, there is no guarantee227 // that the channel receives a value.228 //229 // If the protocol is HTTP/1.1 and CloseNotify is called while230 // processing an idempotent request (such as GET) while231 // HTTP/1.1 pipelining is in use, the arrival of a subsequent232 // pipelined request may cause a value to be sent on the233 // returned channel. In practice HTTP/1.1 pipelining is not234 // enabled in browsers and not seen often in the wild. If this235 // is a problem, use HTTP/2 or only use CloseNotify on methods236 // such as POST.237 CloseNotify() <-chan bool238}239240var (241 // ServerContextKey is a context key. It can be used in HTTP242 // handlers with Context.Value to access the server that243 // started the handler. The associated value will be of244 // type *Server.245 ServerContextKey = &contextKey{"http-server"}246247 // LocalAddrContextKey is a context key. It can be used in248 // HTTP handlers with Context.Value to access the local249 // address the connection arrived on.250 // The associated value will be of type net.Addr.251 LocalAddrContextKey = &contextKey{"local-addr"}252)253254// A conn represents the server side of an HTTP connection.255type conn struct {256 // server is the server on which the connection arrived.257 // Immutable; never nil.258 server *Server259260 // cancelCtx cancels the connection-level context.261 cancelCtx context.CancelFunc262263 // rwc is the underlying network connection.264 // This is never wrapped by other types and is the value given out265 // to [Hijacker] callers. It is usually of type *net.TCPConn or266 // *tls.Conn.267 rwc net.Conn268269 // remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously270 // inside the Listener's Accept goroutine, as some implementations block.271 // It is populated immediately inside the (*conn).serve goroutine.272 // This is the value of a Handler's (*Request).RemoteAddr.273 remoteAddr string274275 // tlsState is the TLS connection state when using TLS.276 // nil means not TLS.277 tlsState *tls.ConnectionState278279 // werr is set to the first write error to rwc.280 // It is set via checkConnErrorWriter{w}, where bufw writes.281 werr error282283 // r is bufr's read source. It's a wrapper around rwc that provides284 // io.LimitedReader-style limiting (while reading request headers)285 // and functionality to support CloseNotifier. See *connReader docs.286 r *connReader287288 // bufr reads from r.289 bufr *bufio.Reader290291 // bufw writes to checkConnErrorWriter{c}, which populates werr on error.292 bufw *bufio.Writer293294 // lastMethod is the method of the most recent request295 // on this connection, if any.296 lastMethod string297298 curReq atomic.Pointer[response] // (which has a Request in it)299300 curState atomic.Uint64 // packed (unixtime<<8|uint8(ConnState))301302 // mu guards hijackedv303 mu sync.Mutex304305 // hijackedv is whether this connection has been hijacked306 // by a Handler with the Hijacker interface.307 // It is guarded by mu.308 hijackedv bool309}310311func (c *conn) hijacked() bool {312 c.mu.Lock()313 defer c.mu.Unlock()314 return c.hijackedv315}316317// c.mu must be held.318func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {319 if c.hijackedv {320 return nil, nil, ErrHijacked321 }322 c.r.abortPendingRead()323324 c.hijackedv = true325 rwc = c.rwc326 rwc.SetDeadline(time.Time{})327328 if c.r.hasByte {329 if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {330 return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)331 }332 }333 c.bufw.Reset(rwc)334 buf = bufio.NewReadWriter(c.bufr, c.bufw)335336 c.setState(rwc, StateHijacked, runHooks)337 return338}339340// This should be >= 512 bytes for DetectContentType,341// but otherwise it's somewhat arbitrary.342const bufferBeforeChunkingSize = 2048343344// chunkWriter writes to a response's conn buffer, and is the writer345// wrapped by the response.w buffered writer.346//347// chunkWriter also is responsible for finalizing the Header, including348// conditionally setting the Content-Type and setting a Content-Length349// in cases where the handler's final output is smaller than the buffer350// size. It also conditionally adds chunk headers, when in chunking mode.351//352// See the comment above (*response).Write for the entire write flow.353type chunkWriter struct {354 res *response355356 // header is either nil or a deep clone of res.handlerHeader357 // at the time of res.writeHeader, if res.writeHeader is358 // called and extra buffering is being done to calculate359 // Content-Type and/or Content-Length.360 header Header361362 // wroteHeader tells whether the header's been written to "the363 // wire" (or rather: w.conn.buf). this is unlike364 // (*response).wroteHeader, which tells only whether it was365 // logically written.366 wroteHeader bool367368 // set by the writeHeader method:369 chunking bool // using chunked transfer encoding for reply body370}371372var (373 crlf = []byte("\r\n")374 colonSpace = []byte(": ")375)376377func (cw *chunkWriter) Write(p []byte) (n int, err error) {378 if !cw.wroteHeader {379 cw.writeHeader(p)380 }381 if cw.res.req.Method == "HEAD" {382 // Eat writes.383 return len(p), nil384 }385 if cw.chunking {386 _, err = fmt.Fprintf(cw.res.conn.bufw, "%x\r\n", len(p))387 if err != nil {388 cw.res.conn.rwc.Close()389 return390 }391 }392 n, err = cw.res.conn.bufw.Write(p)393 if cw.chunking && err == nil {394 _, err = cw.res.conn.bufw.Write(crlf)395 }396 if err != nil {397 cw.res.conn.rwc.Close()398 }399 return400}401402func (cw *chunkWriter) flush() error {403 if !cw.wroteHeader {404 cw.writeHeader(nil)405 }406 return cw.res.conn.bufw.Flush()407}408409func (cw *chunkWriter) close() {410 if !cw.wroteHeader {411 cw.writeHeader(nil)412 }413 if cw.chunking {414 bw := cw.res.conn.bufw // conn's bufio writer415 // zero chunk to mark EOF416 bw.WriteString("0\r\n")417 if trailers := cw.res.finalTrailers(); trailers != nil {418 trailers.Write(bw) // the writer handles noting errors419 }420 // final blank line after the trailers (whether421 // present or not)422 bw.WriteString("\r\n")423 }424}425426// A response represents the server side of an HTTP response.427type response struct {428 conn *conn429 req *Request // request for this response430 reqBody *body // nil when NoBody431 cancelCtx context.CancelFunc // when ServeHTTP exits432 wroteHeader bool // a non-1xx header has been (logically) written433 wants10KeepAlive bool // HTTP/1.0 w/ Connection "keep-alive"434 wantsClose bool // HTTP request has Connection "close"435 ecReader *expectContinueReader436437 // canWriteContinue is an atomic boolean that says whether or438 // not a 100 Continue header can be written to the439 // connection.440 // writeContinueMu must be held while writing the header.441 // These two fields together synchronize the body reader (the442 // expectContinueReader, which wants to write 100 Continue)443 // against the main writer.444 writeContinueMu sync.Mutex445 canWriteContinue atomic.Bool446447 w *bufio.Writer // buffers output in chunks to chunkWriter448 cw chunkWriter449450 // handlerHeader is the Header that Handlers get access to,451 // which may be retained and mutated even after WriteHeader.452 // handlerHeader is copied into cw.header at WriteHeader453 // time, and privately mutated thereafter.454 handlerHeader Header455 calledHeader bool // handler accessed handlerHeader via Header456457 written int64 // number of bytes written in body458 contentLength int64 // explicitly-declared Content-Length; or -1459 status int // status code passed to WriteHeader460461 // close connection after this reply. set on request and462 // updated after response from handler if there's a463 // "Connection: keep-alive" response header and a464 // Content-Length.465 closeAfterReply bool466467 // When fullDuplex is false (the default), we consume any remaining468 // request body before starting to write a response.469 fullDuplex bool470471 // requestBodyLimitHit is set by requestTooLarge when472 // maxBytesReader hits its max size. It is checked in473 // WriteHeader, to make sure we don't consume the474 // remaining request body to try to advance to the next HTTP475 // request. Instead, when this is set, we stop reading476 // subsequent requests on this connection and stop reading477 // input from it.478 requestBodyLimitHit bool479480 // trailers are the headers to be sent after the handler481 // finishes writing the body. This field is initialized from482 // the Trailer response header when the response header is483 // written.484 trailers []string485486 handlerDone atomic.Bool // set true when the handler exits487488 // Buffers for Date, Content-Length, and status code489 dateBuf [len(TimeFormat)]byte490 clenBuf [10]byte491 statusBuf [3]byte492493 // lazyCloseNotifyMu protects closeNotifyCh and closeNotifyTriggered.494 lazyCloseNotifyMu sync.Mutex495 // closeNotifyCh is the channel returned by CloseNotify.496 closeNotifyCh chan bool497 // closeNotifyTriggered tracks prior closeNotify calls.498 closeNotifyTriggered bool499}500501func (c *response) SetReadDeadline(deadline time.Time) error {502 return c.conn.rwc.SetReadDeadline(deadline)503}504505func (c *response) SetWriteDeadline(deadline time.Time) error {506 return c.conn.rwc.SetWriteDeadline(deadline)507}508509func (c *response) EnableFullDuplex() error {510 c.fullDuplex = true511 return nil512}513514// TrailerPrefix is a magic prefix for [ResponseWriter.Header] map keys515// that, if present, signals that the map entry is actually for516// the response trailers, and not the response headers. The prefix517// is stripped after the ServeHTTP call finishes and the values are518// sent in the trailers.519//520// This mechanism is intended only for trailers that are not known521// prior to the headers being written. If the set of trailers is fixed522// or known before the header is written, the normal Go trailers mechanism523// is preferred:524//525// https://pkg.go.dev/net/http#ResponseWriter526// https://pkg.go.dev/net/http#example-ResponseWriter-Trailers527const TrailerPrefix = "Trailer:"528529// finalTrailers is called after the Handler exits and returns a non-nil530// value if the Handler set any trailers.531func (w *response) finalTrailers() Header {532 var t Header533 for k, vv := range w.handlerHeader {534 if kk, found := strings.CutPrefix(k, TrailerPrefix); found {535 if t == nil {536 t = make(Header)537 }538 t[kk] = vv539 }540 }541 for _, k := range w.trailers {542 if t == nil {543 t = make(Header)544 }545 for _, v := range w.handlerHeader[k] {546 t.Add(k, v)547 }548 }549 return t550}551552// declareTrailer is called for each Trailer header when the553// response header is written. It notes that a header will need to be554// written in the trailers at the end of the response.555func (w *response) declareTrailer(k string) {556 k = CanonicalHeaderKey(k)557 if !httpguts.ValidTrailerHeader(k) {558 // Forbidden by RFC 7230, section 4.1.2559 return560 }561 w.trailers = append(w.trailers, k)562}563564// requestTooLarge is called by maxBytesReader when too much input has565// been read from the client.566func (w *response) requestTooLarge() {567 w.closeAfterReply = true568 w.requestBodyLimitHit = true569 if !w.wroteHeader {570 w.Header().Set("Connection", "close")571 }572}573574// disableWriteContinue stops Request.Body.Read from sending an automatic575// 100 Continue. As the name implies, it is only useful when the request576// expects a 100 Continue and the body is wrapped in an expectContinueReader;577// otherwise, it is a no-op.578// If a 100-Continue is being written, it waits for it to complete before579// continuing. If skipDrain is true, it also prevents the server from draining580// the request body and flags the connection to be closed after the reply, as581// the client will never send the body.582func (w *response) disableWriteContinue(skipDrain bool) {583 if w.ecReader == nil {584 return585 }586 w.writeContinueMu.Lock()587 if w.canWriteContinue.Load() {588 w.canWriteContinue.Store(false)589 if skipDrain {590 // Make sure that the connection will not be reused by sending591 // "Connection: close" header in the response.592 w.closeAfterReply = true593 // Ensure that the body will not be drained in Close.594 w.ecReader.closed.Store(true)595 }596 }597 w.writeContinueMu.Unlock()598}599600// writerOnly hides an io.Writer value's optional ReadFrom method601// from io.Copy.602type writerOnly struct {603 io.Writer604}605606// ReadFrom is here to optimize copying from an [*os.File] regular file607// to a [*net.TCPConn] with sendfile, or from a supported src type such608// as a *net.TCPConn on Linux with splice.609func (w *response) ReadFrom(src io.Reader) (n int64, err error) {610 buf := getCopyBuf()611 defer putCopyBuf(buf)612613 // Our underlying w.conn.rwc is usually a *TCPConn (with its614 // own ReadFrom method). If not, just fall back to the normal615 // copy method.616 rf, ok := w.conn.rwc.(io.ReaderFrom)617 if !ok {618 return io.CopyBuffer(writerOnly{w}, src, buf)619 }620621 // Copy the first sniffLen bytes before switching to ReadFrom.622 // This ensures we don't start writing the response before the623 // source is available (see golang.org/issue/5660) and provides624 // enough bytes to perform Content-Type sniffing when required.625 if !w.cw.wroteHeader {626 n0, err := io.CopyBuffer(writerOnly{w}, io.LimitReader(src, internal.SniffLen), buf)627 n += n0628 if err != nil || n0 < internal.SniffLen {629 return n, err630 }631 }632633 w.w.Flush() // get rid of any previous writes634 w.cw.flush() // make sure Header is written; flush data to rwc635636 // Now that cw has been flushed, its chunking field is guaranteed initialized.637 if !w.cw.chunking && w.bodyAllowed() && w.req.Method != "HEAD" {638 // When a content length is declared, but exceeded; any excess bytes639 // from src should be ignored, and ErrContentLength should be returned.640 // This mirrors the behavior of response.Write.641 if w.contentLength != -1 {642 defer func(originalReader io.Reader) {643 if w.written != w.contentLength {644 return645 }646 if n, _ := originalReader.Read([]byte{0}); err == nil && n != 0 {647 err = ErrContentLength648 }649 }(src)650 // src can be an io.LimitedReader already. To avoid unnecessary651 // alloc and having to unnest readers repeatedly in net.sendFile,652 // just adjust the existing LimitedReader N when this is the case.653 if lr, ok := src.(*io.LimitedReader); ok {654 if lenDiff := lr.N - (w.contentLength - w.written); lenDiff > 0 {655 defer func() { lr.N += lenDiff }()656 lr.N -= lenDiff657 }658 } else {659 src = io.LimitReader(src, w.contentLength-w.written)660 }661 }662 n0, err := rf.ReadFrom(src)663 n += n0664 w.written += n0665 return n, err666 }667668 n0, err := io.CopyBuffer(writerOnly{w}, src, buf)669 n += n0670 return n, err671}672673// debugServerConnections controls whether all server connections are wrapped674// with a verbose logging wrapper.675const debugServerConnections = false676677// Create new connection from rwc.678func (s *Server) newConn(rwc net.Conn) *conn {679 c := &conn{680 server: s,681 rwc: rwc,682 }683 if debugServerConnections {684 c.rwc = newLoggingConn("server", c.rwc)685 }686 return c687}688689type readResult struct {690 _ incomparable691 n int692 err error693 b byte // byte read, if n == 1694}695696// connReader is the io.Reader wrapper used by *conn. It combines a697// selectively-activated io.LimitedReader (to bound request header698// read sizes) with support for selectively keeping an io.Reader.Read699// call blocked in a background goroutine to wait for activity and700// trigger a CloseNotifier channel.701// After a Handler has hijacked the conn and exited, connReader behaves like a702// proxy for the net.Conn and the aforementioned behavior is bypassed.703type connReader struct {704 rwc net.Conn // rwc is the underlying network connection.705706 mu sync.Mutex // guards following707 conn *conn // conn is nil after handler exit.708 hasByte bool709 byteBuf [1]byte710 cond *sync.Cond711 inRead bool712 aborted bool // set true before conn.rwc deadline is set to past713 remain int64 // bytes remaining714}715716func (cr *connReader) lock() {717 cr.mu.Lock()718 if cr.cond == nil {719 cr.cond = sync.NewCond(&cr.mu)720 }721}722723func (cr *connReader) unlock() { cr.mu.Unlock() }724725func (cr *connReader) releaseConn() {726 cr.lock()727 defer cr.unlock()728 cr.conn = nil729}730731func (cr *connReader) startBackgroundRead() {732 cr.lock()733 defer cr.unlock()734 if cr.inRead {735 panic("invalid concurrent Body.Read call")736 }737 if cr.hasByte {738 return739 }740 cr.inRead = true741 cr.rwc.SetReadDeadline(time.Time{})742 go cr.backgroundRead()743}744745func (cr *connReader) backgroundRead() {746 n, err := cr.rwc.Read(cr.byteBuf[:])747 cr.lock()748 if n == 1 {749 cr.hasByte = true750 // We were past the end of the previous request's body already751 // (since we wouldn't be in a background read otherwise), so752 // this is a pipelined HTTP request. Prior to Go 1.11 we used to753 // send on the CloseNotify channel and cancel the context here,754 // but the behavior was documented as only "may", and we only755 // did that because that's how CloseNotify accidentally behaved756 // in very early Go releases prior to context support. Once we757 // added context support, people used a Handler's758 // Request.Context() and passed it along. Having that context759 // cancel on pipelined HTTP requests caused problems.760 // Fortunately, almost nothing uses HTTP/1.x pipelining.761 // Unfortunately, apt-get does, or sometimes does.762 // New Go 1.11 behavior: don't fire CloseNotify or cancel763 // contexts on pipelined requests. Shouldn't affect people, but764 // fixes cases like Issue 23921. This does mean that a client765 // closing their TCP connection after sending a pipelined766 // request won't cancel the context, but we'll catch that on any767 // write failure (in checkConnErrorWriter.Write).768 // If the server never writes, yes, there are still contrived769 // server & client behaviors where this fails to ever cancel the770 // context, but that's kinda why HTTP/1.x pipelining died771 // anyway.772 }773 if ne, ok := err.(net.Error); ok && cr.aborted && ne.Timeout() {774 // Ignore this error. It's the expected error from775 // another goroutine calling abortPendingRead.776 } else if err != nil {777 cr.handleReadErrorLocked(err)778 }779 cr.aborted = false780 cr.inRead = false781 cr.unlock()782 cr.cond.Broadcast()783}784785func (cr *connReader) abortPendingRead() {786 cr.lock()787 defer cr.unlock()788 if !cr.inRead {789 return790 }791 cr.aborted = true792 cr.rwc.SetReadDeadline(aLongTimeAgo)793 for cr.inRead {794 cr.cond.Wait()795 }796 cr.rwc.SetReadDeadline(time.Time{})797}798799func (cr *connReader) setReadLimit(remain int64) { cr.remain = remain }800func (cr *connReader) setInfiniteReadLimit() { cr.remain = maxInt64 }801func (cr *connReader) hitReadLimit() bool { return cr.remain <= 0 }802803// handleReadErrorLocked is called whenever a Read from the client returns a804// non-nil error.805//806// The provided non-nil err is almost always io.EOF or a "use of807// closed network connection". In any case, the error is not808// particularly interesting, except perhaps for debugging during809// development. Any error means the connection is dead and we should810// down its context.811//812// The caller must hold connReader.mu.813func (cr *connReader) handleReadErrorLocked(_ error) {814 if cr.conn == nil {815 return816 }817 cr.conn.cancelCtx()818 if res := cr.conn.curReq.Load(); res != nil {819 res.closeNotify()820 }821}822823func (cr *connReader) Read(p []byte) (n int, err error) {824 cr.lock()825 if cr.conn == nil {826 cr.unlock()827 return cr.rwc.Read(p)828 }829 if cr.inRead {830 hijacked := cr.conn.hijacked()831 cr.unlock()832 if hijacked {833 panic("invalid Body.Read call. After hijacked, the original Request must not be used")834 }835 panic("invalid concurrent Body.Read call")836 }837 if cr.hitReadLimit() {838 cr.unlock()839 return 0, io.EOF840 }841 if len(p) == 0 {842 cr.unlock()843 return 0, nil844 }845 if int64(len(p)) > cr.remain {846 p = p[:cr.remain]847 }848 if cr.hasByte {849 p[0] = cr.byteBuf[0]850 cr.hasByte = false851 cr.unlock()852 return 1, nil853 }854 cr.inRead = true855 cr.unlock()856 n, err = cr.rwc.Read(p)857858 cr.lock()859 cr.inRead = false860 if err != nil {861 cr.handleReadErrorLocked(err)862 }863 cr.remain -= int64(n)864 cr.unlock()865866 cr.cond.Broadcast()867 return n, err868}869870var (871 bufioReaderPool sync.Pool872 bufioWriter2kPool sync.Pool873 bufioWriter4kPool sync.Pool874)875876const copyBufPoolSize = 32 * 1024877878var copyBufPool = sync.Pool{New: func() any { return new([copyBufPoolSize]byte) }}879880func getCopyBuf() []byte {881 return copyBufPool.Get().(*[copyBufPoolSize]byte)[:]882}883884func putCopyBuf(b []byte) {885 if len(b) != copyBufPoolSize {886 panic("trying to put back buffer of the wrong size in the copyBufPool")887 }888 copyBufPool.Put((*[copyBufPoolSize]byte)(b))889}890891func bufioWriterPool(size int) *sync.Pool {892 switch size {893 case 2 << 10:894 return &bufioWriter2kPool895 case 4 << 10:896 return &bufioWriter4kPool897 }898 return nil899}900901func newBufioReader(r io.Reader) *bufio.Reader {902 if v := bufioReaderPool.Get(); v != nil {903 br := v.(*bufio.Reader)904 br.Reset(r)905 return br906 }907 // Note: if this reader size is ever changed, update908 // TestHandlerBodyClose's assumptions.909 return bufio.NewReader(r)910}911912func putBufioReader(br *bufio.Reader) {913 br.Reset(nil)914 bufioReaderPool.Put(br)915}916917func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {918 pool := bufioWriterPool(size)919 if pool != nil {920 if v := pool.Get(); v != nil {921 bw := v.(*bufio.Writer)922 bw.Reset(w)923 return bw924 }925 }926 return bufio.NewWriterSize(w, size)927}928929func putBufioWriter(bw *bufio.Writer) {930 bw.Reset(nil)931 if pool := bufioWriterPool(bw.Available()); pool != nil {932 pool.Put(bw)933 }934}935936// DefaultMaxHeaderBytes is the maximum permitted size of the headers937// in an HTTP request.938// This can be overridden by setting [Server.MaxHeaderBytes].939const DefaultMaxHeaderBytes = 1 << 20 // 1 MB940941// DefaultMaxHeaderValueCount is the maximum permitted number of942// header values in an HTTP request.943// This can be overridden by setting [Server.MaxHeaderValueCount].944const DefaultMaxHeaderValueCount = 500945946func (s *Server) maxHeaderBytes() int {947 if s.MaxHeaderBytes > 0 {948 return s.MaxHeaderBytes949 }950 return DefaultMaxHeaderBytes951}952953func (s *Server) maxHeaderValueCount() int {954 if s.MaxHeaderValueCount > 0 {955 return s.MaxHeaderValueCount956 }957 return DefaultMaxHeaderValueCount958}959960func (s *Server) initialReadLimitSize() int64 {961 return int64(s.maxHeaderBytes()) + 4096 // bufio slop962}963964// tlsHandshakeTimeout returns the time limit permitted for the TLS965// handshake, or zero for unlimited.966//967// It returns the minimum of any positive ReadHeaderTimeout,968// ReadTimeout, or WriteTimeout.969func (s *Server) tlsHandshakeTimeout() time.Duration {970 var ret time.Duration971 for _, v := range [...]time.Duration{972 s.ReadHeaderTimeout,973 s.ReadTimeout,974 s.WriteTimeout,975 } {976 if v <= 0 {977 continue978 }979 if ret == 0 || v < ret {980 ret = v981 }982 }983 return ret984}985986// wrapper around io.ReadCloser which on first read, sends an987// HTTP/1.1 100 Continue header988type expectContinueReader struct {989 resp *response990 readCloser io.ReadCloser991 closed atomic.Bool992}993994func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {995 if ecr.closed.Load() {996 return 0, ErrBodyReadAfterClose997 }998 w := ecr.resp999 if w.canWriteContinue.Load() {1000 w.writeContinueMu.Lock()1001 if w.canWriteContinue.Load() {1002 w.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")1003 w.conn.bufw.Flush()1004 w.canWriteContinue.Store(false)1005 }1006 w.writeContinueMu.Unlock()1007 }1008 return ecr.readCloser.Read(p)1009}10101011func (ecr *expectContinueReader) Close() error {1012 if ecr.resp.canWriteContinue.Load() {1013 ecr.resp.disableWriteContinue(true)1014 }1015 if ecr.closed.Swap(true) {1016 return nil1017 }1018 return ecr.readCloser.Close()1019}10201021// TimeFormat is the time format to use when generating times in HTTP1022// headers. It is like [time.RFC1123] but hard-codes GMT as the time1023// zone. The time being formatted must be in UTC for Format to1024// generate the correct format.1025//1026// For parsing this time format, see [ParseTime].1027const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"10281029var errTooLarge = errors.New("http: request too large")10301031// Read next request from connection.1032func (c *conn) readRequest(ctx context.Context) (w *response, err error) {1033 if c.hijacked() {1034 return nil, ErrHijacked1035 }10361037 t0 := time.Now()1038 var wholeReqDeadline time.Time // or zero if none1039 if d := c.server.ReadTimeout; d > 0 {1040 wholeReqDeadline = t0.Add(d)1041 }1042 if d := c.server.WriteTimeout; d > 0 {1043 defer func() {1044 c.rwc.SetWriteDeadline(time.Now().Add(d))1045 }()1046 }10471048 c.r.setReadLimit(c.server.initialReadLimitSize())1049 if c.lastMethod == "POST" {1050 // RFC 7230 section 3 tolerance for old buggy clients.1051 peek, _ := c.bufr.Peek(4) // ReadRequest will get err below1052 c.bufr.Discard(numLeadingCRorLF(peek))1053 }1054 req, err := readRequestLimit(c.bufr, int64(c.server.maxHeaderValueCount()))1055 if err != nil {1056 if c.r.hitReadLimit() {1057 return nil, errTooLarge1058 }1059 return nil, err1060 }10611062 if !http1ServerSupportsRequest(req) {1063 return nil, statusError{StatusHTTPVersionNotSupported, "unsupported protocol version"}1064 }10651066 c.lastMethod = req.Method1067 c.r.setInfiniteReadLimit()10681069 hosts, haveHost := req.Header["Host"]1070 isH2Upgrade := req.isH2Upgrade()1071 if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade && req.Method != "CONNECT" {1072 return nil, badRequestError("missing required Host header")1073 }1074 if len(hosts) == 1 && !httpguts.ValidHostHeader(hosts[0]) {1075 return nil, badRequestError("malformed Host header")1076 }1077 for k, vv := range req.Header {1078 if !httpguts.ValidHeaderFieldName(k) {1079 return nil, badRequestError("invalid header name")1080 }1081 for _, v := range vv {1082 if !httpguts.ValidHeaderFieldValue(v) {1083 return nil, badRequestError("invalid header value")1084 }1085 }1086 }1087 delete(req.Header, "Host")10881089 ctx, cancelCtx := context.WithCancel(ctx)1090 req.ctx = ctx1091 req.RemoteAddr = c.remoteAddr1092 req.TLS = c.tlsState1093 var reqBody *body1094 switch b := req.Body.(type) {1095 case noBody:1096 case *body:1097 reqBody = b1098 reqBody.doEarlyClose = true1099 default:1100 panic(fmt.Errorf("http: unexpected request body type %T", req.Body))1101 }11021103 c.rwc.SetReadDeadline(wholeReqDeadline)11041105 w = &response{1106 conn: c,1107 cancelCtx: cancelCtx,1108 req: req,1109 reqBody: reqBody,1110 handlerHeader: make(Header),1111 contentLength: -1,11121113 // We populate these ahead of time so we're not1114 // reading from req.Header after their Handler starts1115 // and maybe mutates it (Issue 14940)1116 wants10KeepAlive: req.wantsHttp10KeepAlive(),1117 wantsClose: req.wantsClose(),1118 }1119 if isH2Upgrade {1120 w.closeAfterReply = true1121 }1122 w.cw.res = w1123 w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)1124 return w, nil1125}11261127// http1ServerSupportsRequest reports whether Go's HTTP/1.x server1128// supports the given request.1129func http1ServerSupportsRequest(req *Request) bool {1130 if req.ProtoMajor == 1 {1131 return true1132 }1133 // Accept "PRI * HTTP/2.0" upgrade requests, so Handlers can1134 // wire up their own HTTP/2 upgrades.1135 if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&1136 req.Method == "PRI" && req.RequestURI == "*" {1137 return true1138 }1139 // Reject HTTP/0.x, and all other HTTP/2+ requests (which1140 // aren't encoded in ASCII anyway).1141 return false1142}11431144func (w *response) Header() Header {1145 if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {1146 // Accessing the header between logically writing it1147 // and physically writing it means we need to allocate1148 // a clone to snapshot the logically written state.1149 w.cw.header = w.handlerHeader.Clone()1150 }1151 w.calledHeader = true1152 return w.handlerHeader1153}11541155// maxPostHandlerReadBytes is the max number of Request.Body bytes not1156// consumed by a handler that the server will read from the client1157// in order to keep a connection alive. If there are more bytes1158// than this, the server, to be paranoid, instead sends a1159// "Connection close" response.1160//1161// This number is approximately what a typical machine's TCP buffer1162// size is anyway. (if we have the bytes on the machine, we might as1163// well read them)1164const maxPostHandlerReadBytes = 256 << 1011651166func checkWriteHeaderCode(code int) {1167 // Issue 22880: require valid WriteHeader status codes.1168 // For now we only enforce that it's three digits.1169 // In the future we might block things over 599 (600 and above aren't defined1170 // at https://httpwg.org/specs/rfc7231.html#status.codes).1171 // But for now any three digits.1172 //1173 // We used to send "HTTP/1.1 000 0" on the wire in responses but there's1174 // no equivalent bogus thing we can realistically send in HTTP/2,1175 // so we'll consistently panic instead and help people find their bugs1176 // early. (We can't return an error from WriteHeader even if we wanted to.)1177 if code < 100 || code > 999 {1178 panic(fmt.Sprintf("invalid WriteHeader code %v", code))1179 }1180}11811182// relevantCaller searches the call stack for the first function outside of net/http.1183// The purpose of this function is to provide more helpful error messages.1184func relevantCaller() runtime.Frame {1185 pc := make([]uintptr, 16)1186 n := runtime.Callers(1, pc)1187 frames := runtime.CallersFrames(pc[:n])1188 var frame runtime.Frame1189 for {1190 var more bool1191 frame, more = frames.Next()1192 if !strings.HasPrefix(frame.Function, "net/http.") {1193 return frame1194 }1195 if !more {1196 break1197 }1198 }1199 return frame1200}12011202func (w *response) WriteHeader(code int) {1203 if w.conn.hijacked() {1204 caller := relevantCaller()1205 w.conn.server.logf("http: response.WriteHeader on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)1206 return1207 }1208 if w.wroteHeader {1209 caller := relevantCaller()1210 w.conn.server.logf("http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)1211 return1212 }1213 checkWriteHeaderCode(code)12141215 // Sending a 100 Continue or any non-1XX header disables the1216 // automatically-sent 100 Continue from Request.Body.Read. If it is a final1217 // response (200 or higher), we skip draining the request body, which the1218 // client will never send.1219 if code == 100 || code >= 200 {1220 w.disableWriteContinue(code >= 200)1221 }12221223 // Handle informational headers.1224 //1225 // We shouldn't send any further headers after 101 Switching Protocols,1226 // so it takes the non-informational path.1227 if code >= 100 && code <= 199 && code != StatusSwitchingProtocols {1228 w.writeContinueMu.Lock()1229 defer w.writeContinueMu.Unlock()1230 writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])12311232 // Per RFC 8297 we must not clear the current header map1233 w.handlerHeader.WriteSubset(w.conn.bufw, excludedHeadersNoBody)1234 w.conn.bufw.Write(crlf)1235 w.conn.bufw.Flush()12361237 return1238 }12391240 w.wroteHeader = true1241 w.status = code12421243 if w.calledHeader && w.cw.header == nil {1244 w.cw.header = w.handlerHeader.Clone()1245 }12461247 if cl := w.handlerHeader.get("Content-Length"); cl != "" {1248 v, err := strconv.ParseInt(cl, 10, 64)1249 if err == nil && v >= 0 {1250 w.contentLength = v1251 } else {1252 w.conn.server.logf("http: invalid Content-Length of %q", cl)1253 w.handlerHeader.Del("Content-Length")1254 }1255 }1256}12571258// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.1259// This type is used to avoid extra allocations from cloning and/or populating1260// the response Header map and all its 1-element slices.1261type extraHeader struct {1262 contentType string1263 connection string1264 transferEncoding string1265 date []byte // written if not nil1266 contentLength []byte // written if not nil1267}12681269// Sorted the same as extraHeader.Write's loop.1270var extraHeaderKeys = [][]byte{1271 []byte("Content-Type"),1272 []byte("Connection"),1273 []byte("Transfer-Encoding"),1274}12751276var (1277 headerContentLength = []byte("Content-Length: ")1278 headerDate = []byte("Date: ")1279)12801281// Write writes the headers described in h to w.1282//1283// This method has a value receiver, despite the somewhat large size1284// of h, because it prevents an allocation. The escape analysis isn't1285// smart enough to realize this function doesn't mutate h.1286func (h extraHeader) Write(w *bufio.Writer) {1287 if h.date != nil {1288 w.Write(headerDate)1289 w.Write(h.date)1290 w.Write(crlf)1291 }1292 if h.contentLength != nil {1293 w.Write(headerContentLength)1294 w.Write(h.contentLength)1295 w.Write(crlf)1296 }1297 for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {1298 if v != "" {1299 w.Write(extraHeaderKeys[i])1300 w.Write(colonSpace)1301 w.WriteString(v)1302 w.Write(crlf)1303 }1304 }1305}13061307// writeHeader finalizes the header sent to the client and writes it1308// to cw.res.conn.bufw.1309//1310// p is not written by writeHeader, but is the first chunk of the body1311// that will be written. It is sniffed for a Content-Type if none is1312// set explicitly. It's also used to set the Content-Length, if the1313// total body size was small and the handler has already finished1314// running.1315func (cw *chunkWriter) writeHeader(p []byte) {1316 if cw.wroteHeader {1317 return1318 }1319 cw.wroteHeader = true13201321 w := cw.res1322 keepAlivesEnabled := w.conn.server.doKeepAlives()1323 isHEAD := w.req.Method == "HEAD"13241325 // header is written out to w.conn.buf below. Depending on the1326 // state of the handler, we either own the map or not. If we1327 // don't own it, the exclude map is created lazily for1328 // WriteSubset to remove headers. The setHeader struct holds1329 // headers we need to add.1330 header := cw.header1331 owned := header != nil1332 if !owned {1333 header = w.handlerHeader1334 }1335 var excludeHeader map[string]bool1336 delHeader := func(key string) {1337 if owned {1338 header.Del(key)1339 return1340 }1341 if _, ok := header[key]; !ok {1342 return1343 }1344 if excludeHeader == nil {1345 excludeHeader = make(map[string]bool)1346 }1347 excludeHeader[key] = true1348 }1349 var setHeader extraHeader13501351 // Don't write out the fake "Trailer:foo" keys. See TrailerPrefix.1352 trailers := false1353 for k := range cw.header {1354 if strings.HasPrefix(k, TrailerPrefix) {1355 if excludeHeader == nil {1356 excludeHeader = make(map[string]bool)1357 }1358 excludeHeader[k] = true1359 trailers = true1360 }1361 }1362 for _, v := range cw.header["Trailer"] {1363 trailers = true1364 foreachHeaderElement(v, cw.res.declareTrailer)1365 }13661367 te := header.get("Transfer-Encoding")1368 hasTE := te != ""13691370 // If the handler is done but never sent a Content-Length1371 // response header and this is our first (and last) write, set1372 // it, even to zero. This helps HTTP/1.0 clients keep their1373 // "keep-alive" connections alive.1374 // Exceptions: 304/204/1xx responses never get Content-Length, and if1375 // it was a HEAD request, we don't know the difference between1376 // 0 actual bytes and 0 bytes because the handler noticed it1377 // was a HEAD request and chose not to write anything. So for1378 // HEAD, the handler should either write the Content-Length or1379 // write non-zero bytes. If it's actually 0 bytes and the1380 // handler never looked at the Request.Method, we just don't1381 // send a Content-Length header.1382 // Further, we don't send an automatic Content-Length if they1383 // set a Transfer-Encoding, because they're generally incompatible.1384 if w.handlerDone.Load() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && !header.has("Content-Length") && (!isHEAD || len(p) > 0) {1385 w.contentLength = int64(len(p))1386 setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)1387 }13881389 // If this was an HTTP/1.0 request with keep-alive and we sent a1390 // Content-Length back, we can make this a keep-alive response ...1391 if w.wants10KeepAlive && keepAlivesEnabled {1392 sentLength := header.get("Content-Length") != ""1393 if sentLength && header.get("Connection") == "keep-alive" {1394 w.closeAfterReply = false1395 }1396 }13971398 // Check for an explicit (and valid) Content-Length header.1399 hasCL := w.contentLength != -114001401 if w.wants10KeepAlive && (isHEAD || hasCL || !bodyAllowedForStatus(w.status)) {1402 _, connectionHeaderSet := header["Connection"]1403 if !connectionHeaderSet {1404 setHeader.connection = "keep-alive"1405 }1406 } else if !w.req.ProtoAtLeast(1, 1) || w.wantsClose {1407 w.closeAfterReply = true1408 }14091410 if header.get("Connection") == "close" || !keepAlivesEnabled {1411 w.closeAfterReply = true1412 }14131414 // If the client wanted a 100-continue but we never sent it to1415 // them (or, more strictly: we never finished reading their1416 // request body), don't reuse this connection.1417 //1418 // This behavior was first added on the theory that we don't know1419 // if the next bytes on the wire are going to be the remainder of1420 // the request body or the subsequent request (see issue 11549),1421 // but that's not correct: If we keep using the connection,1422 // the client is required to send the request body whether we1423 // asked for it or not.1424 //1425 // We probably do want to skip reusing the connection in most cases,1426 // however. If the client is offering a large request body that we1427 // don't intend to use, then it's better to close the connection1428 // than to read the body. For now, assume that if we're sending1429 // headers, the handler is done reading the body and we should1430 // drop the connection if we haven't seen EOF.1431 if w.ecReader != nil && w.reqBody.bodyRemains() {1432 w.closeAfterReply = true1433 }14341435 // We do this by default because there are a number of clients that1436 // send a full request before starting to read the response, and they1437 // can deadlock if we start writing the response with unconsumed body1438 // remaining. See Issue 15527 for some history.1439 //1440 // If full duplex mode has been enabled with ResponseController.EnableFullDuplex,1441 // then leave the request body alone.1442 //1443 // We don't take this path when w.closeAfterReply is set.1444 // We may not need to consume the request to get ready for the next one1445 // (since we're closing the conn), but a client which sends a full request1446 // before reading a response may deadlock in this case.1447 // This behavior has been present since CL 5268043 (2011), however,1448 // so it doesn't seem to be causing problems.1449 if w.req.ContentLength != 0 && w.reqBody != nil && !w.closeAfterReply && !w.fullDuplex {1450 var discard, tooBig bool1451 w.reqBody.mu.Lock()1452 switch {1453 case w.reqBody.closed:1454 if !w.reqBody.sawEOF {1455 // Body was closed in handler with non-EOF error.1456 w.closeAfterReply = true1457 }1458 case w.reqBody.unreadDataSizeLocked() >= maxPostHandlerReadBytes:1459 tooBig = true1460 default:1461 discard = true1462 }1463 w.reqBody.mu.Unlock()14641465 if discard {1466 w.reqBody.Close()1467 if w.reqBody.didEarlyClose() {1468 w.closeAfterReply = true1469 }1470 }1471 if tooBig {1472 w.requestTooLarge()1473 delHeader("Connection")1474 setHeader.connection = "close"1475 }1476 }14771478 code := w.status1479 if bodyAllowedForStatus(code) {1480 // If no content type, apply sniffing algorithm to body.1481 _, haveType := header["Content-Type"]14821483 // If the Content-Encoding was set and is non-blank,1484 // we shouldn't sniff the body. See Issue 31753.1485 ce := header.Get("Content-Encoding")1486 hasCE := len(ce) > 01487 if !hasCE && !haveType && !hasTE && len(p) > 0 {1488 setHeader.contentType = DetectContentType(p)1489 }1490 } else {1491 for _, k := range suppressedHeaders(code) {1492 delHeader(k)1493 }1494 }14951496 if !header.has("Date") {1497 setHeader.date = time.Now().UTC().AppendFormat(cw.res.dateBuf[:0], TimeFormat)1498 }14991500 if hasCL && hasTE && te != "identity" {1501 // TODO: return an error if WriteHeader gets a return parameter1502 // For now just ignore the Content-Length.1503 w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",1504 te, w.contentLength)1505 delHeader("Content-Length")1506 hasCL = false1507 }15081509 if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent {1510 // Response has no body.1511 delHeader("Transfer-Encoding")1512 } else if hasCL {1513 // Content-Length has been provided, so no chunking is to be done.1514 delHeader("Transfer-Encoding")1515 } else if w.req.ProtoAtLeast(1, 1) {1516 // HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no1517 // content-length has been provided. The connection must be closed after the1518 // reply is written, and no chunking is to be done. This is the setup1519 // recommended in the Server-Sent Events candidate recommendation 11,1520 // section 8.1521 if hasTE && te == "identity" {1522 cw.chunking = false1523 w.closeAfterReply = true1524 delHeader("Transfer-Encoding")1525 } else {1526 // HTTP/1.1 or greater: use chunked transfer encoding1527 // to avoid closing the connection at EOF.1528 cw.chunking = true1529 setHeader.transferEncoding = "chunked"1530 if hasTE && te == "chunked" {1531 // We will send the chunked Transfer-Encoding header later.1532 delHeader("Transfer-Encoding")1533 }1534 }1535 } else {1536 // HTTP version < 1.1: cannot do chunked transfer1537 // encoding and we don't know the Content-Length so1538 // signal EOF by closing connection.1539 w.closeAfterReply = true1540 delHeader("Transfer-Encoding") // in case already set1541 }15421543 // Cannot use Content-Length with non-identity Transfer-Encoding.1544 if cw.chunking {1545 delHeader("Content-Length")1546 }1547 if !w.req.ProtoAtLeast(1, 0) {1548 return1549 }15501551 // Only override the Connection header if it is not a successful1552 // protocol switch response and if KeepAlives are not enabled.1553 // See https://golang.org/issue/36381.1554 delConnectionHeader := w.closeAfterReply &&1555 (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) &&1556 !isProtocolSwitchResponse(w.status, header)1557 if delConnectionHeader {1558 delHeader("Connection")1559 if w.req.ProtoAtLeast(1, 1) {1560 setHeader.connection = "close"1561 }1562 }15631564 writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])1565 cw.header.WriteSubset(w.conn.bufw, excludeHeader)1566 setHeader.Write(w.conn.bufw)1567 w.conn.bufw.Write(crlf)1568}15691570// foreachHeaderElement splits v according to the "#rule" construction1571// in RFC 7230 section 7 and calls fn for each non-empty element.1572func foreachHeaderElement(v string, fn func(string)) {1573 v = textproto.TrimString(v)1574 if v == "" {1575 return1576 }1577 if !strings.Contains(v, ",") {1578 fn(v)1579 return1580 }1581 for f := range strings.SplitSeq(v, ",") {1582 if f = textproto.TrimString(f); f != "" {1583 fn(f)1584 }1585 }1586}15871588// writeStatusLine writes an HTTP/1.x Status-Line (RFC 7230 Section 3.1.2)1589// to bw. is11 is whether the HTTP request is HTTP/1.1. false means HTTP/1.0.1590// code is the response status code.1591// scratch is an optional scratch buffer. If it has at least capacity 3, it's used.1592func writeStatusLine(bw *bufio.Writer, is11 bool, code int, scratch []byte) {1593 if is11 {1594 bw.WriteString("HTTP/1.1 ")1595 } else {1596 bw.WriteString("HTTP/1.0 ")1597 }1598 if text := StatusText(code); text != "" {1599 bw.Write(strconv.AppendInt(scratch[:0], int64(code), 10))1600 bw.WriteByte(' ')1601 bw.WriteString(text)1602 bw.WriteString("\r\n")1603 } else {1604 // don't worry about performance1605 fmt.Fprintf(bw, "%03d status code %d\r\n", code, code)1606 }1607}16081609// bodyAllowed reports whether a Write is allowed for this response type.1610// It's illegal to call this before the header has been flushed.1611func (w *response) bodyAllowed() bool {1612 if !w.wroteHeader {1613 panic("net/http: bodyAllowed called before the header was written")1614 }1615 return bodyAllowedForStatus(w.status)1616}16171618// The Life Of A Write is like this:1619//1620// Handler starts. No header has been sent. The handler can either1621// write a header, or just start writing. Writing before sending a header1622// sends an implicitly empty 200 OK header.1623//1624// If the handler didn't declare a Content-Length up front, we either1625// go into chunking mode or, if the handler finishes running before1626// the chunking buffer size, we compute a Content-Length and send that1627// in the header instead.1628//1629// Likewise, if the handler didn't set a Content-Type, we sniff that1630// from the initial chunk of output.1631//1632// The Writers are wired together like:1633//1634// 1. *response (the ResponseWriter) ->1635// 2. (*response).w, a [*bufio.Writer] of bufferBeforeChunkingSize bytes ->1636// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)1637// and which writes the chunk headers, if needed ->1638// 4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to ->1639// 5. checkConnErrorWriter{c}, which notes any non-nil error on Write1640// and populates c.werr with it if so, but otherwise writes to ->1641// 6. the rwc, the [net.Conn].1642//1643// TODO(bradfitz): short-circuit some of the buffering when the1644// initial header contains both a Content-Type and Content-Length.1645// Also short-circuit in (1) when the header's been sent and not in1646// chunking mode, writing directly to (4) instead, if (2) has no1647// buffered data. More generally, we could short-circuit from (1) to1648// (3) even in chunking mode if the write size from (1) is over some1649// threshold and nothing is in (2). The answer might be mostly making1650// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal1651// with this instead.1652func (w *response) Write(data []byte) (n int, err error) {1653 return w.write(len(data), data, "")1654}16551656func (w *response) WriteString(data string) (n int, err error) {1657 return w.write(len(data), nil, data)1658}16591660// either dataB or dataS is non-zero.1661func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {1662 if w.conn.hijacked() {1663 if lenData > 0 {1664 caller := relevantCaller()1665 w.conn.server.logf("http: response.Write on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)1666 }1667 return 0, ErrHijacked1668 }16691670 if w.canWriteContinue.Load() {1671 // Body reader wants to write 100 Continue but hasn't yet. Tell it not to.1672 w.disableWriteContinue(true)1673 }16741675 if !w.wroteHeader {1676 w.WriteHeader(StatusOK)1677 }1678 if lenData == 0 {1679 return 0, nil1680 }1681 if !w.bodyAllowed() {1682 return 0, ErrBodyNotAllowed1683 }16841685 w.written += int64(lenData) // ignoring errors, for errorKludge1686 if w.contentLength != -1 && w.written > w.contentLength {1687 return 0, ErrContentLength1688 }1689 if dataB != nil {1690 return w.w.Write(dataB)1691 } else {1692 return w.w.WriteString(dataS)1693 }1694}16951696func (w *response) finishRequest() {1697 w.handlerDone.Store(true)16981699 if !w.wroteHeader {1700 w.WriteHeader(StatusOK)1701 }17021703 w.w.Flush()1704 putBufioWriter(w.w)1705 w.cw.close()1706 w.conn.bufw.Flush()17071708 w.conn.r.abortPendingRead()1709 w.reqBody.registerOnHitEOF(nil) // prevent new background read from starting17101711 if w.canWriteContinue.Load() {1712 w.disableWriteContinue(true)1713 }17141715 // Close the body (regardless of w.closeAfterReply) so we can1716 // re-use its bufio.Reader later safely.1717 //1718 // In full-duplex mode, this may also drain the remaining request body.1719 w.reqBody.Close()1720}17211722// shouldReuseConnection reports whether the underlying TCP connection can be reused.1723// It must only be called after the handler is done executing.1724func (w *response) shouldReuseConnection() bool {1725 if w.closeAfterReply {1726 // The request or something set while executing the1727 // handler indicated we shouldn't reuse this1728 // connection.1729 return false1730 }17311732 if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {1733 // Did not write enough. Avoid getting out of sync.1734 return false1735 }17361737 // There was some error writing to the underlying connection1738 // during the request, so don't re-use this conn.1739 if w.conn.werr != nil {1740 return false1741 }17421743 if w.closedRequestBodyEarly() {1744 return false1745 }17461747 return true1748}17491750func (w *response) closedRequestBodyEarly() bool {1751 return w.reqBody != nil && w.reqBody.didEarlyClose()1752}17531754func (w *response) Flush() {1755 w.FlushError()1756}17571758func (w *response) FlushError() error {1759 if !w.wroteHeader {1760 w.WriteHeader(StatusOK)1761 }1762 err := w.w.Flush()1763 e2 := w.cw.flush()1764 if err == nil {1765 err = e21766 }1767 return err1768}17691770func (c *conn) finalFlush() {1771 if c.bufr != nil {1772 // Steal the bufio.Reader (~4KB worth of memory) and its associated1773 // reader for a future connection.1774 putBufioReader(c.bufr)1775 c.bufr = nil1776 }17771778 if c.bufw != nil {1779 c.bufw.Flush()1780 // Steal the bufio.Writer (~4KB worth of memory) and its associated1781 // writer for a future connection.1782 putBufioWriter(c.bufw)1783 c.bufw = nil1784 }1785}17861787// Close the connection.1788func (c *conn) close() {1789 c.finalFlush()1790 c.rwc.Close()1791}17921793// rstAvoidanceDelay is the amount of time we sleep after closing the1794// write side of a TCP connection before closing the entire socket.1795// By sleeping, we increase the chances that the client sees our FIN1796// and processes its final data before they process the subsequent RST1797// from closing a connection with known unread data.1798// This RST seems to occur mostly on BSD systems. (And Windows?)1799// This timeout is somewhat arbitrary (~latency around the planet),1800// and may be modified by tests.1801//1802// TODO(bcmills): This should arguably be a server configuration parameter,1803// not a hard-coded value.1804var rstAvoidanceDelay = 500 * time.Millisecond18051806type closeWriter interface {1807 CloseWrite() error1808}18091810var _ closeWriter = (*net.TCPConn)(nil)18111812// closeWriteAndWait flushes any outstanding data and sends a FIN packet (if1813// client is connected via TCP), signaling that we're done. We then1814// pause for a bit, hoping the client processes it before any1815// subsequent RST.1816//1817// See https://golang.org/issue/35951818func (c *conn) closeWriteAndWait() {1819 c.finalFlush()1820 if tcp, ok := c.rwc.(closeWriter); ok {1821 tcp.CloseWrite()1822 }18231824 // When we return from closeWriteAndWait, the caller will fully close the1825 // connection. If client is still writing to the connection, this will cause1826 // the write to fail with ECONNRESET or similar. Unfortunately, many TCP1827 // implementations will also drop unread packets from the client's read buffer1828 // when a write fails, causing our final response to be truncated away too.1829 //1830 // As a result, https://www.rfc-editor.org/rfc/rfc7230#section-6.6 recommends1831 // that “[t]he server … continues to read from the connection until it1832 // receives a corresponding close by the client, or until the server is1833 // reasonably certain that its own TCP stack has received the client's1834 // acknowledgement of the packet(s) containing the server's last response.”1835 //1836 // Unfortunately, we have no straightforward way to be “reasonably certain”1837 // that we have received the client's ACK, and at any rate we don't want to1838 // allow a misbehaving client to soak up server connections indefinitely by1839 // withholding an ACK, nor do we want to go through the complexity or overhead1840 // of using low-level APIs to figure out when a TCP round-trip has completed.1841 //1842 // Instead, we declare that we are “reasonably certain” that we received the1843 // ACK if maxRSTAvoidanceDelay has elapsed.1844 time.Sleep(rstAvoidanceDelay)1845}18461847// validNextProto reports whether the proto is a valid ALPN protocol name.1848// Everything is valid except the empty string and built-in protocol types,1849// so that those can't be overridden with alternate implementations.1850func validNextProto(proto string) bool {1851 switch proto {1852 case "", "http/1.1", "http/1.0":1853 return false1854 }1855 return true1856}18571858const (1859 runHooks = true1860 skipHooks = false1861)18621863func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) {1864 srv := c.server1865 switch state {1866 case StateNew:1867 srv.trackConn(c, true)1868 case StateHijacked, StateClosed:1869 srv.trackConn(c, false)1870 }1871 if state > 0xff || state < 0 {1872 panic("internal error")1873 }1874 packedState := uint64(time.Now().Unix()<<8) | uint64(state)1875 c.curState.Store(packedState)1876 if !runHook {1877 return1878 }1879 if hook := srv.ConnState; hook != nil {1880 hook(nc, state)1881 }1882}18831884func (c *conn) getState() (state ConnState, unixSec int64) {1885 packedState := c.curState.Load()1886 return ConnState(packedState & 0xff), int64(packedState >> 8)1887}18881889// badRequestError is a literal string (used by in the server in HTML,1890// unescaped) to tell the user why their request was bad. It should1891// be plain text without user info or other embedded errors.1892func badRequestError(e string) error { return statusError{StatusBadRequest, e} }18931894// statusError is an error used to respond to a request with an HTTP status.1895// The text should be plain text without user info or other embedded errors.1896type statusError struct {1897 code int1898 text string1899}19001901func (e statusError) Error() string { return StatusText(e.code) + ": " + e.text }19021903// ErrAbortHandler is a sentinel panic value to abort a handler.1904// While any panic from ServeHTTP aborts the response to the client,1905// panicking with ErrAbortHandler also suppresses logging of a stack1906// trace to the server's error log.1907var ErrAbortHandler = internal.ErrAbortHandler19081909// isCommonNetReadError reports whether err is a common error1910// encountered during reading a request off the network when the1911// client has gone away or had its read fail somehow. This is used to1912// determine which logs are interesting enough to log about.1913func isCommonNetReadError(err error) bool {1914 if err == io.EOF {1915 return true1916 }1917 if neterr, ok := err.(net.Error); ok && neterr.Timeout() {1918 return true1919 }1920 if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {1921 return true1922 }1923 return false1924}19251926// Serve a new connection.1927func (c *conn) serve(ctx context.Context) {1928 if ra := c.rwc.RemoteAddr(); ra != nil {1929 c.remoteAddr = ra.String()1930 }1931 ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())1932 var inFlightResponse *response1933 defer func() {1934 if err := recover(); err != nil && err != ErrAbortHandler {1935 const size = 64 << 101936 buf := make([]byte, size)1937 buf = buf[:runtime.Stack(buf, false)]1938 c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)1939 }1940 if inFlightResponse != nil {1941 inFlightResponse.cancelCtx()1942 inFlightResponse.disableWriteContinue(true)1943 }1944 if !c.hijacked() {1945 if inFlightResponse != nil {1946 inFlightResponse.conn.r.abortPendingRead()1947 inFlightResponse.reqBody.Close()1948 }1949 c.close()1950 c.setState(c.rwc, StateClosed, runHooks)1951 }1952 }()19531954 type connectionStater interface {1955 ConnectionState() tls.ConnectionState1956 }1957 type handshakeContexter interface {1958 HandshakeContext(ctx context.Context) error1959 }1960 if connStater, ok := c.rwc.(connectionStater); ok {1961 tlsTO := c.server.tlsHandshakeTimeout()1962 if tlsTO > 0 {1963 dl := time.Now().Add(tlsTO)1964 c.rwc.SetReadDeadline(dl)1965 c.rwc.SetWriteDeadline(dl)1966 }1967 var err error1968 if handshaker, ok := c.rwc.(handshakeContexter); ok {1969 err = handshaker.HandshakeContext(ctx)1970 }1971 if err != nil {1972 // If the handshake failed due to the client not speaking1973 // TLS, assume they're speaking plaintext HTTP and write a1974 // 400 response on the TLS conn's underlying net.Conn.1975 var reason string1976 if re, ok := err.(tls.RecordHeaderError); ok && re.Conn != nil && tlsRecordHeaderLooksLikeHTTP(re.RecordHeader) {1977 io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n")1978 re.Conn.Close()1979 reason = "client sent an HTTP request to an HTTPS server"1980 } else {1981 reason = err.Error()1982 }1983 c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), reason)1984 return1985 }1986 // Restore Conn-level deadlines.1987 if tlsTO > 0 {1988 c.rwc.SetReadDeadline(time.Time{})1989 c.rwc.SetWriteDeadline(time.Time{})1990 }1991 c.tlsState = new(tls.ConnectionState)1992 *c.tlsState = connStater.ConnectionState()1993 proto := c.tlsState.NegotiatedProtocol1994 if proto == "h2" && c.server.h2 != nil {1995 // net/http/internal/http2 path.1996 //1997 // Mark freshly created HTTP/2 as active and prevent any server state hooks1998 // from being run on these connections. This prevents closeIdleConns from1999 // closing such connections. See issue https://golang.org/issue/39776.2000 c.setState(c.rwc, StateActive, skipHooks)
Findings
✓ No findings reported for this file.