From 2be0bd717db9298cfbe71364fffffe34bd846336 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 21:33:53 +0000 Subject: [PATCH] Fix data race on injectedHTTPClient in client package Add sync.RWMutex to protect concurrent read/write access to the package-level injectedHTTPClient variable, which was causing flaky test failures when TestGetHTTPClient and TestHttpClientProvidesOAuth2BearerToken ran in parallel with -race. Agent-Logs-Url: https://github.com/TwiN/gatus/sessions/5eccf19f-b033-4bf0-9d3b-4e462e7e89c4 Co-authored-by: TwiN <15699766+TwiN@users.noreply.github.com> --- client/client.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 00a2af44..70cf0485 100644 --- a/client/client.go +++ b/client/client.go @@ -16,6 +16,7 @@ import ( "os" "runtime" "strings" + "sync" "time" "github.com/TwiN/gocache/v2" @@ -36,7 +37,8 @@ const ( var ( // injectedHTTPClient is used for testing purposes - injectedHTTPClient *http.Client + injectedHTTPClient *http.Client + injectedHTTPClientM sync.RWMutex whoisClient = whois.NewClient().WithReferralCache(true) whoisExpirationDateCache = gocache.NewCache().WithMaxSize(10000).WithDefaultTTL(24 * time.Hour) @@ -45,6 +47,8 @@ var ( // GetHTTPClient returns the shared HTTP client, or the client from the configuration passed func GetHTTPClient(config *Config) *http.Client { + injectedHTTPClientM.RLock() + defer injectedHTTPClientM.RUnlock() if injectedHTTPClient != nil { return injectedHTTPClient } @@ -508,7 +512,9 @@ func QueryDNS(queryType, queryName, url string) (connected bool, dnsRcode string // InjectHTTPClient is used to inject a custom HTTP client for testing purposes func InjectHTTPClient(httpClient *http.Client) { + injectedHTTPClientM.Lock() injectedHTTPClient = httpClient + injectedHTTPClientM.Unlock() } // rdapQuery returns domain expiration via RDAP protocol