src/net/http/server.go GO 4,300 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 4,300.
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.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.