Skip to content

Commit f862141

Browse files
committed
Add setting to enable/disable utf 8 label names
1 parent ba8d6e9 commit f862141

File tree

4 files changed

+123
-50
lines changed

4 files changed

+123
-50
lines changed

pkg/featureflags/client_capability.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,42 @@ package featureflags
22

33
import (
44
"context"
5+
"flag"
56
"mime"
67
"net/http"
78
"strings"
89

910
"connectrpc.com/connect"
11+
"github.com/go-kit/log"
1012
"github.com/go-kit/log/level"
1113
"github.com/grafana/dskit/middleware"
12-
"github.com/grafana/pyroscope/pkg/util"
1314
"google.golang.org/grpc"
1415
"google.golang.org/grpc/metadata"
1516
)
1617

1718
const (
1819
// Capability names - update parseClientCapabilities below when new capabilities added
1920
allowUtf8LabelNamesCapabilityName string = "allow-utf8-labelnames"
21+
22+
// Config
23+
clientCapabilityPrefix = "client-capability."
24+
allowUtf8LabelNames = clientCapabilityPrefix + allowUtf8LabelNamesCapabilityName
2025
)
2126

27+
type ClientCapabilityConfig struct {
28+
AllowUtf8LabelNames bool `yaml:"allow_utf_8_label_names" category:"experimental"`
29+
}
30+
31+
func (cfg *ClientCapabilityConfig) RegisterFlags(fs *flag.FlagSet) {
32+
fs.BoolVar(
33+
&cfg.AllowUtf8LabelNames,
34+
allowUtf8LabelNames,
35+
false,
36+
"Enable reading and writing utf-8 label names. To use this feature, API calls must "+
37+
"include `allow-utf8-labelnames=true` in the `Accept` header.",
38+
)
39+
}
40+
2241
// Define a custom context key type to avoid collisions
2342
type contextKey struct{}
2443

@@ -35,7 +54,7 @@ func GetClientCapabilities(ctx context.Context) (ClientCapabilities, bool) {
3554
return value, ok
3655
}
3756

38-
func ClientCapabilitiesGRPCMiddleware() grpc.UnaryServerInterceptor {
57+
func ClientCapabilitiesGRPCMiddleware(cfg *ClientCapabilityConfig, logger log.Logger) grpc.UnaryServerInterceptor {
3958
return func(
4059
ctx context.Context,
4160
req interface{},
@@ -56,7 +75,7 @@ func ClientCapabilitiesGRPCMiddleware() grpc.UnaryServerInterceptor {
5675
}
5776

5877
// Reuse existing HTTP header parsing
59-
clientCapabilities, err := parseClientCapabilities(httpHeader)
78+
clientCapabilities, err := parseClientCapabilities(httpHeader, cfg, logger)
6079
if err != nil {
6180
return nil, connect.NewError(connect.CodeInvalidArgument, err)
6281
}
@@ -68,10 +87,10 @@ func ClientCapabilitiesGRPCMiddleware() grpc.UnaryServerInterceptor {
6887

6988
// ClientCapabilitiesHttpMiddleware creates middleware that extracts and parses the
7089
// `Accept` header for capabilities the client supports
71-
func ClientCapabilitiesHttpMiddleware() middleware.Interface {
90+
func ClientCapabilitiesHttpMiddleware(cfg *ClientCapabilityConfig, logger log.Logger) middleware.Interface {
7291
return middleware.Func(func(next http.Handler) http.Handler {
7392
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
74-
clientCapabilities, err := parseClientCapabilities(r.Header)
93+
clientCapabilities, err := parseClientCapabilities(r.Header, cfg, logger)
7594
if err != nil {
7695
http.Error(w, "Invalid header format: "+err.Error(), http.StatusBadRequest)
7796
return
@@ -83,7 +102,7 @@ func ClientCapabilitiesHttpMiddleware() middleware.Interface {
83102
})
84103
}
85104

86-
func parseClientCapabilities(header http.Header) (ClientCapabilities, error) {
105+
func parseClientCapabilities(header http.Header, cfg *ClientCapabilityConfig, logger log.Logger) (ClientCapabilities, error) {
87106
acceptHeaderValues := header.Values("Accept")
88107

89108
var capabilities ClientCapabilities
@@ -100,10 +119,16 @@ func parseClientCapabilities(header http.Header) (ClientCapabilities, error) {
100119
switch k {
101120
case allowUtf8LabelNamesCapabilityName:
102121
if v == "true" {
103-
capabilities.AllowUtf8LabelNames = true
122+
if !cfg.AllowUtf8LabelNames {
123+
level.Warn(logger).Log(
124+
"msg", "client requested capability that is not enabled on server",
125+
"capability", allowUtf8LabelNamesCapabilityName)
126+
} else {
127+
capabilities.AllowUtf8LabelNames = true
128+
}
104129
}
105130
default:
106-
level.Debug(util.Logger).Log(
131+
level.Debug(logger).Log(
107132
"msg", "unknown capability parsed from Accept header",
108133
"acceptHeaderKey", k,
109134
"acceptHeaderValue", v)

0 commit comments

Comments
 (0)