Use textproto.CanonicalMIMEHeaderKey
authorDavid Leadbeater <dgl@dgl.cx>
Thu, 23 Jun 2022 01:09:02 +0000 (11:09 +1000)
committerSuraj Nath <9503187+electron0zero@users.noreply.github.com>
Fri, 30 Sep 2022 10:09:17 +0000 (15:39 +0530)
Using the full i18n library isn't needed, this just needs to be ASCII
per MIME style header standards.

Signed-off-by: David Leadbeater <dgl@dgl.cx>
Signed-off-by: SuperQ <superq@gmail.com>
config/config.go
go.mod
prober/handler.go
prober/http.go
prober/http_test.go

index 7a238244a0bdba0981a0764cb13eb51d49c7f68b..246e52d804053be24d7d8bef693a0150d080c84e 100644 (file)
@@ -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 f584f779af25206eb3e052f10351d86dbc267d19..f6ae5cdbcdb75c82c0cc68cd62e316ad74cf3f69 100644 (file)
--- 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
index 51f6189a5dab96f02094eb46eb297098f897946e..f449cace287fb92510d1fdf0c9aeb46e63697474 100644 (file)
@@ -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
index 4d65c3a4d0a9fc61defc51f2b69e04125d8cb8b3..17d75d75409a7189c8f02d702a9394f8ca587ea9 100644 (file)
@@ -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
                }
index 1ca6127d2a5245d1df3c8d29ededaba72f1e1e72..69fcceefc06c7a17071404c7dcbb999b9d603ec6 100644 (file)
@@ -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)
                                }