github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/http3/server.go (about)

     1  package http3
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"net"
    10  	"net/http"
    11  	"runtime"
    12  	"strconv"
    13  	"strings"
    14  	"sync"
    15  	"time"
    16  
    17  	"github.com/TugasAkhir-QUIC/quic-go"
    18  	"github.com/TugasAkhir-QUIC/quic-go/internal/protocol"
    19  	"github.com/TugasAkhir-QUIC/quic-go/internal/utils"
    20  	"github.com/TugasAkhir-QUIC/quic-go/quicvarint"
    21  
    22  	"github.com/quic-go/qpack"
    23  )
    24  
    25  // allows mocking of quic.Listen and quic.ListenAddr
    26  var (
    27  	quicListen = func(conn net.PacketConn, tlsConf *tls.Config, config *quic.Config) (QUICEarlyListener, error) {
    28  		return quic.ListenEarly(conn, tlsConf, config)
    29  	}
    30  	quicListenAddr = func(addr string, tlsConf *tls.Config, config *quic.Config) (QUICEarlyListener, error) {
    31  		return quic.ListenAddrEarly(addr, tlsConf, config)
    32  	}
    33  	errPanicked = errors.New("panicked")
    34  )
    35  
    36  // NextProtoH3 is the ALPN protocol negotiated during the TLS handshake, for QUIC v1 and v2.
    37  const NextProtoH3 = "h3"
    38  
    39  // StreamType is the stream type of a unidirectional stream.
    40  type StreamType uint64
    41  
    42  const (
    43  	streamTypeControlStream      = 0
    44  	streamTypePushStream         = 1
    45  	streamTypeQPACKEncoderStream = 2
    46  	streamTypeQPACKDecoderStream = 3
    47  )
    48  
    49  // A QUICEarlyListener listens for incoming QUIC connections.
    50  type QUICEarlyListener interface {
    51  	Accept(context.Context) (quic.EarlyConnection, error)
    52  	Addr() net.Addr
    53  	io.Closer
    54  }
    55  
    56  var _ QUICEarlyListener = &quic.EarlyListener{}
    57  
    58  func versionToALPN(v protocol.Version) string {
    59  	//nolint:exhaustive // These are all the versions we care about.
    60  	switch v {
    61  	case protocol.Version1, protocol.Version2:
    62  		return NextProtoH3
    63  	default:
    64  		return ""
    65  	}
    66  }
    67  
    68  // ConfigureTLSConfig creates a new tls.Config which can be used
    69  // to create a quic.Listener meant for serving http3. The created
    70  // tls.Config adds the functionality of detecting the used QUIC version
    71  // in order to set the correct ALPN value for the http3 connection.
    72  func ConfigureTLSConfig(tlsConf *tls.Config) *tls.Config {
    73  	// The tls.Config used to setup the quic.Listener needs to have the GetConfigForClient callback set.
    74  	// That way, we can get the QUIC version and set the correct ALPN value.
    75  	return &tls.Config{
    76  		GetConfigForClient: func(ch *tls.ClientHelloInfo) (*tls.Config, error) {
    77  			// determine the ALPN from the QUIC version used
    78  			proto := NextProtoH3
    79  			val := ch.Context().Value(quic.QUICVersionContextKey)
    80  			if v, ok := val.(quic.Version); ok {
    81  				proto = versionToALPN(v)
    82  			}
    83  			config := tlsConf
    84  			if tlsConf.GetConfigForClient != nil {
    85  				getConfigForClient := tlsConf.GetConfigForClient
    86  				var err error
    87  				conf, err := getConfigForClient(ch)
    88  				if err != nil {
    89  					return nil, err
    90  				}
    91  				if conf != nil {
    92  					config = conf
    93  				}
    94  			}
    95  			if config == nil {
    96  				return nil, nil
    97  			}
    98  			config = config.Clone()
    99  			config.NextProtos = []string{proto}
   100  			return config, nil
   101  		},
   102  	}
   103  }
   104  
   105  // contextKey is a value for use with context.WithValue. It's used as
   106  // a pointer so it fits in an interface{} without allocation.
   107  type contextKey struct {
   108  	name string
   109  }
   110  
   111  func (k *contextKey) String() string { return "quic-go/http3 context value " + k.name }
   112  
   113  // ServerContextKey is a context key. It can be used in HTTP
   114  // handlers with Context.Value to access the server that
   115  // started the handler. The associated value will be of
   116  // type *http3.Server.
   117  var ServerContextKey = &contextKey{"http3-server"}
   118  
   119  // RemoteAddrContextKey is a context key. It can be used in
   120  // HTTP handlers with Context.Value to access the remote
   121  // address of the connection. The associated value will be of
   122  // type net.Addr.
   123  //
   124  // Use this value instead of [http.Request.RemoteAddr] if you
   125  // require access to the remote address of the connection rather
   126  // than its string representation.
   127  var RemoteAddrContextKey = &contextKey{"remote-addr"}
   128  
   129  type requestError struct {
   130  	err       error
   131  	streamErr ErrCode
   132  	connErr   ErrCode
   133  }
   134  
   135  func newStreamError(code ErrCode, err error) requestError {
   136  	return requestError{err: err, streamErr: code}
   137  }
   138  
   139  func newConnError(code ErrCode, err error) requestError {
   140  	return requestError{err: err, connErr: code}
   141  }
   142  
   143  // listenerInfo contains info about specific listener added with addListener
   144  type listenerInfo struct {
   145  	port int // 0 means that no info about port is available
   146  }
   147  
   148  // Server is a HTTP/3 server.
   149  type Server struct {
   150  	// Addr optionally specifies the UDP address for the server to listen on,
   151  	// in the form "host:port".
   152  	//
   153  	// When used by ListenAndServe and ListenAndServeTLS methods, if empty,
   154  	// ":https" (port 443) is used. See net.Dial for details of the address
   155  	// format.
   156  	//
   157  	// Otherwise, if Port is not set and underlying QUIC listeners do not
   158  	// have valid port numbers, the port part is used in Alt-Svc headers set
   159  	// with SetQuicHeaders.
   160  	Addr string
   161  
   162  	// Port is used in Alt-Svc response headers set with SetQuicHeaders. If
   163  	// needed Port can be manually set when the Server is created.
   164  	//
   165  	// This is useful when a Layer 4 firewall is redirecting UDP traffic and
   166  	// clients must use a port different from the port the Server is
   167  	// listening on.
   168  	Port int
   169  
   170  	// TLSConfig provides a TLS configuration for use by server. It must be
   171  	// set for ListenAndServe and Serve methods.
   172  	TLSConfig *tls.Config
   173  
   174  	// QuicConfig provides the parameters for QUIC connection created with
   175  	// Serve. If nil, it uses reasonable default values.
   176  	//
   177  	// Configured versions are also used in Alt-Svc response header set with
   178  	// SetQuicHeaders.
   179  	QuicConfig *quic.Config
   180  
   181  	// Handler is the HTTP request handler to use. If not set, defaults to
   182  	// http.NotFound.
   183  	Handler http.Handler
   184  
   185  	// EnableDatagrams enables support for HTTP/3 datagrams.
   186  	// If set to true, QuicConfig.EnableDatagram will be set.
   187  	// See https://datatracker.ietf.org/doc/html/rfc9297.
   188  	EnableDatagrams bool
   189  
   190  	// MaxHeaderBytes controls the maximum number of bytes the server will
   191  	// read parsing the request HEADERS frame. It does not limit the size of
   192  	// the request body. If zero or negative, http.DefaultMaxHeaderBytes is
   193  	// used.
   194  	MaxHeaderBytes int
   195  
   196  	// AdditionalSettings specifies additional HTTP/3 settings.
   197  	// It is invalid to specify any settings defined by the HTTP/3 draft and the datagram draft.
   198  	AdditionalSettings map[uint64]uint64
   199  
   200  	// StreamHijacker, when set, is called for the first unknown frame parsed on a bidirectional stream.
   201  	// It is called right after parsing the frame type.
   202  	// If parsing the frame type fails, the error is passed to the callback.
   203  	// In that case, the frame type will not be set.
   204  	// Callers can either ignore the frame and return control of the stream back to HTTP/3
   205  	// (by returning hijacked false).
   206  	// Alternatively, callers can take over the QUIC stream (by returning hijacked true).
   207  	StreamHijacker func(FrameType, quic.Connection, quic.Stream, error) (hijacked bool, err error)
   208  
   209  	// UniStreamHijacker, when set, is called for unknown unidirectional stream of unknown stream type.
   210  	// If parsing the stream type fails, the error is passed to the callback.
   211  	// In that case, the stream type will not be set.
   212  	UniStreamHijacker func(StreamType, quic.Connection, quic.ReceiveStream, error) (hijacked bool)
   213  
   214  	// ConnContext optionally specifies a function that modifies
   215  	// the context used for a new connection c. The provided ctx
   216  	// has a ServerContextKey value.
   217  	ConnContext func(ctx context.Context, c quic.Connection) context.Context
   218  
   219  	mutex     sync.RWMutex
   220  	listeners map[*QUICEarlyListener]listenerInfo
   221  
   222  	closed bool
   223  
   224  	altSvcHeader string
   225  
   226  	logger utils.Logger
   227  }
   228  
   229  // ListenAndServe listens on the UDP address s.Addr and calls s.Handler to handle HTTP/3 requests on incoming connections.
   230  //
   231  // If s.Addr is blank, ":https" is used.
   232  func (s *Server) ListenAndServe() error {
   233  	return s.serveConn(s.TLSConfig, nil)
   234  }
   235  
   236  // ListenAndServeTLS listens on the UDP address s.Addr and calls s.Handler to handle HTTP/3 requests on incoming connections.
   237  //
   238  // If s.Addr is blank, ":https" is used.
   239  func (s *Server) ListenAndServeTLS(certFile, keyFile string) error {
   240  	var err error
   241  	certs := make([]tls.Certificate, 1)
   242  	certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
   243  	if err != nil {
   244  		return err
   245  	}
   246  	// We currently only use the cert-related stuff from tls.Config,
   247  	// so we don't need to make a full copy.
   248  	config := &tls.Config{
   249  		Certificates: certs,
   250  	}
   251  	return s.serveConn(config, nil)
   252  }
   253  
   254  // Serve an existing UDP connection.
   255  // It is possible to reuse the same connection for outgoing connections.
   256  // Closing the server does not close the connection.
   257  func (s *Server) Serve(conn net.PacketConn) error {
   258  	return s.serveConn(s.TLSConfig, conn)
   259  }
   260  
   261  // ServeQUICConn serves a single QUIC connection.
   262  func (s *Server) ServeQUICConn(conn quic.Connection) error {
   263  	s.mutex.Lock()
   264  	if s.logger == nil {
   265  		s.logger = utils.DefaultLogger.WithPrefix("server")
   266  	}
   267  	s.mutex.Unlock()
   268  
   269  	return s.handleConn(conn)
   270  }
   271  
   272  // ServeListener serves an existing QUIC listener.
   273  // Make sure you use http3.ConfigureTLSConfig to configure a tls.Config
   274  // and use it to construct a http3-friendly QUIC listener.
   275  // Closing the server does close the listener.
   276  // ServeListener always returns a non-nil error. After Shutdown or Close, the returned error is http.ErrServerClosed.
   277  func (s *Server) ServeListener(ln QUICEarlyListener) error {
   278  	if err := s.addListener(&ln); err != nil {
   279  		return err
   280  	}
   281  	defer s.removeListener(&ln)
   282  	for {
   283  		conn, err := ln.Accept(context.Background())
   284  		if err == quic.ErrServerClosed {
   285  			return http.ErrServerClosed
   286  		}
   287  		if err != nil {
   288  			return err
   289  		}
   290  		go func() {
   291  			if err := s.handleConn(conn); err != nil {
   292  				s.logger.Debugf("handling connection failed: %s", err)
   293  			}
   294  		}()
   295  	}
   296  }
   297  
   298  var errServerWithoutTLSConfig = errors.New("use of http3.Server without TLSConfig")
   299  
   300  func (s *Server) serveConn(tlsConf *tls.Config, conn net.PacketConn) error {
   301  	if tlsConf == nil {
   302  		return errServerWithoutTLSConfig
   303  	}
   304  
   305  	s.mutex.Lock()
   306  	closed := s.closed
   307  	s.mutex.Unlock()
   308  	if closed {
   309  		return http.ErrServerClosed
   310  	}
   311  
   312  	baseConf := ConfigureTLSConfig(tlsConf)
   313  	quicConf := s.QuicConfig
   314  	if quicConf == nil {
   315  		quicConf = &quic.Config{Allow0RTT: true}
   316  	} else {
   317  		quicConf = s.QuicConfig.Clone()
   318  	}
   319  	if s.EnableDatagrams {
   320  		quicConf.EnableDatagrams = true
   321  	}
   322  
   323  	var ln QUICEarlyListener
   324  	var err error
   325  	if conn == nil {
   326  		addr := s.Addr
   327  		if addr == "" {
   328  			addr = ":https"
   329  		}
   330  		ln, err = quicListenAddr(addr, baseConf, quicConf)
   331  	} else {
   332  		ln, err = quicListen(conn, baseConf, quicConf)
   333  	}
   334  	if err != nil {
   335  		return err
   336  	}
   337  	return s.ServeListener(ln)
   338  }
   339  
   340  func extractPort(addr string) (int, error) {
   341  	_, portStr, err := net.SplitHostPort(addr)
   342  	if err != nil {
   343  		return 0, err
   344  	}
   345  
   346  	portInt, err := net.LookupPort("tcp", portStr)
   347  	if err != nil {
   348  		return 0, err
   349  	}
   350  	return portInt, nil
   351  }
   352  
   353  func (s *Server) generateAltSvcHeader() {
   354  	if len(s.listeners) == 0 {
   355  		// Don't announce any ports since no one is listening for connections
   356  		s.altSvcHeader = ""
   357  		return
   358  	}
   359  
   360  	// This code assumes that we will use protocol.SupportedVersions if no quic.Config is passed.
   361  	supportedVersions := protocol.SupportedVersions
   362  	if s.QuicConfig != nil && len(s.QuicConfig.Versions) > 0 {
   363  		supportedVersions = s.QuicConfig.Versions
   364  	}
   365  
   366  	// keep track of which have been seen so we don't yield duplicate values
   367  	seen := make(map[string]struct{}, len(supportedVersions))
   368  	var versionStrings []string
   369  	for _, version := range supportedVersions {
   370  		if v := versionToALPN(version); len(v) > 0 {
   371  			if _, ok := seen[v]; !ok {
   372  				versionStrings = append(versionStrings, v)
   373  				seen[v] = struct{}{}
   374  			}
   375  		}
   376  	}
   377  
   378  	var altSvc []string
   379  	addPort := func(port int) {
   380  		for _, v := range versionStrings {
   381  			altSvc = append(altSvc, fmt.Sprintf(`%s=":%d"; ma=2592000`, v, port))
   382  		}
   383  	}
   384  
   385  	if s.Port != 0 {
   386  		// if Port is specified, we must use it instead of the
   387  		// listener addresses since there's a reason it's specified.
   388  		addPort(s.Port)
   389  	} else {
   390  		// if we have some listeners assigned, try to find ports
   391  		// which we can announce, otherwise nothing should be announced
   392  		validPortsFound := false
   393  		for _, info := range s.listeners {
   394  			if info.port != 0 {
   395  				addPort(info.port)
   396  				validPortsFound = true
   397  			}
   398  		}
   399  		if !validPortsFound {
   400  			if port, err := extractPort(s.Addr); err == nil {
   401  				addPort(port)
   402  			}
   403  		}
   404  	}
   405  
   406  	s.altSvcHeader = strings.Join(altSvc, ",")
   407  }
   408  
   409  // We store a pointer to interface in the map set. This is safe because we only
   410  // call trackListener via Serve and can track+defer untrack the same pointer to
   411  // local variable there. We never need to compare a Listener from another caller.
   412  func (s *Server) addListener(l *QUICEarlyListener) error {
   413  	s.mutex.Lock()
   414  	defer s.mutex.Unlock()
   415  
   416  	if s.closed {
   417  		return http.ErrServerClosed
   418  	}
   419  	if s.logger == nil {
   420  		s.logger = utils.DefaultLogger.WithPrefix("server")
   421  	}
   422  	if s.listeners == nil {
   423  		s.listeners = make(map[*QUICEarlyListener]listenerInfo)
   424  	}
   425  
   426  	laddr := (*l).Addr()
   427  	if port, err := extractPort(laddr.String()); err == nil {
   428  		s.listeners[l] = listenerInfo{port}
   429  	} else {
   430  		s.logger.Errorf("Unable to extract port from listener %s, will not be announced using SetQuicHeaders: %s", laddr, err)
   431  		s.listeners[l] = listenerInfo{}
   432  	}
   433  	s.generateAltSvcHeader()
   434  	return nil
   435  }
   436  
   437  func (s *Server) removeListener(l *QUICEarlyListener) {
   438  	s.mutex.Lock()
   439  	defer s.mutex.Unlock()
   440  	delete(s.listeners, l)
   441  	s.generateAltSvcHeader()
   442  }
   443  
   444  func (s *Server) handleConn(conn quic.Connection) error {
   445  	decoder := qpack.NewDecoder(nil)
   446  
   447  	// send a SETTINGS frame
   448  	str, err := conn.OpenUniStream()
   449  	if err != nil {
   450  		return fmt.Errorf("opening the control stream failed: %w", err)
   451  	}
   452  	b := make([]byte, 0, 64)
   453  	b = quicvarint.Append(b, streamTypeControlStream) // stream type
   454  	b = (&settingsFrame{Datagram: s.EnableDatagrams, Other: s.AdditionalSettings}).Append(b)
   455  	str.Write(b)
   456  
   457  	go s.handleUnidirectionalStreams(conn)
   458  
   459  	// Process all requests immediately.
   460  	// It's the client's responsibility to decide which requests are eligible for 0-RTT.
   461  	for {
   462  		str, err := conn.AcceptStream(context.Background())
   463  		if err != nil {
   464  			var appErr *quic.ApplicationError
   465  			if errors.As(err, &appErr) && appErr.ErrorCode == quic.ApplicationErrorCode(ErrCodeNoError) {
   466  				return nil
   467  			}
   468  			return fmt.Errorf("accepting stream failed: %w", err)
   469  		}
   470  		go func() {
   471  			rerr := s.handleRequest(conn, str, decoder, func() {
   472  				conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "")
   473  			})
   474  			if rerr.err == errHijacked {
   475  				return
   476  			}
   477  			if rerr.err != nil || rerr.streamErr != 0 || rerr.connErr != 0 {
   478  				s.logger.Debugf("Handling request failed: %s", err)
   479  				if rerr.streamErr != 0 {
   480  					str.CancelWrite(quic.StreamErrorCode(rerr.streamErr))
   481  				}
   482  				if rerr.connErr != 0 {
   483  					var reason string
   484  					if rerr.err != nil {
   485  						reason = rerr.err.Error()
   486  					}
   487  					conn.CloseWithError(quic.ApplicationErrorCode(rerr.connErr), reason)
   488  				}
   489  				return
   490  			}
   491  			str.Close()
   492  		}()
   493  	}
   494  }
   495  
   496  func (s *Server) handleUnidirectionalStreams(conn quic.Connection) {
   497  	for {
   498  		str, err := conn.AcceptUniStream(context.Background())
   499  		if err != nil {
   500  			s.logger.Debugf("accepting unidirectional stream failed: %s", err)
   501  			return
   502  		}
   503  
   504  		go func(str quic.ReceiveStream) {
   505  			streamType, err := quicvarint.Read(quicvarint.NewReader(str))
   506  			if err != nil {
   507  				if s.UniStreamHijacker != nil && s.UniStreamHijacker(StreamType(streamType), conn, str, err) {
   508  					return
   509  				}
   510  				s.logger.Debugf("reading stream type on stream %d failed: %s", str.StreamID(), err)
   511  				return
   512  			}
   513  			// We're only interested in the control stream here.
   514  			switch streamType {
   515  			case streamTypeControlStream:
   516  			case streamTypeQPACKEncoderStream, streamTypeQPACKDecoderStream:
   517  				// Our QPACK implementation doesn't use the dynamic table yet.
   518  				// TODO: check that only one stream of each type is opened.
   519  				return
   520  			case streamTypePushStream: // only the server can push
   521  				conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeStreamCreationError), "")
   522  				return
   523  			default:
   524  				if s.UniStreamHijacker != nil && s.UniStreamHijacker(StreamType(streamType), conn, str, nil) {
   525  					return
   526  				}
   527  				str.CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError))
   528  				return
   529  			}
   530  			f, err := parseNextFrame(str, nil)
   531  			if err != nil {
   532  				conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), "")
   533  				return
   534  			}
   535  			sf, ok := f.(*settingsFrame)
   536  			if !ok {
   537  				conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), "")
   538  				return
   539  			}
   540  			if !sf.Datagram {
   541  				return
   542  			}
   543  			// If datagram support was enabled on our side as well as on the client side,
   544  			// we can expect it to have been negotiated both on the transport and on the HTTP/3 layer.
   545  			// Note: ConnectionState() will block until the handshake is complete (relevant when using 0-RTT).
   546  			if s.EnableDatagrams && !conn.ConnectionState().SupportsDatagrams {
   547  				conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeSettingsError), "missing QUIC Datagram support")
   548  			}
   549  		}(str)
   550  	}
   551  }
   552  
   553  func (s *Server) maxHeaderBytes() uint64 {
   554  	if s.MaxHeaderBytes <= 0 {
   555  		return http.DefaultMaxHeaderBytes
   556  	}
   557  	return uint64(s.MaxHeaderBytes)
   558  }
   559  
   560  func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *qpack.Decoder, onFrameError func()) requestError {
   561  	var ufh unknownFrameHandlerFunc
   562  	if s.StreamHijacker != nil {
   563  		ufh = func(ft FrameType, e error) (processed bool, err error) { return s.StreamHijacker(ft, conn, str, e) }
   564  	}
   565  	frame, err := parseNextFrame(str, ufh)
   566  	if err != nil {
   567  		if err == errHijacked {
   568  			return requestError{err: errHijacked}
   569  		}
   570  		return newStreamError(ErrCodeRequestIncomplete, err)
   571  	}
   572  	hf, ok := frame.(*headersFrame)
   573  	if !ok {
   574  		return newConnError(ErrCodeFrameUnexpected, errors.New("expected first frame to be a HEADERS frame"))
   575  	}
   576  	if hf.Length > s.maxHeaderBytes() {
   577  		return newStreamError(ErrCodeFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, s.maxHeaderBytes()))
   578  	}
   579  	headerBlock := make([]byte, hf.Length)
   580  	if _, err := io.ReadFull(str, headerBlock); err != nil {
   581  		return newStreamError(ErrCodeRequestIncomplete, err)
   582  	}
   583  	hfs, err := decoder.DecodeFull(headerBlock)
   584  	if err != nil {
   585  		// TODO: use the right error code
   586  		return newConnError(ErrCodeGeneralProtocolError, err)
   587  	}
   588  	req, err := requestFromHeaders(hfs)
   589  	if err != nil {
   590  		return newStreamError(ErrCodeMessageError, err)
   591  	}
   592  
   593  	connState := conn.ConnectionState().TLS
   594  	req.TLS = &connState
   595  	req.RemoteAddr = conn.RemoteAddr().String()
   596  
   597  	// Check that the client doesn't send more data in DATA frames than indicated by the Content-Length header (if set).
   598  	// See section 4.1.2 of RFC 9114.
   599  	var httpStr Stream
   600  	if _, ok := req.Header["Content-Length"]; ok && req.ContentLength >= 0 {
   601  		httpStr = newLengthLimitedStream(newStream(str, onFrameError), req.ContentLength)
   602  	} else {
   603  		httpStr = newStream(str, onFrameError)
   604  	}
   605  	body := newRequestBody(httpStr)
   606  	req.Body = body
   607  
   608  	if s.logger.Debug() {
   609  		s.logger.Infof("%s %s%s, on stream %d", req.Method, req.Host, req.RequestURI, str.StreamID())
   610  	} else {
   611  		s.logger.Infof("%s %s%s", req.Method, req.Host, req.RequestURI)
   612  	}
   613  
   614  	ctx := str.Context()
   615  	ctx = context.WithValue(ctx, ServerContextKey, s)
   616  	ctx = context.WithValue(ctx, http.LocalAddrContextKey, conn.LocalAddr())
   617  	ctx = context.WithValue(ctx, RemoteAddrContextKey, conn.RemoteAddr())
   618  	if s.ConnContext != nil {
   619  		ctx = s.ConnContext(ctx, conn)
   620  		if ctx == nil {
   621  			panic("http3: ConnContext returned nil")
   622  		}
   623  	}
   624  	req = req.WithContext(ctx)
   625  	r := newResponseWriter(str, conn, s.logger)
   626  	if req.Method == http.MethodHead {
   627  		r.isHead = true
   628  	}
   629  	handler := s.Handler
   630  	if handler == nil {
   631  		handler = http.DefaultServeMux
   632  	}
   633  
   634  	var panicked bool
   635  	func() {
   636  		defer func() {
   637  			if p := recover(); p != nil {
   638  				panicked = true
   639  				if p == http.ErrAbortHandler {
   640  					return
   641  				}
   642  				// Copied from net/http/server.go
   643  				const size = 64 << 10
   644  				buf := make([]byte, size)
   645  				buf = buf[:runtime.Stack(buf, false)]
   646  				s.logger.Errorf("http: panic serving: %v\n%s", p, buf)
   647  			}
   648  		}()
   649  		handler.ServeHTTP(r, req)
   650  	}()
   651  
   652  	if body.wasStreamHijacked() {
   653  		return requestError{err: errHijacked}
   654  	}
   655  
   656  	// only write response when there is no panic
   657  	if !panicked {
   658  		// response not written to the client yet, set Content-Length
   659  		if !r.written {
   660  			if _, haveCL := r.header["Content-Length"]; !haveCL {
   661  				r.header.Set("Content-Length", strconv.FormatInt(r.numWritten, 10))
   662  			}
   663  		}
   664  		r.Flush()
   665  	}
   666  	// If the EOF was read by the handler, CancelRead() is a no-op.
   667  	str.CancelRead(quic.StreamErrorCode(ErrCodeNoError))
   668  
   669  	// abort the stream when there is a panic
   670  	if panicked {
   671  		return newStreamError(ErrCodeInternalError, errPanicked)
   672  	}
   673  	return requestError{}
   674  }
   675  
   676  // Close the server immediately, aborting requests and sending CONNECTION_CLOSE frames to connected clients.
   677  // Close in combination with ListenAndServe() (instead of Serve()) may race if it is called before a UDP socket is established.
   678  func (s *Server) Close() error {
   679  	s.mutex.Lock()
   680  	defer s.mutex.Unlock()
   681  
   682  	s.closed = true
   683  
   684  	var err error
   685  	for ln := range s.listeners {
   686  		if cerr := (*ln).Close(); cerr != nil && err == nil {
   687  			err = cerr
   688  		}
   689  	}
   690  	return err
   691  }
   692  
   693  // CloseGracefully shuts down the server gracefully. The server sends a GOAWAY frame first, then waits for either timeout to trigger, or for all running requests to complete.
   694  // CloseGracefully in combination with ListenAndServe() (instead of Serve()) may race if it is called before a UDP socket is established.
   695  func (s *Server) CloseGracefully(timeout time.Duration) error {
   696  	// TODO: implement
   697  	return nil
   698  }
   699  
   700  // ErrNoAltSvcPort is the error returned by SetQuicHeaders when no port was found
   701  // for Alt-Svc to announce. This can happen if listening on a PacketConn without a port
   702  // (UNIX socket, for example) and no port is specified in Server.Port or Server.Addr.
   703  var ErrNoAltSvcPort = errors.New("no port can be announced, specify it explicitly using Server.Port or Server.Addr")
   704  
   705  // SetQuicHeaders can be used to set the proper headers that announce that this server supports HTTP/3.
   706  // The values set by default advertise all of the ports the server is listening on, but can be
   707  // changed to a specific port by setting Server.Port before launching the serverr.
   708  // If no listener's Addr().String() returns an address with a valid port, Server.Addr will be used
   709  // to extract the port, if specified.
   710  // For example, a server launched using ListenAndServe on an address with port 443 would set:
   711  //
   712  //	Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
   713  func (s *Server) SetQuicHeaders(hdr http.Header) error {
   714  	s.mutex.RLock()
   715  	defer s.mutex.RUnlock()
   716  
   717  	if s.altSvcHeader == "" {
   718  		return ErrNoAltSvcPort
   719  	}
   720  	// use the map directly to avoid constant canonicalization
   721  	// since the key is already canonicalized
   722  	hdr["Alt-Svc"] = append(hdr["Alt-Svc"], s.altSvcHeader)
   723  	return nil
   724  }
   725  
   726  // ListenAndServeQUIC listens on the UDP network address addr and calls the
   727  // handler for HTTP/3 requests on incoming connections. http.DefaultServeMux is
   728  // used when handler is nil.
   729  func ListenAndServeQUIC(addr, certFile, keyFile string, handler http.Handler) error {
   730  	server := &Server{
   731  		Addr:    addr,
   732  		Handler: handler,
   733  	}
   734  	return server.ListenAndServeTLS(certFile, keyFile)
   735  }
   736  
   737  // ListenAndServe listens on the given network address for both TLS/TCP and QUIC
   738  // connections in parallel. It returns if one of the two returns an error.
   739  // http.DefaultServeMux is used when handler is nil.
   740  // The correct Alt-Svc headers for QUIC are set.
   741  func ListenAndServe(addr, certFile, keyFile string, handler http.Handler) error {
   742  	// Load certs
   743  	var err error
   744  	certs := make([]tls.Certificate, 1)
   745  	certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
   746  	if err != nil {
   747  		return err
   748  	}
   749  	// We currently only use the cert-related stuff from tls.Config,
   750  	// so we don't need to make a full copy.
   751  	config := &tls.Config{
   752  		Certificates: certs,
   753  	}
   754  
   755  	if addr == "" {
   756  		addr = ":https"
   757  	}
   758  
   759  	// Open the listeners
   760  	udpAddr, err := net.ResolveUDPAddr("udp", addr)
   761  	if err != nil {
   762  		return err
   763  	}
   764  	udpConn, err := net.ListenUDP("udp", udpAddr)
   765  	if err != nil {
   766  		return err
   767  	}
   768  	defer udpConn.Close()
   769  
   770  	if handler == nil {
   771  		handler = http.DefaultServeMux
   772  	}
   773  	// Start the servers
   774  	quicServer := &Server{
   775  		TLSConfig: config,
   776  		Handler:   handler,
   777  	}
   778  
   779  	hErr := make(chan error, 1)
   780  	qErr := make(chan error, 1)
   781  	go func() {
   782  		hErr <- http.ListenAndServeTLS(addr, certFile, keyFile, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   783  			quicServer.SetQuicHeaders(w.Header())
   784  			handler.ServeHTTP(w, r)
   785  		}))
   786  	}()
   787  	go func() {
   788  		qErr <- quicServer.Serve(udpConn)
   789  	}()
   790  
   791  	select {
   792  	case err := <-hErr:
   793  		quicServer.Close()
   794  		return err
   795  	case err := <-qErr:
   796  		// Cannot close the HTTP server or wait for requests to complete properly :/
   797  		return err
   798  	}
   799  }