server.go 23 KB

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