Repository: prometheus/common (go)

Issue:
Authorization credentials should be optional
As part of [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-introduction), authorization is defined in ABNF as:

```
Authorization = auth-scheme [ 1*SP ( token68 / [ auth-param *( OWS "," OWS auth-param ) ] ) ]
```

This means that the scheme MUST be provided but credentials are optional.

Pull request description:
Allow using empty Authorization credentials
Resolves #545. Looks like we didn't have any validation here. That may make this a breaking change if users rely on this (incorrect) behavior.

cc @roidelapluie who seems to have written most of the original code. :)

Patch:
diff --git a/config/http_config.go b/config/http_config.go
index 4763549..14ee673 100644
--- a/config/http_config.go
+++ b/config/http_config.go
@@ -546,10 +546,10 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HT
 
 		// If a authorization_credentials is provided, create a round tripper that will set the
 		// Authorization header correctly on each request.
-		if cfg.Authorization != nil && len(cfg.Authorization.Credentials) > 0 {
-			rt = NewAuthorizationCredentialsRoundTripper(cfg.Authorization.Type, cfg.Authorization.Credentials, rt)
-		} else if cfg.Authorization != nil && len(cfg.Authorization.CredentialsFile) > 0 {
+		if cfg.Authorization != nil && len(cfg.Authorization.CredentialsFile) > 0 {
 			rt = NewAuthorizationCredentialsFileRoundTripper(cfg.Authorization.Type, cfg.Authorization.CredentialsFile, rt)
+		} else if cfg.Authorization != nil {
+			rt = NewAuthorizationCredentialsRoundTripper(cfg.Authorization.Type, cfg.Authorization.Credentials, rt)
 		}
 		// Backwards compatibility, be nice with importers who would not have
 		// called Validate().


Test patch:
diff --git a/config/http_config_test.go b/config/http_config_test.go
index 4ebe038..72d1e79 100644
--- a/config/http_config_test.go
+++ b/config/http_config_test.go
@@ -269,6 +269,27 @@ func TestNewClientFromConfig(t *testing.T) {
 					fmt.Fprint(w, ExpectedMessage)
 				}
 			},
+		}, {
+			clientConfig: HTTPClientConfig{
+				Authorization: &Authorization{
+					Type: AuthorizationType,
+				},
+				TLSConfig: TLSConfig{
+					CAFile:             TLSCAChainPath,
+					CertFile:           ClientCertificatePath,
+					KeyFile:            ClientKeyNoPassPath,
+					ServerName:         "",
+					InsecureSkipVerify: false},
+			},
+			handler: func(w http.ResponseWriter, r *http.Request) {
+				bearer := r.Header.Get("Authorization")
+				if strings.TrimSpace(bearer) != AuthorizationType {
+					fmt.Fprintf(w, "The expected Bearer Authorization (%s) differs from the obtained Bearer Authorization (%s)",
+						AuthorizationType, bearer)
+				} else {
+					fmt.Fprint(w, ExpectedMessage)
+				}
+			},
 		}, {
 			clientConfig: HTTPClientConfig{
 				Authorization: &Authorization{