From f17b6144db08ae1c12f2ad64b7896a8721afb234 Mon Sep 17 00:00:00 2001 From: Ofer Chen Date: Thu, 28 Aug 2025 06:24:15 +0200 Subject: [PATCH] transport/h2: propagate clearDeadline errors --- transport/h2/h2.go | 2 +- transport/h2/h2_test.go | 45 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/transport/h2/h2.go b/transport/h2/h2.go index 71b82bb6..1acf1977 100644 --- a/transport/h2/h2.go +++ b/transport/h2/h2.go @@ -170,7 +170,7 @@ func (t *Transport) performH2Handshake(ctx context.Context, conn *tls.Conn) (*ht } if err := ctx.Err(); err != nil { if derr := t.clearDeadline(conn); derr != nil { - return derr + return multierr.Append(err, derr) } return err } diff --git a/transport/h2/h2_test.go b/transport/h2/h2_test.go index d84eba3e..a723f986 100644 --- a/transport/h2/h2_test.go +++ b/transport/h2/h2_test.go @@ -209,6 +209,51 @@ func TestPerformH2HandshakeClearDeadlineError(t *testing.T) { <-done } +func TestPerformH2HandshakeClearDeadlineContextError(t *testing.T) { + cert, pool := generateSelfSignedCert(t) + + serverConf := &tls.Config{ + Certificates: []tls.Certificate{cert}, + NextProtos: []string{"h2"}, + MinVersion: tls.VersionTLS13, + MaxVersion: tls.VersionTLS13, + } + clientConf := &tls.Config{ + RootCAs: pool, + NextProtos: []string{"h2"}, + MinVersion: tls.VersionTLS13, + MaxVersion: tls.VersionTLS13, + ServerName: "127.0.0.1", + } + + c1, c2 := net.Pipe() + srv := tls.Server(c1, serverConf) + cli := tls.Client(c2, clientConf) + errCh := make(chan error, 1) + go func() { errCh <- srv.Handshake() }() + if err := cli.Handshake(); err != nil { + t.Fatalf("client handshake: %v", err) + } + if err := <-errCh; err != nil { + t.Fatalf("server handshake: %v", err) + } + + wantErr := errors.New("clear deadline fail") + tr := &Transport{ + logger: zap.NewNop(), + clearDeadline: func(net.Conn) error { return wantErr }, + } + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := tr.performH2Handshake(ctx, cli); !errors.Is(err, wantErr) || !errors.Is(err, context.Canceled) { + t.Fatalf("expected combined context and clearDeadline errors, got %v", err) + } + + cli.Close() + srv.Close() +} + func TestPerformH2Handshake(t *testing.T) { cert, pool := generateSelfSignedCert(t) serverConf := &tls.Config{Certificates: []tls.Certificate{cert}, NextProtos: []string{"h2"}, MinVersion: tls.VersionTLS13, MaxVersion: tls.VersionTLS13}