From 01d91987af07e379de56674de31360f38ee53bd9 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Sun, 18 Jan 2026 16:21:48 +0100 Subject: [PATCH] feat(challenge): add context --- challenge/dns01/dns_challenge.go | 6 +++--- challenge/dns01/dns_challenge_test.go | 12 ++++++------ challenge/http01/http_challenge.go | 4 ++-- challenge/http01/http_challenge_server.go | 5 +++-- challenge/provider.go | 9 ++++++--- challenge/resolver/prober.go | 14 +++++++------- challenge/tlsalpn01/tls_alpn_challenge.go | 4 ++-- challenge/tlsalpn01/tls_alpn_challenge_server.go | 5 +++-- 8 files changed, 32 insertions(+), 27 deletions(-) diff --git a/challenge/dns01/dns_challenge.go b/challenge/dns01/dns_challenge.go index d855eb4b7..9956562f0 100644 --- a/challenge/dns01/dns_challenge.go +++ b/challenge/dns01/dns_challenge.go @@ -77,7 +77,7 @@ func (c *Challenge) PreSolve(ctx context.Context, authz acme.Authorization) erro return err } - err = c.provider.Present(authz.Identifier.Value, chlng.Token, keyAuth) + err = c.provider.Present(ctx, authz.Identifier.Value, chlng.Token, keyAuth) if err != nil { return fmt.Errorf("[%s] acme: error presenting token: %w", domain, err) } @@ -134,7 +134,7 @@ func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error { } // CleanUp cleans the challenge. -func (c *Challenge) CleanUp(authz acme.Authorization) error { +func (c *Challenge) CleanUp(ctx context.Context, authz acme.Authorization) error { log.Info("acme: Cleaning DNS-01 challenge.", "domain", challenge.GetTargetedDomain(authz)) chlng, err := challenge.FindChallenge(challenge.DNS01, authz) @@ -147,7 +147,7 @@ func (c *Challenge) CleanUp(authz acme.Authorization) error { return err } - return c.provider.CleanUp(authz.Identifier.Value, chlng.Token, keyAuth) + return c.provider.CleanUp(ctx, authz.Identifier.Value, chlng.Token, keyAuth) } func (c *Challenge) Sequential() (bool, time.Duration) { diff --git a/challenge/dns01/dns_challenge_test.go b/challenge/dns01/dns_challenge_test.go index 8fa26a506..7c8872e7f 100644 --- a/challenge/dns01/dns_challenge_test.go +++ b/challenge/dns01/dns_challenge_test.go @@ -21,17 +21,17 @@ type providerMock struct { present, cleanUp error } -func (p *providerMock) Present(domain, token, keyAuth string) error { return p.present } -func (p *providerMock) CleanUp(domain, token, keyAuth string) error { return p.cleanUp } +func (p *providerMock) Present(_ context.Context, _, _, _ string) error { return p.present } +func (p *providerMock) CleanUp(_ context.Context, _, _, _ string) error { return p.cleanUp } type providerTimeoutMock struct { present, cleanUp error timeout, interval time.Duration } -func (p *providerTimeoutMock) Present(domain, token, keyAuth string) error { return p.present } -func (p *providerTimeoutMock) CleanUp(domain, token, keyAuth string) error { return p.cleanUp } -func (p *providerTimeoutMock) Timeout() (time.Duration, time.Duration) { return p.timeout, p.interval } +func (p *providerTimeoutMock) Present(_ context.Context, _, _, _ string) error { return p.present } +func (p *providerTimeoutMock) CleanUp(_ context.Context, _, _, _ string) error { return p.cleanUp } +func (p *providerTimeoutMock) Timeout() (time.Duration, time.Duration) { return p.timeout, p.interval } func TestChallenge_PreSolve(t *testing.T) { server := tester.MockACMEServer().BuildHTTPS(t) @@ -285,7 +285,7 @@ func TestChallenge_CleanUp(t *testing.T) { }, } - err = chlg.CleanUp(authz) + err = chlg.CleanUp(t.Context(), authz) if test.expectError { require.Error(t, err) } else { diff --git a/challenge/http01/http_challenge.go b/challenge/http01/http_challenge.go index 57424490c..c27ae12b5 100644 --- a/challenge/http01/http_challenge.go +++ b/challenge/http01/http_challenge.go @@ -67,13 +67,13 @@ func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error { return err } - err = c.provider.Present(authz.Identifier.Value, chlng.Token, keyAuth) + err = c.provider.Present(ctx, authz.Identifier.Value, chlng.Token, keyAuth) if err != nil { return fmt.Errorf("[%s] acme: error presenting token: %w", domain, err) } defer func() { - err := c.provider.CleanUp(authz.Identifier.Value, chlng.Token, keyAuth) + err := c.provider.CleanUp(ctx, authz.Identifier.Value, chlng.Token, keyAuth) if err != nil { log.Warn("acme: cleaning up failed.", "domain", domain, "error", err) } diff --git a/challenge/http01/http_challenge_server.go b/challenge/http01/http_challenge_server.go index 7960171ed..7350f6213 100644 --- a/challenge/http01/http_challenge_server.go +++ b/challenge/http01/http_challenge_server.go @@ -1,6 +1,7 @@ package http01 import ( + "context" "fmt" "io/fs" "net" @@ -75,7 +76,7 @@ func NewUnixProviderServer(socketPath string, socketMode fs.FileMode) *ProviderS } // Present starts a web server and makes the token available at `ChallengePath(token)` for web requests. -func (s *ProviderServer) Present(domain, token, keyAuth string) error { +func (s *ProviderServer) Present(ctx context.Context, domain, token, keyAuth string) error { var err error s.listener, err = net.Listen(s.network, s.GetAddress()) @@ -97,7 +98,7 @@ func (s *ProviderServer) Present(domain, token, keyAuth string) error { } // CleanUp closes the HTTP server and removes the token from `ChallengePath(token)`. -func (s *ProviderServer) CleanUp(domain, token, keyAuth string) error { +func (s *ProviderServer) CleanUp(ctx context.Context, domain, token, keyAuth string) error { if s.listener == nil { return nil } diff --git a/challenge/provider.go b/challenge/provider.go index d7cc213f7..396ab1bc6 100644 --- a/challenge/provider.go +++ b/challenge/provider.go @@ -1,14 +1,17 @@ package challenge -import "time" +import ( + "context" + "time" +) // Provider enables implementing a custom challenge // provider. Present presents the solution to a challenge available to // be solved. CleanUp will be called by the challenge if Present ends // in a non-error state. type Provider interface { - Present(domain, token, keyAuth string) error - CleanUp(domain, token, keyAuth string) error + Present(ctx context.Context, domain, token, keyAuth string) error + CleanUp(ctx context.Context, domain, token, keyAuth string) error } // ProviderTimeout allows for implementing a diff --git a/challenge/resolver/prober.go b/challenge/resolver/prober.go index ea8f9a512..f36f8e1f8 100644 --- a/challenge/resolver/prober.go +++ b/challenge/resolver/prober.go @@ -23,7 +23,7 @@ type preSolver interface { // Interface for challenges like dns, where we can solve all the challenges before to delete them. type cleanup interface { - CleanUp(authorization acme.Authorization) error + CleanUp(ctx context.Context, authorization acme.Authorization) error } type sequential interface { @@ -108,7 +108,7 @@ func sequentialSolve(ctx context.Context, authSolvers []*selectedAuthSolver, fai if err != nil { failures[domain] = err - cleanUp(authSolver.solver, authSolver.authz) + cleanUp(ctx, authSolver.solver, authSolver.authz) continue } @@ -119,13 +119,13 @@ func sequentialSolve(ctx context.Context, authSolvers []*selectedAuthSolver, fai if err != nil { failures[domain] = err - cleanUp(authSolver.solver, authSolver.authz) + cleanUp(ctx, authSolver.solver, authSolver.authz) continue } // Clean challenge - cleanUp(authSolver.solver, authSolver.authz) + cleanUp(ctx, authSolver.solver, authSolver.authz) if len(authSolvers)-1 > i { solvr := authSolver.solver.(sequential) @@ -151,7 +151,7 @@ func parallelSolve(ctx context.Context, authSolvers []*selectedAuthSolver, failu defer func() { // Clean all created TXT records for _, authSolver := range authSolvers { - cleanUp(authSolver.solver, authSolver.authz) + cleanUp(ctx, authSolver.solver, authSolver.authz) } }() @@ -172,11 +172,11 @@ func parallelSolve(ctx context.Context, authSolvers []*selectedAuthSolver, failu } } -func cleanUp(solvr solver, authz acme.Authorization) { +func cleanUp(ctx context.Context, solvr solver, authz acme.Authorization) { if solvr, ok := solvr.(cleanup); ok { domain := challenge.GetTargetedDomain(authz) - err := solvr.CleanUp(authz) + err := solvr.CleanUp(ctx, authz) if err != nil { log.Warn("acme: cleaning up failed.", "domain", domain, "error", err) } diff --git a/challenge/tlsalpn01/tls_alpn_challenge.go b/challenge/tlsalpn01/tls_alpn_challenge.go index 7fa133f2e..5c214567c 100644 --- a/challenge/tlsalpn01/tls_alpn_challenge.go +++ b/challenge/tlsalpn01/tls_alpn_challenge.go @@ -73,13 +73,13 @@ func (c *Challenge) Solve(ctx context.Context, authz acme.Authorization) error { return err } - err = c.provider.Present(domain, chlng.Token, keyAuth) + err = c.provider.Present(ctx, domain, chlng.Token, keyAuth) if err != nil { return fmt.Errorf("[%s] acme: error presenting token: %w", challenge.GetTargetedDomain(authz), err) } defer func() { - err := c.provider.CleanUp(domain, chlng.Token, keyAuth) + err := c.provider.CleanUp(ctx, domain, chlng.Token, keyAuth) if err != nil { log.Warn("acme: cleaning up failed.", "domain", challenge.GetTargetedDomain(authz), err) } diff --git a/challenge/tlsalpn01/tls_alpn_challenge_server.go b/challenge/tlsalpn01/tls_alpn_challenge_server.go index 4fdf2c810..583c977ee 100644 --- a/challenge/tlsalpn01/tls_alpn_challenge_server.go +++ b/challenge/tlsalpn01/tls_alpn_challenge_server.go @@ -1,6 +1,7 @@ package tlsalpn01 import ( + "context" "crypto/tls" "errors" "fmt" @@ -66,7 +67,7 @@ func NewProviderServer(host, port string) *ProviderServer { // Present generates a certificate with an SHA-256 digest of the keyAuth provided // as the acmeValidation-v1 extension value to conform to the ACME-TLS-ALPN spec. -func (s *ProviderServer) Present(domain, token, keyAuth string) error { +func (s *ProviderServer) Present(ctx context.Context, domain, token, keyAuth string) error { // Generate the challenge certificate using the provided keyAuth and domain. cert, err := ChallengeCert(domain, keyAuth) if err != nil { @@ -101,7 +102,7 @@ func (s *ProviderServer) Present(domain, token, keyAuth string) error { } // CleanUp closes the HTTPS server. -func (s *ProviderServer) CleanUp(domain, token, keyAuth string) error { +func (s *ProviderServer) CleanUp(ctx context.Context, domain, token, keyAuth string) error { if s.listener == nil { return nil }