From 44710719f890a1cfa5877211185ddb632145c3b1 Mon Sep 17 00:00:00 2001 From: David Leadbeater Date: Thu, 23 Jun 2022 11:09:02 +1000 Subject: [PATCH] Use textproto.CanonicalMIMEHeaderKey Using the full i18n library isn't needed, this just needs to be ASCII per MIME style header standards. Signed-off-by: David Leadbeater Signed-off-by: SuperQ --- config/config.go | 7 ++----- go.mod | 2 +- prober/handler.go | 7 ++----- prober/http.go | 16 ++-------------- prober/http_test.go | 6 ++---- 5 files changed, 9 insertions(+), 29 deletions(-) diff --git a/config/config.go b/config/config.go index 7a23824..246e52d 100644 --- a/config/config.go +++ b/config/config.go @@ -17,6 +17,7 @@ import ( "errors" "fmt" "math" + "net/textproto" "os" "regexp" "runtime" @@ -26,8 +27,6 @@ import ( "sync" "time" - "golang.org/x/text/cases" - "golang.org/x/text/language" yaml "gopkg.in/yaml.v3" "github.com/alecthomas/units" @@ -88,8 +87,6 @@ var ( IPProtocolFallback: true, Recursion: true, } - - caser = cases.Title(language.Und) ) func init() { @@ -334,7 +331,7 @@ func (s *HTTPProbe) UnmarshalYAML(unmarshal func(interface{}) error) error { } for key, value := range s.Headers { - switch caser.String(key) { + switch textproto.CanonicalMIMEHeaderKey(key) { case "Accept-Encoding": if !isCompressionAcceptEncodingValid(s.Compression, value) { return fmt.Errorf(`invalid configuration "%s: %s", "compression: %s"`, key, value, s.Compression) diff --git a/go.mod b/go.mod index f584f77..f6ae5cd 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/prometheus/common v0.37.0 github.com/prometheus/exporter-toolkit v0.7.1 golang.org/x/net v0.0.0-20220728211354-c7608f3a8462 - golang.org/x/text v0.3.7 google.golang.org/grpc v1.48.0 gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/yaml.v2 v2.4.0 @@ -32,6 +31,7 @@ require ( golang.org/x/mod v0.4.2 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.6 // indirect diff --git a/prober/handler.go b/prober/handler.go index 51f6189..f449cac 100644 --- a/prober/handler.go +++ b/prober/handler.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "net/http" + "net/textproto" "net/url" "strconv" "time" @@ -28,8 +29,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/common/expfmt" - "golang.org/x/text/cases" - "golang.org/x/text/language" "gopkg.in/yaml.v2" ) @@ -45,8 +44,6 @@ var ( Name: "blackbox_module_unknown_total", Help: "Count of unknown modules requested by probes", }) - - caser = cases.Title(language.Und) ) func init() { @@ -146,7 +143,7 @@ func setHTTPHost(hostname string, module *config.Module) error { headers := make(map[string]string) if module.HTTP.Headers != nil { for name, value := range module.HTTP.Headers { - if caser.String(name) == "Host" && value != hostname { + if textproto.CanonicalMIMEHeaderKey(name) == "Host" && value != hostname { return fmt.Errorf("host header defined both in module configuration (%s) and with URL-parameter 'hostname' (%s)", value, hostname) } headers[name] = value diff --git a/prober/http.go b/prober/http.go index 4d65c3a..17d75d7 100644 --- a/prober/http.go +++ b/prober/http.go @@ -39,8 +39,6 @@ import ( pconfig "github.com/prometheus/common/config" "github.com/prometheus/common/version" "golang.org/x/net/publicsuffix" - "golang.org/x/text/cases" - "golang.org/x/text/language" "github.com/prometheus/blackbox_exporter/config" ) @@ -343,16 +341,6 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr } } - // 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 @@ -363,7 +351,7 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr // its value instead. This helps avoid TLS handshake error // if targetHost is an IP address. for name, value := range httpConfig.Headers { - if caser.String(name) == "Host" { + if textproto.CanonicalMIMEHeaderKey(name) == "Host" { httpClientConfig.TLSConfig.ServerName = value } } @@ -438,7 +426,7 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr request = request.WithContext(ctx) for key, value := range httpConfig.Headers { - if caser.String(key) == "Host" { + if textproto.CanonicalMIMEHeaderKey(key) == "Host" { request.Host = value continue } diff --git a/prober/http_test.go b/prober/http_test.go index 1ca6127..69fccee 100644 --- a/prober/http_test.go +++ b/prober/http_test.go @@ -24,6 +24,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "net/textproto" "net/url" "os" "strconv" @@ -35,8 +36,6 @@ 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" ) @@ -1070,9 +1069,8 @@ 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 textproto.CanonicalMIMEHeaderKey(key) == "Host" { if r.Host != value { t.Errorf("Unexpected host: expected %q, got %q.", value, r.Host) } -- 2.25.1