Compare commits

...

2 Commits

Author SHA1 Message Date
Hein 705c4f8001 fix(manager): ensure HTTP1 is set when HTTP2 is disabled
Tests / Integration Tests (push) Failing after 1s
Tests / Unit Tests (push) Failing after 1m41s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 3m50s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 3m53s
Build , Vet Test, and Lint / Build (push) Successful in 3m55s
Build , Vet Test, and Lint / Lint Code (push) Successful in 4m3s
2026-06-30 13:54:56 +02:00
Hein d648614611 feat(config): add PanicHandler to Config for custom recovery 2026-06-30 13:49:51 +02:00
2 changed files with 22 additions and 2 deletions
+4
View File
@@ -42,6 +42,10 @@ type Config struct {
// AutoTLSEmail is the email for Let's Encrypt registration (optional but recommended) // AutoTLSEmail is the email for Let's Encrypt registration (optional but recommended)
AutoTLSEmail string AutoTLSEmail string
// PanicHandler is called when a request handler panics.
// If nil, the default middleware.PanicRecovery is used (logs, records metric, returns 500).
PanicHandler func(w http.ResponseWriter, r *http.Request, rcv any)
// Graceful shutdown configuration // Graceful shutdown configuration
// ShutdownTimeout is the maximum time to wait for graceful shutdown // ShutdownTimeout is the maximum time to wait for graceful shutdown
// Default: 30 seconds // Default: 30 seconds
+18 -2
View File
@@ -452,8 +452,19 @@ func newInstance(cfg Config) (*serverInstance, error) {
handler = gz(handler) handler = gz(handler)
} }
// Wrap with the panic recovery middleware // Wrap with panic recovery — use caller-supplied handler if provided
handler = middleware.PanicRecovery(handler) if cfg.PanicHandler != nil {
handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rcv := recover(); rcv != nil {
cfg.PanicHandler(w, r, rcv)
}
}()
handler.ServeHTTP(w, r)
})
} else {
handler = middleware.PanicRecovery(handler)
}
// Configure TLS if any TLS option is enabled // Configure TLS if any TLS option is enabled
tlsConfig, certFile, keyFile, err := configureTLS(cfg) tlsConfig, certFile, keyFile, err := configureTLS(cfg)
@@ -475,6 +486,10 @@ func newInstance(cfg Config) (*serverInstance, error) {
// The GODEBUG=http2xconnect=1 flag is read by net/http's init(); setting it here // The GODEBUG=http2xconnect=1 flag is read by net/http's init(); setting it here
// ensures it propagates to subprocesses and any future process restarts. // ensures it propagates to subprocesses and any future process restarts.
// For the current process, set GODEBUG=http2xconnect=1 in the environment before launch. // For the current process, set GODEBUG=http2xconnect=1 in the environment before launch.
if httpServer.Protocols == nil {
httpServer.Protocols = &http.Protocols{}
httpServer.Protocols.SetHTTP1(true)
}
if cfg.HTTP2 { if cfg.HTTP2 {
if existing := os.Getenv("GODEBUG"); !strings.Contains(existing, "http2xconnect=1") { if existing := os.Getenv("GODEBUG"); !strings.Contains(existing, "http2xconnect=1") {
if existing == "" { if existing == "" {
@@ -489,6 +504,7 @@ func newInstance(cfg Config) (*serverInstance, error) {
httpServer.Protocols.SetHTTP2(true) httpServer.Protocols.SetHTTP2(true)
httpServer.Protocols.SetUnencryptedHTTP2(true) httpServer.Protocols.SetUnencryptedHTTP2(true)
} else { } else {
httpServer.Protocols.SetHTTP1(true)
httpServer.Protocols.SetHTTP2(false) httpServer.Protocols.SetHTTP2(false)
} }