server.go 22 KB

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