diff --git a/discovery/http/http.go b/discovery/http/http.go index 9c6db98a4b..df093b6578 100644 --- a/discovery/http/http.go +++ b/discovery/http/http.go @@ -21,7 +21,9 @@ import ( "io/ioutil" "net/http" "net/url" + "regexp" "strconv" + "strings" "time" "github.com/go-kit/log" @@ -41,7 +43,8 @@ var ( RefreshInterval: model.Duration(60 * time.Second), HTTPClientConfig: config.DefaultHTTPClientConfig, } - userAgent = fmt.Sprintf("Prometheus/%s", version.Version) + userAgent = fmt.Sprintf("Prometheus/%s", version.Version) + matchContentType = regexp.MustCompile(`^(?i:application\/json(;\s*charset=("utf-8"|utf-8))?)$`) ) func init() { @@ -152,7 +155,7 @@ func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) { return nil, errors.Errorf("server returned HTTP status %s", resp.Status) } - if resp.Header.Get("Content-Type") != "application/json" { + if !matchContentType.MatchString(strings.TrimSpace(resp.Header.Get("Content-Type"))) { return nil, errors.Errorf("unsupported content type %q", resp.Header.Get("Content-Type")) } diff --git a/discovery/http/http_test.go b/discovery/http/http_test.go index c248beb62d..7adcb7c70c 100644 --- a/discovery/http/http_test.go +++ b/discovery/http/http_test.go @@ -104,3 +104,61 @@ func TestHTTPInvalidFormat(t *testing.T) { _, err = d.refresh(ctx) require.EqualError(t, err, `unsupported content type "text/plain; charset=utf-8"`) } + +func TestContentTypeRegex(t *testing.T) { + cases := []struct { + header string + match bool + }{ + { + header: "application/json;charset=utf-8", + match: true, + }, + { + header: "application/json;charset=UTF-8", + match: true, + }, + { + header: "Application/JSON;Charset=\"utf-8\"", + match: true, + }, + { + header: "application/json; charset=\"utf-8\"", + match: true, + }, + { + header: "application/json", + match: true, + }, + { + header: "application/jsonl; charset=\"utf-8\"", + match: false, + }, + { + header: "application/json;charset=UTF-9", + match: false, + }, + { + header: "application /json;charset=UTF-8", + match: false, + }, + { + header: "application/ json;charset=UTF-8", + match: false, + }, + { + header: "application/json;", + match: false, + }, + { + header: "charset=UTF-8", + match: false, + }, + } + + for _, test := range cases { + t.Run(test.header, func(t *testing.T) { + require.Equal(t, test.match, matchContentType.MatchString(test.header)) + }) + } +}