package tracerconfig import ( "context" "net/http" ) // bearerCredentials implements gRPC PerRPCCredentials for bearer token authentication. // It is safe for concurrent use as required by the gRPC PerRPCCredentials interface. type bearerCredentials struct { tokenFunc BearerTokenFunc } // GetRequestMetadata returns authorization metadata for each RPC call. // It calls the token function to retrieve the current token. func (c *bearerCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { token, err := c.tokenFunc(ctx) if err != nil { return nil, err } if token == "" { return nil, nil // Omit header for empty token } return map[string]string{"authorization": "Bearer " + token}, nil } // RequireTransportSecurity returns true because bearer tokens require TLS. func (c *bearerCredentials) RequireTransportSecurity() bool { return true } // bearerRoundTripper wraps an http.RoundTripper to add bearer token authentication. // It is safe for concurrent use as required by the http.RoundTripper interface. type bearerRoundTripper struct { base http.RoundTripper tokenFunc BearerTokenFunc } // RoundTrip adds the Authorization header with the bearer token. func (rt *bearerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { token, err := rt.tokenFunc(req.Context()) if err != nil { return nil, err } if token == "" { return rt.base.RoundTrip(req) } // Clone only when adding a header to preserve the original request req = req.Clone(req.Context()) req.Header.Set("Authorization", "Bearer "+token) return rt.base.RoundTrip(req) }