var ErrBodyNotAllowed … var ErrHijacked … var ErrContentLength … var ErrWriteAfterFlush … type Handler … type ResponseWriter … type Flusher … type Hijacker … type CloseNotifier … var ServerContextKey … var LocalAddrContextKey … type conn … func (c *conn) hijacked() bool { … } // c.mu must be held. func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) { … } const bufferBeforeChunkingSize … type chunkWriter … var crlf … var colonSpace … func (cw *chunkWriter) Write(p []byte) (n int, err error) { … } func (cw *chunkWriter) flush() error { … } func (cw *chunkWriter) close() { … } type response … func (c *response) SetReadDeadline(deadline time.Time) error { … } func (c *response) SetWriteDeadline(deadline time.Time) error { … } func (c *response) EnableFullDuplex() error { … } const TrailerPrefix … // finalTrailers is called after the Handler exits and returns a non-nil // value if the Handler set any trailers. func (w *response) finalTrailers() Header { … } // declareTrailer is called for each Trailer header when the // response header is written. It notes that a header will need to be // written in the trailers at the end of the response. func (w *response) declareTrailer(k string) { … } // requestTooLarge is called by maxBytesReader when too much input has // been read from the client. func (w *response) requestTooLarge() { … } // disableWriteContinue stops Request.Body.Read from sending an automatic 100-Continue. // If a 100-Continue is being written, it waits for it to complete before continuing. func (w *response) disableWriteContinue() { … } type writerOnly … // ReadFrom is here to optimize copying from an [*os.File] regular file // to a [*net.TCPConn] with sendfile, or from a supported src type such // as a *net.TCPConn on Linux with splice. func (w *response) ReadFrom(src io.Reader) (n int64, err error) { … } const debugServerConnections … // Create new connection from rwc. func (s *Server) newConn(rwc net.Conn) *conn { … } type readResult … type connReader … func (cr *connReader) lock() { … } func (cr *connReader) unlock() { … } func (cr *connReader) startBackgroundRead() { … } func (cr *connReader) backgroundRead() { … } func (cr *connReader) abortPendingRead() { … } func (cr *connReader) setReadLimit(remain int64) { … } func (cr *connReader) setInfiniteReadLimit() { … } func (cr *connReader) hitReadLimit() bool { … } // handleReadError is called whenever a Read from the client returns a // non-nil error. // // The provided non-nil err is almost always io.EOF or a "use of // closed network connection". In any case, the error is not // particularly interesting, except perhaps for debugging during // development. Any error means the connection is dead and we should // down its context. // // It may be called from multiple goroutines. func (cr *connReader) handleReadError(_ error) { … } // may be called from multiple goroutines. func (cr *connReader) closeNotify() { … } func (cr *connReader) Read(p []byte) (n int, err error) { … } var bufioReaderPool … var bufioWriter2kPool … var bufioWriter4kPool … const copyBufPoolSize … var copyBufPool … func getCopyBuf() []byte { … } func putCopyBuf(b []byte) { … } func bufioWriterPool(size int) *sync.Pool { … } // newBufioReader should be an internal detail, // but widely used packages access it using linkname. // Notable members of the hall of shame include: // - github.com/gobwas/ws // // Do not remove or change the type signature. // See go.dev/issue/67401. // //go:linkname newBufioReader func newBufioReader(r io.Reader) *bufio.Reader { … } // putBufioReader should be an internal detail, // but widely used packages access it using linkname. // Notable members of the hall of shame include: // - github.com/gobwas/ws // // Do not remove or change the type signature. // See go.dev/issue/67401. // //go:linkname putBufioReader func putBufioReader(br *bufio.Reader) { … } // newBufioWriterSize should be an internal detail, // but widely used packages access it using linkname. // Notable members of the hall of shame include: // - github.com/gobwas/ws // // Do not remove or change the type signature. // See go.dev/issue/67401. // //go:linkname newBufioWriterSize func newBufioWriterSize(w io.Writer, size int) *bufio.Writer { … } // putBufioWriter should be an internal detail, // but widely used packages access it using linkname. // Notable members of the hall of shame include: // - github.com/gobwas/ws // // Do not remove or change the type signature. // See go.dev/issue/67401. // //go:linkname putBufioWriter func putBufioWriter(bw *bufio.Writer) { … } const DefaultMaxHeaderBytes … func (s *Server) maxHeaderBytes() int { … } func (s *Server) initialReadLimitSize() int64 { … } // tlsHandshakeTimeout returns the time limit permitted for the TLS // handshake, or zero for unlimited. // // It returns the minimum of any positive ReadHeaderTimeout, // ReadTimeout, or WriteTimeout. func (s *Server) tlsHandshakeTimeout() time.Duration { … } type expectContinueReader … func (ecr *expectContinueReader) Read(p []byte) (n int, err error) { … } func (ecr *expectContinueReader) Close() error { … } const TimeFormat … // appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat)) func appendTime(b []byte, t time.Time) []byte { … } var errTooLarge … // Read next request from connection. func (c *conn) readRequest(ctx context.Context) (w *response, err error) { … } // http1ServerSupportsRequest reports whether Go's HTTP/1.x server // supports the given request. func http1ServerSupportsRequest(req *Request) bool { … } func (w *response) Header() Header { … } const maxPostHandlerReadBytes … func checkWriteHeaderCode(code int) { … } // relevantCaller searches the call stack for the first function outside of net/http. // The purpose of this function is to provide more helpful error messages. func relevantCaller() runtime.Frame { … } func (w *response) WriteHeader(code int) { … } type extraHeader … var extraHeaderKeys … var headerContentLength … var headerDate … // Write writes the headers described in h to w. // // This method has a value receiver, despite the somewhat large size // of h, because it prevents an allocation. The escape analysis isn't // smart enough to realize this function doesn't mutate h. func (h extraHeader) Write(w *bufio.Writer) { … } // writeHeader finalizes the header sent to the client and writes it // to cw.res.conn.bufw. // // p is not written by writeHeader, but is the first chunk of the body // that will be written. It is sniffed for a Content-Type if none is // set explicitly. It's also used to set the Content-Length, if the // total body size was small and the handler has already finished // running. func (cw *chunkWriter) writeHeader(p []byte) { … } // foreachHeaderElement splits v according to the "#rule" construction // in RFC 7230 section 7 and calls fn for each non-empty element. func foreachHeaderElement(v string, fn func(string)) { … } // writeStatusLine writes an HTTP/1.x Status-Line (RFC 7230 Section 3.1.2) // to bw. is11 is whether the HTTP request is HTTP/1.1. false means HTTP/1.0. // code is the response status code. // scratch is an optional scratch buffer. If it has at least capacity 3, it's used. func writeStatusLine(bw *bufio.Writer, is11 bool, code int, scratch []byte) { … } // bodyAllowed reports whether a Write is allowed for this response type. // It's illegal to call this before the header has been flushed. func (w *response) bodyAllowed() bool { … } // The Life Of A Write is like this: // // Handler starts. No header has been sent. The handler can either // write a header, or just start writing. Writing before sending a header // sends an implicitly empty 200 OK header. // // If the handler didn't declare a Content-Length up front, we either // go into chunking mode or, if the handler finishes running before // the chunking buffer size, we compute a Content-Length and send that // in the header instead. // // Likewise, if the handler didn't set a Content-Type, we sniff that // from the initial chunk of output. // // The Writers are wired together like: // // 1. *response (the ResponseWriter) -> // 2. (*response).w, a [*bufio.Writer] of bufferBeforeChunkingSize bytes -> // 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type) // and which writes the chunk headers, if needed -> // 4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to -> // 5. checkConnErrorWriter{c}, which notes any non-nil error on Write // and populates c.werr with it if so, but otherwise writes to -> // 6. the rwc, the [net.Conn]. // // TODO(bradfitz): short-circuit some of the buffering when the // initial header contains both a Content-Type and Content-Length. // Also short-circuit in (1) when the header's been sent and not in // chunking mode, writing directly to (4) instead, if (2) has no // buffered data. More generally, we could short-circuit from (1) to // (3) even in chunking mode if the write size from (1) is over some // threshold and nothing is in (2). The answer might be mostly making // bufferBeforeChunkingSize smaller and having bufio's fast-paths deal // with this instead. func (w *response) Write(data []byte) (n int, err error) { … } func (w *response) WriteString(data string) (n int, err error) { … } // either dataB or dataS is non-zero. func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) { … } func (w *response) finishRequest() { … } // shouldReuseConnection reports whether the underlying TCP connection can be reused. // It must only be called after the handler is done executing. func (w *response) shouldReuseConnection() bool { … } func (w *response) closedRequestBodyEarly() bool { … } func (w *response) Flush() { … } func (w *response) FlushError() error { … } func (c *conn) finalFlush() { … } // Close the connection. func (c *conn) close() { … } var rstAvoidanceDelay … type closeWriter … var _ … // closeWriteAndWait flushes any outstanding data and sends a FIN packet (if // client is connected via TCP), signaling that we're done. We then // pause for a bit, hoping the client processes it before any // subsequent RST. // // See https://golang.org/issue/3595 func (c *conn) closeWriteAndWait() { … } // validNextProto reports whether the proto is a valid ALPN protocol name. // Everything is valid except the empty string and built-in protocol types, // so that those can't be overridden with alternate implementations. func validNextProto(proto string) bool { … } const runHooks … const skipHooks … func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) { … } func (c *conn) getState() (state ConnState, unixSec int64) { … } // badRequestError is a literal string (used by in the server in HTML, // unescaped) to tell the user why their request was bad. It should // be plain text without user info or other embedded errors. func badRequestError(e string) error { … } type statusError … func (e statusError) Error() string { … } var ErrAbortHandler … // isCommonNetReadError reports whether err is a common error // encountered during reading a request off the network when the // client has gone away or had its read fail somehow. This is used to // determine which logs are interesting enough to log about. func isCommonNetReadError(err error) bool { … } // Serve a new connection. func (c *conn) serve(ctx context.Context) { … } func (w *response) sendExpectationFailed() { … } // Hijack implements the [Hijacker.Hijack] method. Our response is both a [ResponseWriter] // and a [Hijacker]. func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) { … } func (w *response) CloseNotify() <-chan bool { … } func registerOnHitEOF(rc io.ReadCloser, fn func()) { … } // requestBodyRemains reports whether future calls to Read // on rc might yield more data. func requestBodyRemains(rc io.ReadCloser) bool { … } type HandlerFunc … // ServeHTTP calls f(w, r). func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { … } // Error replies to the request with the specified error message and HTTP code. // It does not otherwise end the request; the caller should ensure no further // writes are done to w. // The error message should be plain text. // // Error deletes the Content-Length header, // sets Content-Type to “text/plain; charset=utf-8”, // and sets X-Content-Type-Options to “nosniff”. // This configures the header properly for the error message, // in case the caller had set it up expecting a successful output. func Error(w ResponseWriter, error string, code int) { … } // NotFound replies to the request with an HTTP 404 not found error. func NotFound(w ResponseWriter, r *Request) { … } // NotFoundHandler returns a simple request handler // that replies to each request with a “404 page not found” reply. func NotFoundHandler() Handler { … } // StripPrefix returns a handler that serves HTTP requests by removing the // given prefix from the request URL's Path (and RawPath if set) and invoking // the handler h. StripPrefix handles a request for a path that doesn't begin // with prefix by replying with an HTTP 404 not found error. The prefix must // match exactly: if the prefix in the request contains escaped characters // the reply is also an HTTP 404 not found error. func StripPrefix(prefix string, h Handler) Handler { … } // Redirect replies to the request with a redirect to url, // which may be a path relative to the request path. // // The provided code should be in the 3xx range and is usually // [StatusMovedPermanently], [StatusFound] or [StatusSeeOther]. // // If the Content-Type header has not been set, [Redirect] sets it // to "text/html; charset=utf-8" and writes a small HTML body. // Setting the Content-Type header to any value, including nil, // disables that behavior. func Redirect(w ResponseWriter, r *Request, url string, code int) { … } var htmlReplacer … func htmlEscape(s string) string { … } type redirectHandler … func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) { … } // RedirectHandler returns a request handler that redirects // each request it receives to the given url using the given // status code. // // The provided code should be in the 3xx range and is usually // [StatusMovedPermanently], [StatusFound] or [StatusSeeOther]. func RedirectHandler(url string, code int) Handler { … } type ServeMux … // NewServeMux allocates and returns a new [ServeMux]. func NewServeMux() *ServeMux { … } var DefaultServeMux … var defaultServeMux … // cleanPath returns the canonical path for p, eliminating . and .. elements. func cleanPath(p string) string { … } // stripHostPort returns h without any trailing ":<port>". func stripHostPort(h string) string { … } // Handler returns the handler to use for the given request, // consulting r.Method, r.Host, and r.URL.Path. It always returns // a non-nil handler. If the path is not in its canonical form, the // handler will be an internally-generated handler that redirects // to the canonical path. If the host contains a port, it is ignored // when matching handlers. // // The path and host are used unchanged for CONNECT requests. // // Handler also returns the registered pattern that matches the // request or, in the case of internally-generated redirects, // the path that will match after following the redirect. // // If there is no registered handler that applies to the request, // Handler returns a “page not found” handler and an empty pattern. func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) { … } // findHandler finds a handler for a request. // If there is a matching handler, it returns it and the pattern that matched. // Otherwise it returns a Redirect or NotFound handler with the path that would match // after the redirect. func (mux *ServeMux) findHandler(r *Request) (h Handler, patStr string, _ *pattern, matches []string) { … } // matchOrRedirect looks up a node in the tree that matches the host, method and path. // // If the url argument is non-nil, handler also deals with trailing-slash // redirection: when a path doesn't match exactly, the match is tried again // after appending "/" to the path. If that second match succeeds, the last // return value is the URL to redirect to. func (mux *ServeMux) matchOrRedirect(host, method, path string, u *url.URL) (_ *routingNode, matches []string, redirectTo *url.URL) { … } // exactMatch reports whether the node's pattern exactly matches the path. // As a special case, if the node is nil, exactMatch return false. // // Before wildcards were introduced, it was clear that an exact match meant // that the pattern and path were the same string. The only other possibility // was that a trailing-slash pattern, like "/", matched a path longer than // it, like "/a". // // With wildcards, we define an inexact match as any one where a multi wildcard // matches a non-empty string. All other matches are exact. // For example, these are all exact matches: // // pattern path // /a /a // /{x} /a // /a/{$} /a/ // /a/ /a/ // // The last case has a multi wildcard (implicitly), but the match is exact because // the wildcard matches the empty string. // // Examples of matches that are not exact: // // pattern path // / /a // /a/{x...} /a/b func exactMatch(n *routingNode, path string) bool { … } // matchingMethods return a sorted list of all methods that would match with the given host and path. func (mux *ServeMux) matchingMethods(host, path string) []string { … } // ServeHTTP dispatches the request to the handler whose // pattern most closely matches the request URL. func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { … } // Handle registers the handler for the given pattern. // If the given pattern conflicts, with one that is already registered, Handle // panics. func (mux *ServeMux) Handle(pattern string, handler Handler) { … } // HandleFunc registers the handler function for the given pattern. // If the given pattern conflicts, with one that is already registered, HandleFunc // panics. func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { … } // Handle registers the handler for the given pattern in [DefaultServeMux]. // The documentation for [ServeMux] explains how patterns are matched. func Handle(pattern string, handler Handler) { … } // HandleFunc registers the handler function for the given pattern in [DefaultServeMux]. // The documentation for [ServeMux] explains how patterns are matched. func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { … } func (mux *ServeMux) register(pattern string, handler Handler) { … } func (mux *ServeMux) registerErr(patstr string, handler Handler) error { … } // Serve accepts incoming HTTP connections on the listener l, // creating a new service goroutine for each. The service goroutines // read requests and then call handler to reply to them. // // The handler is typically nil, in which case [DefaultServeMux] is used. // // HTTP/2 support is only enabled if the Listener returns [*tls.Conn] // connections and they were configured with "h2" in the TLS // Config.NextProtos. // // Serve always returns a non-nil error. func Serve(l net.Listener, handler Handler) error { … } // ServeTLS accepts incoming HTTPS connections on the listener l, // creating a new service goroutine for each. The service goroutines // read requests and then call handler to reply to them. // // The handler is typically nil, in which case [DefaultServeMux] is used. // // Additionally, files containing a certificate and matching private key // for the server must be provided. If the certificate is signed by a // certificate authority, the certFile should be the concatenation // of the server's certificate, any intermediates, and the CA's certificate. // // ServeTLS always returns a non-nil error. func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error { … } type Server … // Close immediately closes all active net.Listeners and any // connections in state [StateNew], [StateActive], or [StateIdle]. For a // graceful shutdown, use [Server.Shutdown]. // // Close does not attempt to close (and does not even know about) // any hijacked connections, such as WebSockets. // // Close returns any error returned from closing the [Server]'s // underlying Listener(s). func (s *Server) Close() error { … } const shutdownPollIntervalMax … // Shutdown gracefully shuts down the server without interrupting any // active connections. Shutdown works by first closing all open // listeners, then closing all idle connections, and then waiting // indefinitely for connections to return to idle and then shut down. // If the provided context expires before the shutdown is complete, // Shutdown returns the context's error, otherwise it returns any // error returned from closing the [Server]'s underlying Listener(s). // // When Shutdown is called, [Serve], [ListenAndServe], and // [ListenAndServeTLS] immediately return [ErrServerClosed]. Make sure the // program doesn't exit and waits instead for Shutdown to return. // // Shutdown does not attempt to close nor wait for hijacked // connections such as WebSockets. The caller of Shutdown should // separately notify such long-lived connections of shutdown and wait // for them to close, if desired. See [Server.RegisterOnShutdown] for a way to // register shutdown notification functions. // // Once Shutdown has been called on a server, it may not be reused; // future calls to methods such as Serve will return ErrServerClosed. func (s *Server) Shutdown(ctx context.Context) error { … } // RegisterOnShutdown registers a function to call on [Server.Shutdown]. // This can be used to gracefully shutdown connections that have // undergone ALPN protocol upgrade or that have been hijacked. // This function should start protocol-specific graceful shutdown, // but should not wait for shutdown to complete. func (s *Server) RegisterOnShutdown(f func()) { … } // closeIdleConns closes all idle connections and reports whether the // server is quiescent. func (s *Server) closeIdleConns() bool { … } func (s *Server) closeListenersLocked() error { … } type ConnState … const StateNew … const StateActive … const StateIdle … const StateHijacked … const StateClosed … var stateName … func (c ConnState) String() string { … } type serverHandler … // ServeHTTP should be an internal detail, // but widely used packages access it using linkname. // Notable members of the hall of shame include: // - github.com/erda-project/erda-infra // // Do not remove or change the type signature. // See go.dev/issue/67401. // //go:linkname badServeHTTP net/http.serverHandler.ServeHTTP func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) { … } func badServeHTTP(serverHandler, ResponseWriter, *Request) // AllowQuerySemicolons returns a handler that serves requests by converting any // unescaped semicolons in the URL query to ampersands, and invoking the handler h. // // This restores the pre-Go 1.17 behavior of splitting query parameters on both // semicolons and ampersands. (See golang.org/issue/25192). Note that this // behavior doesn't match that of many proxies, and the mismatch can lead to // security issues. // // AllowQuerySemicolons should be invoked before [Request.ParseForm] is called. func AllowQuerySemicolons(h Handler) Handler { … } // ListenAndServe listens on the TCP network address s.Addr and then // calls [Serve] to handle requests on incoming connections. // Accepted connections are configured to enable TCP keep-alives. // // If s.Addr is blank, ":http" is used. // // ListenAndServe always returns a non-nil error. After [Server.Shutdown] or [Server.Close], // the returned error is [ErrServerClosed]. func (s *Server) ListenAndServe() error { … } var testHookServerServe … // shouldConfigureHTTP2ForServe reports whether Server.Serve should configure // automatic HTTP/2. (which sets up the s.TLSNextProto map) func (s *Server) shouldConfigureHTTP2ForServe() bool { … } var ErrServerClosed … // Serve accepts incoming connections on the Listener l, creating a // new service goroutine for each. The service goroutines read requests and // then call s.Handler to reply to them. // // HTTP/2 support is only enabled if the Listener returns [*tls.Conn] // connections and they were configured with "h2" in the TLS // Config.NextProtos. // // Serve always returns a non-nil error and closes l. // After [Server.Shutdown] or [Server.Close], the returned error is [ErrServerClosed]. func (s *Server) Serve(l net.Listener) error { … } // ServeTLS accepts incoming connections on the Listener l, creating a // new service goroutine for each. The service goroutines perform TLS // setup and then read requests, calling s.Handler to reply to them. // // Files containing a certificate and matching private key for the // server must be provided if neither the [Server]'s // TLSConfig.Certificates, TLSConfig.GetCertificate nor // config.GetConfigForClient are populated. // If the certificate is signed by a certificate authority, the // certFile should be the concatenation of the server's certificate, // any intermediates, and the CA's certificate. // // ServeTLS always returns a non-nil error. After [Server.Shutdown] or [Server.Close], the // returned error is [ErrServerClosed]. func (s *Server) ServeTLS(l net.Listener, certFile, keyFile string) error { … } // trackListener adds or removes a net.Listener to the set of tracked // listeners. // // We store a pointer to interface in the map set, in case the // net.Listener is not comparable. This is safe because we only call // trackListener via Serve and can track+defer untrack the same // pointer to local variable there. We never need to compare a // Listener from another caller. // // It reports whether the server is still up (not Shutdown or Closed). func (s *Server) trackListener(ln *net.Listener, add bool) bool { … } func (s *Server) trackConn(c *conn, add bool) { … } func (s *Server) idleTimeout() time.Duration { … } func (s *Server) readHeaderTimeout() time.Duration { … } func (s *Server) doKeepAlives() bool { … } func (s *Server) shuttingDown() bool { … } // SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled. // By default, keep-alives are always enabled. Only very // resource-constrained environments or servers in the process of // shutting down should disable them. func (s *Server) SetKeepAlivesEnabled(v bool) { … } func (s *Server) logf(format string, args ...any) { … } // logf prints to the ErrorLog of the *Server associated with request r // via ServerContextKey. If there's no associated server, or if ErrorLog // is nil, logging is done via the log package's standard logger. func logf(r *Request, format string, args ...any) { … } // ListenAndServe listens on the TCP network address addr and then calls // [Serve] with handler to handle requests on incoming connections. // Accepted connections are configured to enable TCP keep-alives. // // The handler is typically nil, in which case [DefaultServeMux] is used. // // ListenAndServe always returns a non-nil error. func ListenAndServe(addr string, handler Handler) error { … } // ListenAndServeTLS acts identically to [ListenAndServe], except that it // expects HTTPS connections. Additionally, files containing a certificate and // matching private key for the server must be provided. If the certificate // is signed by a certificate authority, the certFile should be the concatenation // of the server's certificate, any intermediates, and the CA's certificate. func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error { … } // ListenAndServeTLS listens on the TCP network address s.Addr and // then calls [ServeTLS] to handle requests on incoming TLS connections. // Accepted connections are configured to enable TCP keep-alives. // // Filenames containing a certificate and matching private key for the // server must be provided if neither the [Server]'s TLSConfig.Certificates // nor TLSConfig.GetCertificate are populated. If the certificate is // signed by a certificate authority, the certFile should be the // concatenation of the server's certificate, any intermediates, and // the CA's certificate. // // If s.Addr is blank, ":https" is used. // // ListenAndServeTLS always returns a non-nil error. After [Server.Shutdown] or // [Server.Close], the returned error is [ErrServerClosed]. func (s *Server) ListenAndServeTLS(certFile, keyFile string) error { … } // setupHTTP2_ServeTLS conditionally configures HTTP/2 on // s and reports whether there was an error setting it up. If it is // not configured for policy reasons, nil is returned. func (s *Server) setupHTTP2_ServeTLS() error { … } // setupHTTP2_Serve is called from (*Server).Serve and conditionally // configures HTTP/2 on s using a more conservative policy than // setupHTTP2_ServeTLS because Serve is called after tls.Listen, // and may be called concurrently. See shouldConfigureHTTP2ForServe. // // The tests named TestTransportAutomaticHTTP2* and // TestConcurrentServerServe in server_test.go demonstrate some // of the supported use cases and motivations. func (s *Server) setupHTTP2_Serve() error { … } func (s *Server) onceSetNextProtoDefaults_Serve() { … } var http2server … // onceSetNextProtoDefaults configures HTTP/2, if the user hasn't // configured otherwise. (by setting s.TLSNextProto non-nil) // It must only be called via s.nextProtoOnce (use s.setupHTTP2_*). func (s *Server) onceSetNextProtoDefaults() { … } // TimeoutHandler returns a [Handler] that runs h with the given time limit. // // The new Handler calls h.ServeHTTP to handle each request, but if a // call runs for longer than its time limit, the handler responds with // a 503 Service Unavailable error and the given message in its body. // (If msg is empty, a suitable default message will be sent.) // After such a timeout, writes by h to its [ResponseWriter] will return // [ErrHandlerTimeout]. // // TimeoutHandler supports the [Pusher] interface but does not support // the [Hijacker] or [Flusher] interfaces. func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler { … } var ErrHandlerTimeout … type timeoutHandler … func (h *timeoutHandler) errorBody() string { … } func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) { … } type timeoutWriter … var _ … // Push implements the [Pusher] interface. func (tw *timeoutWriter) Push(target string, opts *PushOptions) error { … } func (tw *timeoutWriter) Header() Header { … } func (tw *timeoutWriter) Write(p []byte) (int, error) { … } func (tw *timeoutWriter) writeHeaderLocked(code int) { … } func (tw *timeoutWriter) WriteHeader(code int) { … } type onceCloseListener … func (oc *onceCloseListener) Close() error { … } func (oc *onceCloseListener) close() { … } type globalOptionsHandler … func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) { … } type initALPNRequest … // BaseContext is an exported but unadvertised [http.Handler] method // recognized by x/net/http2 to pass down a context; the TLSNextProto // API predates context support so we shoehorn through the only // interface we have available. func (h initALPNRequest) BaseContext() context.Context { … } func (h initALPNRequest) ServeHTTP(rw ResponseWriter, req *Request) { … } type loggingConn … var uniqNameMu … var uniqNameNext … func newLoggingConn(baseName string, c net.Conn) net.Conn { … } func (c *loggingConn) Write(p []byte) (n int, err error) { … } func (c *loggingConn) Read(p []byte) (n int, err error) { … } func (c *loggingConn) Close() (err error) { … } type checkConnErrorWriter … func (w checkConnErrorWriter) Write(p []byte) (n int, err error) { … } func numLeadingCRorLF(v []byte) (n int) { … } // tlsRecordHeaderLooksLikeHTTP reports whether a TLS record header // looks like it might've been a misdirected plaintext HTTP request. func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool { … } // MaxBytesHandler returns a [Handler] that runs h with its [ResponseWriter] and [Request.Body] wrapped by a MaxBytesReader. func MaxBytesHandler(h Handler, n int64) Handler { … }