From e38d38df83dab0d75c15837d6222a4d7f1111fa7 Mon Sep 17 00:00:00 2001 From: "Marcelo E. Magallon" Date: Mon, 13 Jun 2022 17:21:41 -0600 Subject: [PATCH] Make caser a local varialbe, not a global one. The cases.Caser returned by calling cases.Title *cannot* be shared among goroutines. This might happen when Prometheus tries to scrape multiple targets at the same time. From the docs: A Caser may be stateful and should therefore not be shared between goroutines. Fixes: #922 Signed-off-by: Marcelo E. Magallon --- prober/http.go | 12 ++++++++++-- prober/http_test.go | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/prober/http.go b/prober/http.go index 54f4099..99d38a2 100644 --- a/prober/http.go +++ b/prober/http.go @@ -46,8 +46,6 @@ import ( "github.com/prometheus/blackbox_exporter/config" ) -var caser = cases.Title(language.Und) - func matchRegularExpressions(reader io.Reader, httpConfig config.HTTPProbe, logger log.Logger) bool { body, err := ioutil.ReadAll(reader) if err != nil { @@ -342,6 +340,16 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr return false } + // Do not move the following variable to global scope. The cases.Caser returned by + // calling cases.Title *cannot* be shared among goroutines. This might happen when + // Prometheus tries to scrape multiple targets at the same time. From the docs: + // + // A Caser may be stateful and should therefore not be shared between goroutines. + // + // Issue: https://github.com/prometheus/blackbox_exporter/issues/922 + + caser := cases.Title(language.Und) + httpClientConfig := module.HTTP.HTTPClientConfig if len(httpClientConfig.TLSConfig.ServerName) == 0 { // If there is no `server_name` in tls_config, use diff --git a/prober/http_test.go b/prober/http_test.go index dc5b65b..cd27761 100644 --- a/prober/http_test.go +++ b/prober/http_test.go @@ -35,6 +35,8 @@ import ( "github.com/go-kit/log" "github.com/prometheus/client_golang/prometheus" pconfig "github.com/prometheus/common/config" + "golang.org/x/text/cases" + "golang.org/x/text/language" "github.com/prometheus/blackbox_exporter/config" ) @@ -1068,6 +1070,7 @@ func TestHTTPHeaders(t *testing.T) { "Accept-Language": "en-US", } ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + caser := cases.Title(language.Und) for key, value := range headers { if caser.String(key) == "Host" { if r.Host != value { -- 2.25.1