server.go 22 KB

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