From 99d47050e97a8ccac2aad3bda46be46d4fec85ed Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Thu, 2 Mar 2023 21:00:18 -0700 Subject: core: Eliminate unnecessary shutdown delay on Unix (#5413) * core: Eliminate unnecessary shutdown delay on Unix Fix #5393, alternate to #5405 * Comments, cleanup, adjust logs * Fix build constraint --- modules/caddyhttp/app.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'modules/caddyhttp/app.go') diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index 36a4011..670185a 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -517,7 +517,7 @@ func (app *App) Stop() error { // honor scheduled/delayed shutdown time if delay { - app.logger.Debug("shutdown scheduled", + app.logger.Info("shutdown scheduled", zap.Duration("delay_duration", time.Duration(app.ShutdownDelay)), zap.Time("time", scheduledTime)) time.Sleep(time.Duration(app.ShutdownDelay)) @@ -528,9 +528,9 @@ func (app *App) Stop() error { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, time.Duration(app.GracePeriod)) defer cancel() - app.logger.Debug("servers shutting down; grace period initiated", zap.Duration("duration", time.Duration(app.GracePeriod))) + app.logger.Info("servers shutting down; grace period initiated", zap.Duration("duration", time.Duration(app.GracePeriod))) } else { - app.logger.Debug("servers shutting down with eternal grace period") + app.logger.Info("servers shutting down with eternal grace period") } // goroutines aren't guaranteed to be scheduled right away, -- cgit v1.2.3 From 05e9974570a08df14b1162a1e98315d4ee9ec2ee Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 27 Mar 2023 16:22:59 -0400 Subject: caddyhttp: Determine real client IP if trusted proxies configured (#5104) * caddyhttp: Determine real client IP if trusted proxies configured * Support customizing client IP header * Implement client_ip matcher, deprecate remote_ip's forwarded option --- modules/caddyhttp/app.go | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'modules/caddyhttp/app.go') diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index 670185a..ceb62f4 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -232,6 +232,11 @@ func (app *App) Provision(ctx caddy.Context) error { srv.trustedProxies = val.(IPRangeSource) } + // set the default client IP header to read from + if srv.ClientIPHeaders == nil { + srv.ClientIPHeaders = []string{"X-Forwarded-For"} + } + // process each listener address for i := range srv.Listen { lnOut, err := repl.ReplaceOrErr(srv.Listen[i], true, true) -- cgit v1.2.3 From d8d87a378f37d31cfe6502cc66ac3c95fc799489 Mon Sep 17 00:00:00 2001 From: WeidiDeng Date: Tue, 11 Apr 2023 01:05:02 +0800 Subject: caddyhttp: Serve http2 when listener wrapper doesn't return *tls.Conn (#4929) * Serve http2 when listener wrapper doesn't return *tls.Conn * close conn when h2server serveConn returns * merge from upstream * rebase from latest * run New and Closed ConnState hook for h2 conns * go fmt * fix lint * Add comments * reorder import --- modules/caddyhttp/app.go | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'modules/caddyhttp/app.go') diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index ceb62f4..53b5782 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -357,6 +357,14 @@ func (app *App) Start() error { MaxHeaderBytes: srv.MaxHeaderBytes, Handler: srv, ErrorLog: serverLogger, + ConnContext: func(ctx context.Context, c net.Conn) context.Context { + return context.WithValue(ctx, ConnCtxKey, c) + }, + } + h2server := &http2.Server{ + NewWriteScheduler: func() http2.WriteScheduler { + return http2.NewPriorityWriteScheduler(nil) + }, } // disable HTTP/2, which we enabled by default during provisioning @@ -378,6 +386,9 @@ func (app *App) Start() error { } } } + } else { + //nolint:errcheck + http2.ConfigureServer(srv.server, h2server) } // this TLS config is used by the std lib to choose the actual TLS config for connections @@ -387,9 +398,6 @@ func (app *App) Start() error { // enable H2C if configured if srv.protocol("h2c") { - h2server := &http2.Server{ - IdleTimeout: time.Duration(srv.IdleTimeout), - } srv.server.Handler = h2c.NewHandler(srv, h2server) } @@ -456,6 +464,17 @@ func (app *App) Start() error { ln = srv.listenerWrappers[i].WrapListener(ln) } + // handle http2 if use tls listener wrapper + if useTLS { + http2lnWrapper := &http2Listener{ + Listener: ln, + server: srv.server, + h2server: h2server, + } + srv.h2listeners = append(srv.h2listeners, http2lnWrapper) + ln = http2lnWrapper + } + // if binding to port 0, the OS chooses a port for us; // but the user won't know the port unless we print it if !listenAddr.IsUnixNetwork() && listenAddr.StartPort == 0 && listenAddr.EndPort == 0 { @@ -585,12 +604,25 @@ func (app *App) Stop() error { zap.Strings("addresses", server.Listen)) } } + stopH2Listener := func(server *Server) { + defer finishedShutdown.Done() + startedShutdown.Done() + + for i, s := range server.h2listeners { + if err := s.Shutdown(ctx); err != nil { + app.logger.Error("http2 listener shutdown", + zap.Error(err), + zap.Int("index", i)) + } + } + } for _, server := range app.Servers { - startedShutdown.Add(2) - finishedShutdown.Add(2) + startedShutdown.Add(3) + finishedShutdown.Add(3) go stopServer(server) go stopH3Server(server) + go stopH2Listener(server) } // block until all the goroutines have been run by the scheduler; -- cgit v1.2.3 From cbf16f6d9eb77f37d6eb588ff3e54cfdfddecc21 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Tue, 16 May 2023 11:27:52 -0400 Subject: caddyhttp: Implement named routes, `invoke` directive (#5107) * caddyhttp: Implement named routes, `invoke` directive * gofmt * Add experimental marker * Adjust route compile comments --- modules/caddyhttp/app.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp/app.go') diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index 53b5782..0e02afd 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -293,11 +293,19 @@ func (app *App) Provision(ctx caddy.Context) error { if srv.Errors != nil { err := srv.Errors.Routes.Provision(ctx) if err != nil { - return fmt.Errorf("server %s: setting up server error handling routes: %v", srvName, err) + return fmt.Errorf("server %s: setting up error handling routes: %v", srvName, err) } srv.errorHandlerChain = srv.Errors.Routes.Compile(errorEmptyHandler) } + // provision the named routes (they get compiled at runtime) + for name, route := range srv.NamedRoutes { + err := route.Provision(ctx, srv.Metrics) + if err != nil { + return fmt.Errorf("server %s: setting up named route '%s' handlers: %v", name, srvName, err) + } + } + // prepare the TLS connection policies err = srv.TLSConnPolicies.Provision(ctx) if err != nil { -- cgit v1.2.3 From 29452647d803aa1259b4430b52349ce7ac1495a4 Mon Sep 17 00:00:00 2001 From: WeidiDeng Date: Sat, 20 May 2023 00:00:00 +0800 Subject: caddyhttp: Fix h3 shutdown (#5541) * swap h3server close and listener close, avoid quic-listener not closing * fix typo --- modules/caddyhttp/app.go | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'modules/caddyhttp/app.go') diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index 0e02afd..f774c3a 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -594,6 +594,21 @@ func (app *App) Stop() error { return } + // First close h3server then close listeners unlike stdlib for several reasons: + // 1, udp has only a single socket, once closed, no more data can be read and + // written. In contrast, closing tcp listeners won't affect established connections. + // This have something to do with graceful shutdown when upstream implements it. + // 2, h3server will only close listeners it's registered (quic listeners). Closing + // listener first and these listeners maybe unregistered thus won't be closed. caddy + // distinguishes quic-listener and underlying datagram sockets. + + // TODO: CloseGracefully, once implemented upstream (see https://github.com/quic-go/quic-go/issues/2103) + if err := server.h3server.Close(); err != nil { + app.logger.Error("HTTP/3 server shutdown", + zap.Error(err), + zap.Strings("addresses", server.Listen)) + } + // TODO: we have to manually close our listeners because quic-go won't // close listeners it didn't create along with the server itself... // see https://github.com/quic-go/quic-go/issues/3560 @@ -604,13 +619,6 @@ func (app *App) Stop() error { zap.String("address", el.LocalAddr().String())) } } - - // TODO: CloseGracefully, once implemented upstream (see https://github.com/quic-go/quic-go/issues/2103) - if err := server.h3server.Close(); err != nil { - app.logger.Error("HTTP/3 server shutdown", - zap.Error(err), - zap.Strings("addresses", server.Listen)) - } } stopH2Listener := func(server *Server) { defer finishedShutdown.Done() -- cgit v1.2.3 From cd486c25d168caf58f4b6fe5d3252df9432901ec Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 2 Aug 2023 16:03:26 -0400 Subject: caddyhttp: Make use of `http.ResponseController` (#5654) * caddyhttp: Make use of http.ResponseController Also syncs the reverseproxy implementation with stdlib's which now uses ResponseController as well https://github.com/golang/go/commit/2449bbb5e614954ce9e99c8a481ea2ee73d72d61 * Enable full-duplex for HTTP/1.1 * Appease linter * Add warning for builds with Go 1.20, so it's less surprising to users * Improved godoc for EnableFullDuplex, copied text from stdlib * Only wrap in encode if not already wrapped --- modules/caddyhttp/app.go | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'modules/caddyhttp/app.go') diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index f774c3a..944611d 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -20,7 +20,9 @@ import ( "fmt" "net" "net/http" + "runtime" "strconv" + "strings" "sync" "time" @@ -325,9 +327,15 @@ func (app *App) Provision(ctx caddy.Context) error { // Validate ensures the app's configuration is valid. func (app *App) Validate() error { + isGo120 := strings.Contains(runtime.Version(), "go1.20") + // each server must use distinct listener addresses lnAddrs := make(map[string]string) for srvName, srv := range app.Servers { + if isGo120 && srv.EnableFullDuplex { + app.logger.Warn("enable_full_duplex is not supported in Go 1.20, use a build made with Go 1.21 or later", zap.String("server", srvName)) + } + for _, addr := range srv.Listen { listenAddr, err := caddy.ParseNetworkAddress(addr) if err != nil { -- cgit v1.2.3 From d6f86cccf5fa5b4eb30141da390cf2439746c5da Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 14 Aug 2023 23:41:15 +0800 Subject: ci: use gci linter (#5708) * use gofmput to format code * use gci to format imports * reconfigure gci * linter autofixes * rearrange imports a little * export GOOS=windows golangci-lint run ./... --fix --- modules/caddyhttp/app.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'modules/caddyhttp/app.go') diff --git a/modules/caddyhttp/app.go b/modules/caddyhttp/app.go index 944611d..457a5f4 100644 --- a/modules/caddyhttp/app.go +++ b/modules/caddyhttp/app.go @@ -26,12 +26,13 @@ import ( "sync" "time" - "github.com/caddyserver/caddy/v2" - "github.com/caddyserver/caddy/v2/modules/caddyevents" - "github.com/caddyserver/caddy/v2/modules/caddytls" "go.uber.org/zap" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" + + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/modules/caddyevents" + "github.com/caddyserver/caddy/v2/modules/caddytls" ) func init() { -- cgit v1.2.3