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.
This commit is contained in:
wjqserver 2026-04-07 20:00:58 +08:00
parent e2cf08d5dd
commit 9e57f5a5f5
2 changed files with 47 additions and 3 deletions

View file

@ -518,13 +518,16 @@ func (engine *Engine) Run(opts ...RunOption) error {
} }
err := <-serverStopped 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 errors.Join(err, shutdownErr)
} }
return shutdownErr
}
if err != nil && !errors.Is(err, http.ErrServerClosed) {
return err return err
} }
return err return nil
} }
protocolLabel := "HTTP" protocolLabel := "HTTP"

View file

@ -2,9 +2,15 @@ package touka
import ( import (
"context" "context"
"crypto/rand"
"crypto/rsa"
"crypto/tls" "crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"errors" "errors"
"io" "io"
"math/big"
"net" "net"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@ -13,6 +19,41 @@ import (
"time" "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) { func TestServeServerHTTPModeIgnoresTLSConfig(t *testing.T) {
listener, err := net.Listen("tcp", "127.0.0.1:0") listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil { if err != nil {