Help us shape the future of Go! Take the 2026 Go Developer Survey

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

View as plain text