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
This commit is contained in:
Matt Holt
2019-09-10 08:03:37 -06:00
committed by GitHub
parent d67d8cf5a8
commit 0c8ad52be1
6 changed files with 153 additions and 6 deletions
+47 -1
View File
@@ -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
}
+3
View File
@@ -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
}