Source file src/net/http/internal/http3/server.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package http3
     6  
     7  import (
     8  	"context"
     9  	"crypto/tls"
    10  	"errors"
    11  	"fmt"
    12  	"maps"
    13  	"net"
    14  	"net/http"
    15  	"net/textproto"
    16  	"os"
    17  	"slices"
    18  	"strconv"
    19  	"strings"
    20  	"sync"
    21  	"time"
    22  
    23  	"golang.org/x/net/http/httpguts"
    24  	"net/http/internal/httpcommon"
    25  	"golang.org/x/net/quic"
    26  )
    27  
    28  // A server is an HTTP/3 server.
    29  // The zero value for server is a valid server.
    30  type server struct {
    31  	srv1 *http.Server
    32  	opts ServerOpts
    33  
    34  	initOnce sync.Once
    35  
    36  	// connClosed is used to signal that a connection has been unregistered
    37  	// from activeConns. That way, when shutting down gracefully, the server
    38  	// can avoid busy-waiting for activeConns to be empty.
    39  	connClosed  chan any
    40  	mu          sync.Mutex // Guards fields below.
    41  	activeConns map[*serverConn]struct{}
    42  }
    43  
    44  // netHTTPServer implements the net/http.http3Server interface,
    45  // allowing our HTTP/3 server to integrate with net/http.
    46  type netHTTPServer struct {
    47  	*server
    48  }
    49  
    50  // Implement net.Listener, so we can pass a netHTTPServer to net/http.Server.Serve.
    51  func (netHTTPServer) Accept() (net.Conn, error) { return nil, net.ErrClosed }
    52  func (netHTTPServer) Close() error              { return nil }
    53  func (netHTTPServer) Addr() net.Addr            { return nil }
    54  
    55  // ServeHTTP3 starts serving HTTP/3 on a UDP port.
    56  //
    57  // The ctx parameter is used as the base context for request handlers
    58  // for requests receieved via this port.
    59  func (s netHTTPServer) ServeHTTP3(ctx context.Context, conn net.PacketConn, tlsConfig *tls.Config, h http.Handler) error {
    60  	s.init()
    61  	e, err := quic.NewEndpoint(conn, newQUICConfig(s.opts.QUICConfig, tlsConfig))
    62  	if err != nil {
    63  		return err
    64  	}
    65  	return s.serve(ctx, e, h)
    66  }
    67  
    68  // Shutdown shuts down the server.
    69  func (s netHTTPServer) Shutdown(ctx context.Context) error {
    70  	s.shutdown(ctx)
    71  	return nil
    72  }
    73  
    74  type ServerOpts struct {
    75  	// QUICConfig is the QUIC configuration used by the server.
    76  	// QUICConfig may be nil and should not be modified after calling
    77  	// RegisterServer.
    78  	// If QUICConfig.TLSConfig is nil, the TLSConfig of the net/http Server
    79  	// given to RegisterServer will be used.
    80  	QUICConfig *quic.Config
    81  }
    82  
    83  // RegisterServer adds HTTP/3 support to a net/http Server.
    84  //
    85  // RegisterServer must be called before s begins serving, and only affects
    86  // s.ListenAndServeTLS.
    87  func RegisterServer(s *http.Server, opts ServerOpts) error {
    88  	if err := s.Serve(netHTTPServer{&server{
    89  		opts: opts,
    90  		srv1: s,
    91  	}}); err != nil {
    92  		return errors.New("http3: net/http does not support HTTP/3")
    93  	}
    94  	return nil
    95  }
    96  
    97  func (s *server) init() {
    98  	s.initOnce.Do(func() {
    99  		s.activeConns = make(map[*serverConn]struct{})
   100  		s.connClosed = make(chan any, 1)
   101  	})
   102  }
   103  
   104  // serve accepts incoming connections on the QUIC endpoint e,
   105  // and handles requests from those connections.
   106  func (s *server) serve(ctx context.Context, e *quic.Endpoint, h http.Handler) error {
   107  	s.init()
   108  	defer e.Close(canceledCtx)
   109  	for {
   110  		qconn, err := e.Accept(ctx)
   111  		if err != nil {
   112  			return err
   113  		}
   114  		go s.newServerConn(ctx, qconn, h)
   115  	}
   116  }
   117  
   118  // shutdown attempts a graceful shutdown for the server.
   119  func (s *server) shutdown(ctx context.Context) {
   120  	// Set a reasonable default in case ctx is nil.
   121  	if ctx == nil {
   122  		var cancel context.CancelFunc
   123  		ctx, cancel = context.WithTimeout(context.Background(), time.Second)
   124  		defer cancel()
   125  	}
   126  
   127  	// Send GOAWAY frames to all active connections to give a chance for them
   128  	// to gracefully terminate.
   129  	s.mu.Lock()
   130  	for sc := range s.activeConns {
   131  		// TODO: Modify x/net/quic stream API so that write errors from context
   132  		// deadline are sticky.
   133  		go sc.sendGoaway()
   134  	}
   135  	s.mu.Unlock()
   136  
   137  	// Complete shutdown as soon as there are no more active connections or ctx
   138  	// is done, whichever comes first.
   139  	defer func() {
   140  		s.mu.Lock()
   141  		defer s.mu.Unlock()
   142  		for sc := range s.activeConns {
   143  			sc.abort(&connectionError{
   144  				code:    errH3NoError,
   145  				message: "server is shutting down",
   146  			})
   147  		}
   148  	}()
   149  	noMoreConns := func() bool {
   150  		s.mu.Lock()
   151  		defer s.mu.Unlock()
   152  		return len(s.activeConns) == 0
   153  	}
   154  	for {
   155  		if noMoreConns() {
   156  			return
   157  		}
   158  		select {
   159  		case <-ctx.Done():
   160  			return
   161  		case <-s.connClosed:
   162  		}
   163  	}
   164  }
   165  
   166  func (s *server) registerConn(sc *serverConn) {
   167  	s.mu.Lock()
   168  	defer s.mu.Unlock()
   169  	s.activeConns[sc] = struct{}{}
   170  }
   171  
   172  func (s *server) unregisterConn(sc *serverConn) {
   173  	s.mu.Lock()
   174  	delete(s.activeConns, sc)
   175  	s.mu.Unlock()
   176  	select {
   177  	case s.connClosed <- struct{}{}:
   178  	default:
   179  		// Channel already full. No need to send more values since we are just
   180  		// using this channel as a simpler sync.Cond.
   181  	}
   182  }
   183  
   184  func (s *server) readHeaderTimeout() time.Duration {
   185  	if s.srv1 == nil || s.srv1.ReadHeaderTimeout == 0 {
   186  		return s.readTimeout()
   187  	}
   188  	return s.srv1.ReadHeaderTimeout
   189  }
   190  
   191  func (s *server) readTimeout() time.Duration {
   192  	if s.srv1 == nil {
   193  		return 0
   194  	}
   195  	return s.srv1.ReadTimeout
   196  }
   197  
   198  func (s *server) writeTimeout() time.Duration {
   199  	if s.srv1 == nil {
   200  		return 0
   201  	}
   202  	return s.srv1.WriteTimeout
   203  }
   204  
   205  // TODO: this is currently unused, enforce it.
   206  func (s *server) idleTimeout() time.Duration {
   207  	if s.srv1 == nil || s.srv1.IdleTimeout == 0 {
   208  		return s.readTimeout()
   209  	}
   210  	return s.srv1.IdleTimeout
   211  }
   212  
   213  type serverConn struct {
   214  	qconn   *quic.Conn
   215  	srv     *server
   216  	baseCtx context.Context
   217  	handler http.Handler
   218  
   219  	genericConn // for handleUnidirectionalStream
   220  	enc         qpackEncoder
   221  	dec         qpackDecoder
   222  
   223  	maxHeaderBytes      int64
   224  	maxHeaderValueCount int64
   225  
   226  	// For handling shutdown.
   227  	controlStream      *stream
   228  	mu                 sync.Mutex // Guards everything below.
   229  	maxRequestStreamID int64
   230  	goawaySent         bool
   231  }
   232  
   233  // newServerConn handles a new connection.
   234  // The baseCtx parameter is the base context for request handlers on this connection.
   235  func (s *server) newServerConn(baseCtx context.Context, qconn *quic.Conn, h http.Handler) {
   236  	sc := &serverConn{
   237  		qconn:          qconn,
   238  		srv:            s,
   239  		baseCtx:        baseCtx,
   240  		handler:        h,
   241  		maxHeaderBytes: int64(s.srv1.MaxHeaderBytes),
   242  		// TODO: When we only support go1.27.
   243  		//maxHeaderValueCount: int64(s.srv1.MaxHeaderValueCount),
   244  	}
   245  
   246  	// Should we permit disabling these limits? For now, we do not.
   247  	if sc.maxHeaderBytes <= 0 {
   248  		sc.maxHeaderBytes = int64(http.DefaultMaxHeaderBytes)
   249  	}
   250  	// TODO: When we only support go1.27.
   251  	// if sc.maxHeaderValueCount <= 0 {
   252  	// 	sc.maxHeaderValueCount = int64(http.DefaultMaxHeaderValueCount)
   253  	// }
   254  
   255  	s.registerConn(sc)
   256  	defer s.unregisterConn(sc)
   257  	sc.enc.init()
   258  
   259  	// Create control stream and send SETTINGS frame.
   260  	// TODO: Time out on creating stream.
   261  	var err error
   262  	sc.controlStream, err = newConnStream(context.Background(), sc.qconn, streamTypeControl)
   263  	if err != nil {
   264  		return
   265  	}
   266  	sc.controlStream.writeSettings(
   267  		settingsMaxFieldSectionSize, sc.maxHeaderBytes,
   268  	)
   269  	sc.controlStream.Flush()
   270  
   271  	sc.acceptStreams(sc.qconn, sc)
   272  }
   273  
   274  func (sc *serverConn) handleControlStream(st *stream) error {
   275  	// "A SETTINGS frame MUST be sent as the first frame of each control stream [...]"
   276  	// https://www.rfc-editor.org/rfc/rfc9114.html#section-7.2.4-2
   277  	if err := st.readSettings(func(settingsType, settingsValue int64) error {
   278  		switch settingsType {
   279  		case settingsMaxFieldSectionSize:
   280  			_ = settingsValue // TODO
   281  		case settingsQPACKMaxTableCapacity:
   282  			_ = settingsValue // TODO
   283  		case settingsQPACKBlockedStreams:
   284  			_ = settingsValue // TODO
   285  		default:
   286  			// Unknown settings types are ignored.
   287  		}
   288  		return nil
   289  	}); err != nil {
   290  		return err
   291  	}
   292  
   293  	for {
   294  		ftype, err := st.readFrameHeader()
   295  		if err != nil {
   296  			return err
   297  		}
   298  		switch ftype {
   299  		case frameTypeCancelPush:
   300  			// "If a server receives a CANCEL_PUSH frame for a push ID
   301  			// that has not yet been mentioned by a PUSH_PROMISE frame,
   302  			// this MUST be treated as a connection error of type H3_ID_ERROR."
   303  			// https://www.rfc-editor.org/rfc/rfc9114.html#section-7.2.3-8
   304  			return &connectionError{
   305  				code:    errH3IDError,
   306  				message: "CANCEL_PUSH for unsent push ID",
   307  			}
   308  		case frameTypeGoaway:
   309  			return errH3NoError
   310  		default:
   311  			// Unknown frames are ignored.
   312  			if err := st.discardUnknownFrame(ftype); err != nil {
   313  				return err
   314  			}
   315  		}
   316  	}
   317  }
   318  
   319  func (sc *serverConn) handleEncoderStream(*stream) error {
   320  	// TODO
   321  	return nil
   322  }
   323  
   324  func (sc *serverConn) handleDecoderStream(*stream) error {
   325  	// TODO
   326  	return nil
   327  }
   328  
   329  func (sc *serverConn) handlePushStream(*stream) error {
   330  	// "[...] if a server receives a client-initiated push stream,
   331  	// this MUST be treated as a connection error of type H3_STREAM_CREATION_ERROR."
   332  	// https://www.rfc-editor.org/rfc/rfc9114.html#section-6.2.2-3
   333  	return &connectionError{
   334  		code:    errH3StreamCreationError,
   335  		message: "client created push stream",
   336  	}
   337  }
   338  
   339  // hasDisallowedConnectionHeader reports whether h contains connection headers
   340  // that are not allowed in HTTP/3:
   341  //
   342  // "An endpoint MUST NOT generate an HTTP/3 field section containing
   343  // connection-specific fields; any message containing connection-specific
   344  // fields MUST be treated as malformed."
   345  //
   346  // "The only exception to this is the TE header field, which MAY be present in
   347  // an HTTP/3 request header; when it is, it MUST NOT contain any value other
   348  // than "trailers"."
   349  func hasDisallowedConnectionHeader(h http.Header) bool {
   350  	neverAllowed := []string{
   351  		"Connection",
   352  		"Keep-Alive",
   353  		"Proxy-Connection",
   354  		"Transfer-Encoding",
   355  		"Upgrade",
   356  	}
   357  	for _, k := range neverAllowed {
   358  		if _, ok := h[k]; ok {
   359  			return true
   360  		}
   361  	}
   362  	if te, ok := h["Te"]; ok && (len(te) != 1 || te[0] != "trailers") {
   363  		return true
   364  	}
   365  	return false
   366  }
   367  
   368  type pseudoHeader struct {
   369  	method    string
   370  	scheme    string
   371  	path      string
   372  	authority string
   373  }
   374  
   375  func (sc *serverConn) parseHeader(st *stream) (http.Header, pseudoHeader, error) {
   376  	ftype, err := st.readFrameHeader()
   377  	if err != nil {
   378  		return nil, pseudoHeader{}, err
   379  	}
   380  	if ftype != frameTypeHeaders {
   381  		return nil, pseudoHeader{}, &streamError{errH3MessageError, "received other frames when expecting HEADERS"}
   382  	}
   383  	if st.lim > sc.maxHeaderBytes {
   384  		// If the encoded headers exceed the limit, just reject the request out of hand.
   385  		// This lets us safely check limits in the dec.decode callback below,
   386  		// since the maximum Huffman expansion factor is only ~1.6x.
   387  		return nil, pseudoHeader{}, &streamError{errH3RequestRejected, "headers too large"}
   388  	}
   389  	header := make(http.Header)
   390  	valueCount := int64(0)
   391  	totalSize := int64(0)
   392  	var pHeader pseudoHeader
   393  	var dec qpackDecoder
   394  	var hasMethod, hasScheme, hasPath, hasAuthority bool
   395  	if err := dec.decode(st, func(_ indexType, name, value string) error {
   396  		totalSize += int64(len(name)) + int64(len(value)) + 32 // RFC 9114 Section 4.2.2
   397  		valueCount++
   398  		if totalSize > sc.maxHeaderBytes {
   399  			return &streamError{errH3RequestRejected, "headers too large"}
   400  		}
   401  		// TODO: When we only support go1.27.
   402  		//if valueCount > sc.maxHeaderValueCount {
   403  		//	return &streamError{errH3RequestRejected, "headers too large"}
   404  		//}
   405  		if !httpguts.ValidHeaderFieldValue(value) {
   406  			return &streamError{errH3MessageError, "invalid field value"}
   407  		}
   408  		if name == "" || (name[0] == ':' && value == "") {
   409  			// Reject 0-length pseudo-header values up front,
   410  			// to avoid any confusion down the line between
   411  			// "present but zero-length" and "absent".
   412  			return &streamError{errH3MessageError, "invalid field"}
   413  		}
   414  		switch name {
   415  		case ":method":
   416  			if hasMethod {
   417  				return &streamError{errH3MessageError, "duplicate :method"}
   418  			}
   419  			hasMethod = true
   420  			pHeader.method = value
   421  		case ":scheme":
   422  			if hasScheme {
   423  				return &streamError{errH3MessageError, "duplicate :scheme"}
   424  			}
   425  			hasScheme = true
   426  			pHeader.scheme = value
   427  		case ":path":
   428  			if hasPath {
   429  				return &streamError{errH3MessageError, "duplicate :path"}
   430  			}
   431  			hasPath = true
   432  			pHeader.path = value
   433  		case ":authority":
   434  			if hasAuthority {
   435  				return &streamError{errH3MessageError, "duplicate :authority"}
   436  			}
   437  			hasAuthority = true
   438  			pHeader.authority = value
   439  		default:
   440  			if !validWireHeaderFieldName(name) {
   441  				return &streamError{errH3MessageError, "invalid field name"}
   442  			}
   443  			header.Add(name, value)
   444  		}
   445  		return nil
   446  	}); err != nil {
   447  		return nil, pseudoHeader{}, err
   448  	}
   449  	if err := st.endFrame(); err != nil {
   450  		return nil, pseudoHeader{}, err
   451  	}
   452  	if hasDisallowedConnectionHeader(header) {
   453  		return nil, pseudoHeader{}, &streamError{errH3MessageError, "invalid connection-related header"}
   454  	}
   455  
   456  	// "All HTTP/3 requests MUST include exactly one value for the :method,
   457  	// :scheme, and :path pseudo-header fields, unless the request is a CONNECT
   458  	// request"
   459  	//
   460  	// "A CONNECT request MUST be constructed as follows:
   461  	// - The :method pseudo-header field is set to "CONNECT"
   462  	// - The :scheme and :path pseudo-header fields are omitted
   463  	// - The :authority pseudo-header field contains the host and port to connect to"
   464  	if !hasMethod {
   465  		return nil, pseudoHeader{}, &streamError{errH3MessageError, "missing :method"}
   466  	}
   467  	if pHeader.method != "CONNECT" && (!hasScheme || !hasPath) {
   468  		return nil, pseudoHeader{}, &streamError{errH3MessageError, "missing :scheme or :path for non-CONNECT requests"}
   469  	}
   470  	if pHeader.method == "CONNECT" && (hasScheme || hasPath || !hasAuthority) {
   471  		return nil, pseudoHeader{}, &streamError{
   472  			errH3MessageError, "CONNECT request must only have :method and :authority pseudo-headers",
   473  		}
   474  	}
   475  	return header, pHeader, nil
   476  }
   477  
   478  func (sc *serverConn) sendGoaway() {
   479  	sc.mu.Lock()
   480  	if sc.goawaySent || sc.controlStream == nil {
   481  		sc.mu.Unlock()
   482  		return
   483  	}
   484  	sc.goawaySent = true
   485  	sc.mu.Unlock()
   486  
   487  	// No lock in this section in case writing to stream blocks. This is safe
   488  	// since sc.maxRequestStreamID is only updated when sc.goawaySent is false.
   489  	sc.controlStream.writeVarint(int64(frameTypeGoaway))
   490  	sc.controlStream.writeVarint(int64(sizeVarint(uint64(sc.maxRequestStreamID))))
   491  	sc.controlStream.writeVarint(sc.maxRequestStreamID)
   492  	sc.controlStream.Flush()
   493  }
   494  
   495  // requestShouldGoAway returns true if st has a stream ID that is equal or
   496  // greater than the ID we have sent in a GOAWAY frame, if any.
   497  func (sc *serverConn) requestShouldGoaway(st *stream) bool {
   498  	sc.mu.Lock()
   499  	defer sc.mu.Unlock()
   500  	if sc.goawaySent {
   501  		return st.stream.ID() >= sc.maxRequestStreamID
   502  	} else {
   503  		sc.maxRequestStreamID = max(sc.maxRequestStreamID, st.stream.ID())
   504  		return false
   505  	}
   506  }
   507  
   508  func (sc *serverConn) handleRequestStream(st *stream) error {
   509  	if sc.requestShouldGoaway(st) {
   510  		return &streamError{
   511  			code:    errH3RequestRejected,
   512  			message: "GOAWAY request with equal or lower ID than the stream has been sent",
   513  		}
   514  	}
   515  
   516  	readStartTime := time.Now()
   517  	if t := sc.srv.readHeaderTimeout(); t > 0 {
   518  		st.readDeadline.set(readStartTime.Add(t))
   519  	}
   520  	header, pHeader, err := sc.parseHeader(st)
   521  	if err != nil {
   522  		if errors.Is(err, os.ErrDeadlineExceeded) {
   523  			return &streamError{
   524  				code:    errH3RequestRejected,
   525  				message: "exceeded deadline while parsing header",
   526  			}
   527  		}
   528  		return err
   529  	}
   530  
   531  	if t := sc.srv.readTimeout(); t > 0 {
   532  		st.readDeadline.set(readStartTime.Add(t))
   533  	} else {
   534  		st.readDeadline.set(time.Time{})
   535  	}
   536  	reqInfo := httpcommon.NewServerRequest(httpcommon.ServerRequestParam{
   537  		Method:    pHeader.method,
   538  		Scheme:    pHeader.scheme,
   539  		Authority: pHeader.authority,
   540  		Path:      pHeader.path,
   541  		Header:    header,
   542  	})
   543  	if reqInfo.InvalidReason != "" {
   544  		return &streamError{
   545  			code:    errH3MessageError,
   546  			message: reqInfo.InvalidReason,
   547  		}
   548  	}
   549  
   550  	contentLength := int64(-1)
   551  	if n, err := strconv.ParseUint(header.Get("Content-Length"), 10, 63); err == nil {
   552  		contentLength = int64(n)
   553  	}
   554  
   555  	req := (&http.Request{
   556  		Proto:         "HTTP/3.0",
   557  		Method:        pHeader.method,
   558  		Host:          reqInfo.Host,
   559  		URL:           reqInfo.URL,
   560  		RequestURI:    reqInfo.RequestURI,
   561  		Trailer:       reqInfo.Trailer,
   562  		ProtoMajor:    3,
   563  		RemoteAddr:    sc.qconn.RemoteAddr().String(),
   564  		Header:        header,
   565  		ContentLength: contentLength,
   566  	}).WithContext(sc.baseCtx)
   567  
   568  	rw := &responseWriter{
   569  		st:             st,
   570  		headers:        make(http.Header),
   571  		trailer:        make(http.Header),
   572  		bb:             make(bodyBuffer, 0, defaultBodyBufferCap),
   573  		cannotHaveBody: req.Method == "HEAD",
   574  		bw: &bodyWriter{
   575  			st:     st,
   576  			remain: -1,
   577  			flush:  false,
   578  			name:   "response",
   579  			enc:    &sc.enc,
   580  		},
   581  	}
   582  
   583  	if contentLength != 0 || len(reqInfo.Trailer) != 0 {
   584  		req.Body = &serverRequestReader{
   585  			rw: rw,
   586  			br: bodyReader{
   587  				st:            st,
   588  				remain:        contentLength,
   589  				trailer:       reqInfo.Trailer,
   590  				filterTrailer: true,
   591  			},
   592  			needsContinue: reqInfo.NeedsContinue,
   593  		}
   594  		defer req.Body.Close()
   595  	} else {
   596  		req.Body = http.NoBody
   597  	}
   598  
   599  	// TODO: handle panic coming from the HTTP handler.
   600  	if t := sc.srv.writeTimeout(); t > 0 {
   601  		st.writeDeadline.set(time.Now().Add(t))
   602  	}
   603  	sc.handler.ServeHTTP(rw, req)
   604  	return rw.close()
   605  }
   606  
   607  // abort closes the connection with an error.
   608  func (sc *serverConn) abort(err error) {
   609  	if e, ok := err.(*connectionError); ok {
   610  		sc.qconn.Abort(&quic.ConnectionCloseError{
   611  			Code:   uint64(e.code),
   612  			Reason: e.message,
   613  		})
   614  	} else {
   615  		sc.qconn.Abort(err)
   616  	}
   617  }
   618  
   619  // responseCanHaveBody reports whether a given response status code permits a
   620  // body. See RFC 7230, section 3.3.
   621  func responseCanHaveBody(status int) bool {
   622  	switch {
   623  	case status >= 100 && status <= 199:
   624  		return false
   625  	case status == 204:
   626  		return false
   627  	case status == 304:
   628  		return false
   629  	}
   630  	return true
   631  }
   632  
   633  // trailerPrefix is a magic prefix for [responseWriter.Header] map keys that,
   634  // if present, signals that the map entry is actually for the response
   635  // trailers, and not the response headers. See [net/http.TrailerPrefix] for
   636  // details.
   637  const trailerPrefix = "Trailer:"
   638  
   639  type responseWriter struct {
   640  	st             *stream
   641  	bw             *bodyWriter
   642  	mu             sync.Mutex
   643  	headers        http.Header
   644  	snapHeaders    http.Header // Snapshot of headers at WriteHeader time
   645  	trailer        http.Header
   646  	bb             bodyBuffer
   647  	wroteHeader    bool  // Non-1xx header has been (logically) written.
   648  	statusCode     int   // Non-1xx status of the response that will be sent in HEADERS frame. Zero means none has been set.
   649  	sent100        bool  // Status 100 has been sent by the server.
   650  	cannotHaveBody bool  // Response should not have a body (e.g. response to a HEAD request).
   651  	bodyLenLeft    int64 // How much of the content body is left to be sent, set via "Content-Length" header. -1 if unknown.
   652  }
   653  
   654  func (rw *responseWriter) Header() http.Header {
   655  	return rw.headers
   656  }
   657  
   658  // prepareTrailerForWriteLocked populates any pre-declared trailer header with
   659  // its value, and passes it to bodyWriter so it can be written after body EOF.
   660  // Caller must hold rw.mu.
   661  func (rw *responseWriter) prepareTrailerForWriteLocked() {
   662  	for name := range rw.trailer {
   663  		if val, ok := rw.headers[name]; ok {
   664  			rw.trailer[name] = val
   665  		} else {
   666  			delete(rw.trailer, name)
   667  		}
   668  	}
   669  	for name, vals := range rw.headers {
   670  		if name, found := strings.CutPrefix(name, trailerPrefix); found {
   671  			name = textproto.CanonicalMIMEHeaderKey(textproto.TrimString(name))
   672  			rw.trailer[name] = vals
   673  		}
   674  	}
   675  	if len(rw.trailer) > 0 {
   676  		rw.bw.trailer = rw.trailer
   677  	}
   678  }
   679  
   680  // writeHeaderLockedOnce writes the final response header. If rw.wroteHeader is
   681  // true, calling this method is a no-op. Sending informational status headers
   682  // should be done using writeInfoHeaderLocked, rather than this method.
   683  // Caller must hold rw.mu.
   684  func (rw *responseWriter) writeHeaderLockedOnce() {
   685  	if rw.wroteHeader {
   686  		return
   687  	}
   688  	if !responseCanHaveBody(rw.statusCode) {
   689  		rw.cannotHaveBody = true
   690  	}
   691  	// If there is any Trailer declared, save them so we know which trailers
   692  	// have been pre-declared. Also, write back the extracted value, which is
   693  	// canonicalized, for consistency.
   694  	if _, ok := rw.snapHeaders["Trailer"]; ok {
   695  		extractTrailerFromHeader(rw.snapHeaders, rw.trailer)
   696  		rw.snapHeaders.Set("Trailer", strings.Join(slices.Sorted(maps.Keys(rw.trailer)), ", "))
   697  	}
   698  
   699  	rw.bb.inferHeader(rw.snapHeaders, rw.statusCode)
   700  	encHeaders := rw.bw.enc.encode(func(f func(itype indexType, name, value string)) {
   701  		f(mayIndex, ":status", strconv.Itoa(rw.statusCode))
   702  		for name, values := range rw.snapHeaders {
   703  			if !httpguts.ValidHeaderFieldName(name) {
   704  				continue
   705  			}
   706  			for _, val := range values {
   707  				if !httpguts.ValidHeaderFieldValue(val) {
   708  					continue
   709  				}
   710  				// Issue #71374: Consider supporting never-indexed fields.
   711  				f(mayIndex, name, val)
   712  			}
   713  		}
   714  	})
   715  
   716  	rw.st.writeVarint(int64(frameTypeHeaders))
   717  	rw.st.writeVarint(int64(len(encHeaders)))
   718  	rw.st.Write(encHeaders)
   719  	rw.wroteHeader = true
   720  }
   721  
   722  // writeHeaderLocked writes informational status headers (i.e. status 1XX).
   723  // If a non-informational status header has been written via
   724  // writeHeaderLockedOnce, this method is a no-op.
   725  // Caller must hold rw.mu.
   726  func (rw *responseWriter) writeHeaderLocked(statusCode int) {
   727  	if rw.wroteHeader {
   728  		return
   729  	}
   730  	if statusCode == 100 {
   731  		if rw.sent100 {
   732  			return
   733  		}
   734  		rw.sent100 = true
   735  	}
   736  	encHeaders := rw.bw.enc.encode(func(f func(itype indexType, name, value string)) {
   737  		f(mayIndex, ":status", strconv.Itoa(statusCode))
   738  		for name, values := range rw.headers {
   739  			if name == "Content-Length" || name == "Transfer-Encoding" {
   740  				continue
   741  			}
   742  			if !httpguts.ValidHeaderFieldName(name) {
   743  				continue
   744  			}
   745  			for _, val := range values {
   746  				if !httpguts.ValidHeaderFieldValue(val) {
   747  					continue
   748  				}
   749  				// Issue #71374: Consider supporting never-indexed fields.
   750  				f(mayIndex, name, val)
   751  			}
   752  		}
   753  	})
   754  	rw.st.writeVarint(int64(frameTypeHeaders))
   755  	rw.st.writeVarint(int64(len(encHeaders)))
   756  	rw.st.Write(encHeaders)
   757  }
   758  
   759  func isInfoStatus(status int) bool {
   760  	return status >= 100 && status < 200
   761  }
   762  
   763  // checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
   764  func checkWriteHeaderCode(code int) {
   765  	// Issue 22880: require valid WriteHeader status codes.
   766  	// For now we only enforce that it's three digits.
   767  	// In the future we might block things over 599 (600 and above aren't defined
   768  	// at http://httpwg.org/specs/rfc7231.html#status.codes).
   769  	// But for now any three digits.
   770  	//
   771  	// We used to send "HTTP/1.1 000 0" on the wire in responses but there's
   772  	// no equivalent bogus thing we can realistically send in HTTP/3,
   773  	// so we'll consistently panic instead and help people find their bugs
   774  	// early. (We can't return an error from WriteHeader even if we wanted to.)
   775  	if code < 100 || code > 999 {
   776  		panic(fmt.Sprintf("invalid WriteHeader code %v", code))
   777  	}
   778  }
   779  
   780  func (rw *responseWriter) WriteHeader(statusCode int) {
   781  	// TODO: handle sending informational status headers (e.g. 103).
   782  	rw.mu.Lock()
   783  	defer rw.mu.Unlock()
   784  	if rw.statusCode != 0 {
   785  		return
   786  	}
   787  	checkWriteHeaderCode(statusCode)
   788  
   789  	// Informational headers can be sent multiple times, and should be flushed
   790  	// immediately.
   791  	if isInfoStatus(statusCode) {
   792  		rw.writeHeaderLocked(statusCode)
   793  		rw.st.Flush()
   794  		return
   795  	}
   796  
   797  	// Non-informational headers should only be set once, and should be
   798  	// buffered.
   799  	if n, err := strconv.ParseUint(rw.headers.Get("Content-Length"), 10, 63); err == nil {
   800  		rw.bodyLenLeft = int64(n)
   801  	} else {
   802  		rw.headers.Del("Content-Length")
   803  		rw.bodyLenLeft = -1 // Unknown.
   804  	}
   805  	rw.statusCode = statusCode
   806  	rw.snapHeaders = rw.headers.Clone()
   807  }
   808  
   809  // trimWriteLocked trims a byte slice, b, such that the length of b will not
   810  // exceed rw.bodyLenLeft. This method will update rw.bodyLenLeft when trimming
   811  // b, and will also return whether b was trimmed or not.
   812  // Caller must hold rw.mu.
   813  func (rw *responseWriter) trimWriteLocked(b []byte) ([]byte, bool) {
   814  	if rw.bodyLenLeft < 0 {
   815  		return b, false
   816  	}
   817  	n := min(int64(len(b)), rw.bodyLenLeft)
   818  	rw.bodyLenLeft -= n
   819  	return b[:n], n != int64(len(b))
   820  }
   821  
   822  func (rw *responseWriter) Write(b []byte) (n int, err error) {
   823  	// Calling Write implicitly calls WriteHeader(200) if WriteHeader has not
   824  	// been called before.
   825  	rw.WriteHeader(http.StatusOK)
   826  	rw.mu.Lock()
   827  	defer rw.mu.Unlock()
   828  
   829  	if rw.statusCode == http.StatusNotModified {
   830  		return 0, http.ErrBodyNotAllowed
   831  	}
   832  
   833  	b, trimmed := rw.trimWriteLocked(b)
   834  	if trimmed {
   835  		defer func() {
   836  			err = http.ErrContentLength
   837  		}()
   838  	}
   839  
   840  	// If b fits entirely in our body buffer, save it to the buffer and return
   841  	// early so we can coalesce small writes.
   842  	// As a special case, we always want to save b to the buffer even when b is
   843  	// big if we had yet to write our header, so we can infer headers like
   844  	// "Content-Type" with as much information as possible.
   845  	initialBLen := len(b)
   846  	initialBufLen := len(rw.bb)
   847  	if !rw.wroteHeader || len(b) <= cap(rw.bb)-len(rw.bb) {
   848  		b = rw.bb.write(b)
   849  		if len(b) == 0 {
   850  			return initialBLen, nil
   851  		}
   852  	}
   853  
   854  	// Reaching this point means that our buffer has been sufficiently filled.
   855  	// Therefore, we now want to:
   856  	// 1. Infer and write response headers based on our body buffer, if not
   857  	// done yet.
   858  	// 2. Write our body buffer and the rest of b (if any).
   859  	// 3. Reset the current body buffer so it can be used again.
   860  	rw.writeHeaderLockedOnce()
   861  	if rw.cannotHaveBody {
   862  		return initialBLen, nil
   863  	}
   864  	if n, err := rw.bw.write(rw.bb, b); err != nil {
   865  		return max(0, n-initialBufLen), err
   866  	}
   867  	rw.bb.discard()
   868  	return initialBLen, nil
   869  }
   870  
   871  func (rw *responseWriter) SetReadDeadline(deadline time.Time) error {
   872  	rw.st.readDeadline.set(deadline)
   873  	return nil
   874  }
   875  
   876  func (rw *responseWriter) SetWriteDeadline(deadline time.Time) error {
   877  	rw.st.writeDeadline.set(deadline)
   878  	return nil
   879  }
   880  
   881  func (rw *responseWriter) EnableFullDuplex() error {
   882  	return nil
   883  }
   884  
   885  func (rw *responseWriter) Flush() { rw.FlushError() }
   886  func (rw *responseWriter) FlushError() error {
   887  	// Calling Flush implicitly calls WriteHeader(200) if WriteHeader has not
   888  	// been called before.
   889  	rw.WriteHeader(http.StatusOK)
   890  	rw.mu.Lock()
   891  	defer rw.mu.Unlock()
   892  	rw.writeHeaderLockedOnce()
   893  	if !rw.cannotHaveBody {
   894  		_, err := rw.bw.Write(rw.bb)
   895  		rw.bb.discard()
   896  		if err != nil {
   897  			return err
   898  		}
   899  	}
   900  	return rw.st.Flush()
   901  }
   902  
   903  func (rw *responseWriter) close() error {
   904  	if errors.Is(rw.st.writeDeadline.err(), os.ErrDeadlineExceeded) {
   905  		return &streamError{
   906  			code:    errH3RequestCancelled,
   907  			message: "exceeded deadline while writing response",
   908  		}
   909  	}
   910  
   911  	retErr := rw.FlushError()
   912  	rw.mu.Lock()
   913  	defer rw.mu.Unlock()
   914  	rw.prepareTrailerForWriteLocked()
   915  	if err := rw.bw.Close(); retErr == nil {
   916  		retErr = err
   917  	}
   918  	if errors.Is(retErr, os.ErrDeadlineExceeded) {
   919  		return &streamError{
   920  			code:    errH3RequestCancelled,
   921  			message: retErr.Error(),
   922  		}
   923  	}
   924  	return retErr
   925  }
   926  
   927  // defaultBodyBufferCap is the default number of bytes of body that we are
   928  // willing to save in a buffer for the sake of inferring headers and coalescing
   929  // small writes. 512 was chosen to be consistent with how much
   930  // http.DetectContentType is willing to read.
   931  const defaultBodyBufferCap = 512
   932  
   933  // bodyBuffer is a buffer used to store body content of a response.
   934  type bodyBuffer []byte
   935  
   936  // write writes b to the buffer. It returns a new slice of b, which contains
   937  // any remaining data that could not be written to the buffer, if any.
   938  func (bb *bodyBuffer) write(b []byte) []byte {
   939  	n := min(len(b), cap(*bb)-len(*bb))
   940  	*bb = append(*bb, b[:n]...)
   941  	return b[n:]
   942  }
   943  
   944  // discard resets the buffer so it can be used again.
   945  func (bb *bodyBuffer) discard() {
   946  	*bb = (*bb)[:0]
   947  }
   948  
   949  // inferHeader populates h with the header values that we can infer from our
   950  // current buffer content, if not already explicitly set. This method should be
   951  // called only once with as much body content as possible in the buffer, before
   952  // a HEADERS frame is sent, and before discard has been called. Doing so
   953  // properly is the responsibility of the caller.
   954  func (bb *bodyBuffer) inferHeader(h http.Header, status int) {
   955  	if _, ok := h["Date"]; !ok {
   956  		h.Set("Date", time.Now().UTC().Format(http.TimeFormat))
   957  	}
   958  	// If the Content-Encoding is non-blank, we shouldn't
   959  	// sniff the body. See Issue golang.org/issue/31753.
   960  	hasCE := len(h.Get("Content-Encoding")) > 0
   961  	_, hasCT := h["Content-Type"]
   962  	if !hasCE && !hasCT && responseCanHaveBody(status) && len(*bb) > 0 {
   963  		h.Set("Content-Type", http.DetectContentType(*bb))
   964  	}
   965  	// We can technically infer Content-Length too here, as long as the entire
   966  	// response body fits within hi.buf and does not require flushing. However,
   967  	// we have chosen not to do so for now as Content-Length is not very
   968  	// important for HTTP/3, and such inconsistent behavior might be confusing.
   969  }
   970  
   971  // serverRequestReader wraps around bodyReader, allowing Read and Close calls
   972  // done from within a server handler to coordinate correctly with the
   973  // responseWriter; for example, sending status 100 on Read when appropriate.
   974  type serverRequestReader struct {
   975  	rw            *responseWriter
   976  	br            bodyReader
   977  	needsContinue bool
   978  }
   979  
   980  // maybeSendContinue attempts to send a 100 Continue status code. It
   981  // ensures that status 100 will only be sent once and when appropriate. If a
   982  // non-1xx header has been set before 100 was ever set, it also ensures that
   983  // all subsequent Read will fail.
   984  func (srr *serverRequestReader) maybeSendContinue() {
   985  	if !srr.needsContinue {
   986  		return
   987  	}
   988  	srr.rw.mu.Lock()
   989  	defer srr.rw.mu.Unlock()
   990  	if srr.rw.sent100 {
   991  		return
   992  	}
   993  	if srr.rw.statusCode != 0 {
   994  		srr.br.Close()
   995  		return
   996  	}
   997  	srr.rw.writeHeaderLocked(100)
   998  	srr.rw.st.Flush()
   999  }
  1000  
  1001  func (srr *serverRequestReader) Read(p []byte) (int, error) {
  1002  	srr.maybeSendContinue()
  1003  	return srr.br.Read(p)
  1004  }
  1005  
  1006  func (srr *serverRequestReader) Close() error {
  1007  	return srr.br.Close()
  1008  }
  1009  

View as plain text