From 0c8ad52be127add6f2c050230f1f166ecbde813c Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Tue, 10 Sep 2019 08:03:37 -0600 Subject: Experimental IETF-standard HTTP/3 support (known issue exists) (#2727) * Begin WIP integration of HTTP/3 support * http3: Set actual Handler, make fakeClosePacketConn type for UDP sockets Also use latest quic-go for ALPN fix * Manually keep track of and close HTTP/3 listeners * Update quic-go after working through some http3 bugs * Fix go mod * Make http3 optional for now --- modules/caddyhttp/caddyhttp.go | 48 +++++++++++++++++++++++++++++++++++++++++- modules/caddyhttp/server.go | 3 +++ 2 files changed, 50 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp') diff --git a/modules/caddyhttp/caddyhttp.go b/modules/caddyhttp/caddyhttp.go index 9dfdf36..7f33c1d 100644 --- a/modules/caddyhttp/caddyhttp.go +++ b/modules/caddyhttp/caddyhttp.go @@ -31,6 +31,7 @@ import ( "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddytls" + "github.com/lucas-clemente/quic-go/http3" "github.com/mholt/certmagic" ) @@ -50,7 +51,9 @@ type App struct { GracePeriod caddy.Duration `json:"grace_period,omitempty"` Servers map[string]*Server `json:"servers,omitempty"` - servers []*http.Server + servers []*http.Server + h3servers []*http3.Server + h3listeners []net.PacketConn ctx caddy.Context } @@ -187,6 +190,27 @@ func (app *App) Start() error { return fmt.Errorf("%s/%s: making TLS configuration: %v", network, addr, err) } ln = tls.NewListener(ln, tlsCfg) + + ///////// + // TODO: HTTP/3 support is experimental for now + if srv.ExperimentalHTTP3 { + log.Printf("[INFO] Enabling experimental HTTP/3 listener on %s", addr) + h3ln, err := caddy.ListenPacket("udp", addr) + if err != nil { + return fmt.Errorf("getting HTTP/3 UDP listener: %v", err) + } + h3srv := &http3.Server{ + Server: &http.Server{ + Addr: addr, + Handler: srv, + TLSConfig: tlsCfg, + }, + } + go h3srv.Serve(h3ln) + app.h3servers = append(app.h3servers, h3srv) + app.h3listeners = append(app.h3listeners, h3ln) + } + ///////// } go s.Serve(ln) @@ -212,6 +236,28 @@ func (app *App) Stop() error { return err } } + // TODO: Closing the http3.Server is the right thing to do, + // however, doing so sometimes causes connections from clients + // to fail after config reloads due to a bug that is yet + // unsolved: https://github.com/caddyserver/caddy/pull/2727 + // for _, s := range app.h3servers { + // // TODO: CloseGracefully, once implemented upstream + // // (see https://github.com/lucas-clemente/quic-go/issues/2103) + // err := s.Close() + // if err != nil { + // return err + // } + // } + // as of September 2019, closing the http3.Server + // instances doesn't close their underlying listeners + // so we have todo that ourselves + // (see https://github.com/lucas-clemente/quic-go/issues/2103) + for _, pc := range app.h3listeners { + err := pc.Close() + if err != nil { + return err + } + } return nil } diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index dc38b19..e16a600 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -43,6 +43,9 @@ type Server struct { MaxRehandles *int `json:"max_rehandles,omitempty"` StrictSNIHost bool `json:"strict_sni_host,omitempty"` + // This field is not subject to compatibility promises + ExperimentalHTTP3 bool `json:"experimental_http3,omitempty"` + tlsApp *caddytls.TLS } -- cgit v1.2.3