From 9e57f5a5f56d5ab1b3bc6c981c948f710c67e2cf Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:00:58 +0800 Subject: [PATCH] fix: stop redirect siblings on shutdown Make the non-graceful HTTPS redirect path shut down all sibling servers after any server returns, so cleanup stays consistent with the graceful path and partial shutdowns do not leave the redirect listener running. --- serve.go | 9 ++++++--- serve_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/serve.go b/serve.go index b2ba358..386eaf5 100644 --- a/serve.go +++ b/serve.go @@ -518,13 +518,16 @@ func (engine *Engine) Run(opts ...RunOption) error { } err := <-serverStopped - if err != nil && !errors.Is(err, http.ErrServerClosed) { - if shutdownErr := shutdownServers(servers, defaultShutdownTimeout); shutdownErr != nil { + if shutdownErr := shutdownServers(servers, defaultShutdownTimeout); shutdownErr != nil { + if err != nil && !errors.Is(err, http.ErrServerClosed) { return errors.Join(err, shutdownErr) } + return shutdownErr + } + if err != nil && !errors.Is(err, http.ErrServerClosed) { return err } - return err + return nil } protocolLabel := "HTTP" diff --git a/serve_test.go b/serve_test.go index 2bdddc5..8de14c3 100644 --- a/serve_test.go +++ b/serve_test.go @@ -2,9 +2,15 @@ package touka import ( "context" + "crypto/rand" + "crypto/rsa" "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" "errors" "io" + "math/big" "net" "net/http" "net/http/httptest" @@ -13,6 +19,41 @@ import ( "time" ) +func generateSelfSignedCert(t *testing.T) tls.Certificate { + t.Helper() + + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("generate private key: %v", err) + } + + tmpl := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{CommonName: "127.0.0.1"}, + NotBefore: time.Now().Add(-time.Hour), + NotAfter: time.Now().Add(time.Hour), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + }, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + } + + der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &privateKey.PublicKey, privateKey) + if err != nil { + t.Fatalf("create self-signed cert: %v", err) + } + + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der}) + keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}) + + cert, err := tls.X509KeyPair(certPEM, keyPEM) + if err != nil { + t.Fatalf("parse self-signed cert: %v", err) + } + return cert +} + func TestServeServerHTTPModeIgnoresTLSConfig(t *testing.T) { listener, err := net.Listen("tcp", "127.0.0.1:0") if err != nil {