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