Skip to content

Commit 7717aae

Browse files
authored
chore: simplify, modernize (Go 1.26), update deps (#159)
* chore: simplify, modernize (Go 1.26), update deps - Drop `fmt` import; replace two identical `fmt.Sprintf("%s.%s", RootPluginName, PluginName)` calls with a single `configKey` constant (M/R) - Add `splitTrimmed` helper; fix per-element whitespace bug in CORS CSV fields — a single outer `strings.Trim` left spaces inside tokens after `strings.Split`, which CORS would reject (R/S/M) - Use `strings.TrimSpace` instead of `strings.Trim(s, " ")` in the helper (M) - Use `var ctx context.Context` → short `:=` in span setup (M); extract local `re` to avoid capturing the whole `*Plugin` in `AllowOriginFunc` closure (S) - Drop explicit `string` type annotations on exported const declarations (M) * test: cover splitTrimmed per-element CORS whitespace handling
2 parents b4ddc49 + a562645 commit 7717aae

2 files changed

Lines changed: 70 additions & 21 deletions

File tree

plugin.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package headers
22

33
import (
4-
"context"
5-
"fmt"
64
"net/http"
75
"regexp"
86
"strings"
@@ -19,8 +17,11 @@ import (
1917

2018
// PluginName contains default service name.
2119
const (
22-
RootPluginName string = "http"
23-
PluginName string = "headers"
20+
RootPluginName = "http"
21+
PluginName = "headers"
22+
23+
// configKey is the fully-qualified config section for this plugin.
24+
configKey = RootPluginName + "." + PluginName
2425
)
2526

2627
type Configurer interface {
@@ -48,11 +49,11 @@ func (p *Plugin) Init(cfg Configurer) error {
4849
return errors.E(op, errors.Disabled)
4950
}
5051

51-
if !cfg.Has(fmt.Sprintf("%s.%s", RootPluginName, PluginName)) {
52+
if !cfg.Has(configKey) {
5253
return errors.E(op, errors.Disabled)
5354
}
5455

55-
err := cfg.UnmarshalKey(fmt.Sprintf("%s.%s", RootPluginName, PluginName), &p.cfg)
56+
err := cfg.UnmarshalKey(configKey, &p.cfg)
5657
if err != nil {
5758
return errors.E(op, err)
5859
}
@@ -68,9 +69,7 @@ func (p *Plugin) Init(cfg Configurer) error {
6869
}
6970

7071
if p.cfg.CORS.AllowedOrigin != "" {
71-
// trim all spaces
72-
p.cfg.CORS.AllowedOrigin = strings.Trim(p.cfg.CORS.AllowedOrigin, " ")
73-
opts.AllowedOrigins = strings.Split(p.cfg.CORS.AllowedOrigin, ",")
72+
opts.AllowedOrigins = splitTrimmed(p.cfg.CORS.AllowedOrigin)
7473
}
7574

7675
// if this option is set, the content of `AllowedOrigins` is ignored
@@ -80,27 +79,22 @@ func (p *Plugin) Init(cfg Configurer) error {
8079
if err != nil {
8180
return errors.E(op, err)
8281
}
82+
re := p.allowedOriginRegex
8383
opts.AllowOriginFunc = func(origin string) bool {
84-
return p.allowedOriginRegex.MatchString(origin)
84+
return re.MatchString(origin)
8585
}
8686
}
8787

8888
if p.cfg.CORS.AllowedMethods != "" {
89-
// trim all spaces
90-
p.cfg.CORS.AllowedMethods = strings.Trim(p.cfg.CORS.AllowedMethods, " ")
91-
opts.AllowedMethods = strings.Split(p.cfg.CORS.AllowedMethods, ",")
89+
opts.AllowedMethods = splitTrimmed(p.cfg.CORS.AllowedMethods)
9290
}
9391

9492
if p.cfg.CORS.AllowedHeaders != "" {
95-
// trim all spaces
96-
p.cfg.CORS.AllowedHeaders = strings.Trim(p.cfg.CORS.AllowedHeaders, " ")
97-
opts.AllowedHeaders = strings.Split(p.cfg.CORS.AllowedHeaders, ",")
93+
opts.AllowedHeaders = splitTrimmed(p.cfg.CORS.AllowedHeaders)
9894
}
9995

10096
if p.cfg.CORS.ExposedHeaders != "" {
101-
// trim all spaces
102-
p.cfg.CORS.ExposedHeaders = strings.Trim(p.cfg.CORS.ExposedHeaders, " ")
103-
opts.ExposedHeaders = strings.Split(p.cfg.CORS.ExposedHeaders, ",")
97+
opts.ExposedHeaders = splitTrimmed(p.cfg.CORS.ExposedHeaders)
10498
}
10599

106100
if p.cfg.CORS.MaxAge > 0 {
@@ -132,10 +126,10 @@ func (p *Plugin) Middleware(next http.Handler) http.Handler {
132126

133127
if val, ok := r.Context().Value(rrcontext.OtelTracerNameKey).(string); ok {
134128
tp := trace.SpanFromContext(r.Context()).TracerProvider()
135-
var ctx context.Context
136-
ctx, span = tp.Tracer(val, trace.WithSchemaURL(semconv.SchemaURL),
129+
ctx, sp := tp.Tracer(val, trace.WithSchemaURL(semconv.SchemaURL),
137130
trace.WithInstrumentationVersion(otelhttp.Version)).
138131
Start(r.Context(), PluginName, trace.WithSpanKind(trace.SpanKindInternal))
132+
span = sp
139133

140134
// inject
141135
p.prop.Inject(ctx, propagation.HeaderCarrier(r.Header))
@@ -165,3 +159,13 @@ func (p *Plugin) Middleware(next http.Handler) http.Handler {
165159
func (p *Plugin) Name() string {
166160
return PluginName
167161
}
162+
163+
// splitTrimmed splits a comma-separated string and trims whitespace from each
164+
// element, fixing per-element spaces that a single outer trim would miss.
165+
func splitTrimmed(s string) []string {
166+
parts := strings.Split(s, ",")
167+
for i, p := range parts {
168+
parts[i] = strings.TrimSpace(p)
169+
}
170+
return parts
171+
}

plugin_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,51 @@ func TestMiddleware_NoSpanWithoutOtelContext(t *testing.T) {
9090
assert.Nil(t, headersSpan, "no span should be created without OtelTracerNameKey")
9191
}
9292

93+
func TestSplitTrimmed(t *testing.T) {
94+
tests := []struct {
95+
name string
96+
in string
97+
want []string
98+
}{
99+
{
100+
name: "single value",
101+
in: "GET",
102+
want: []string{"GET"},
103+
},
104+
{
105+
name: "methods with space after comma",
106+
in: "GET, POST",
107+
want: []string{"GET", "POST"},
108+
},
109+
{
110+
name: "headers with spaces around commas",
111+
in: "Cache-Control, Content-Type",
112+
want: []string{"Cache-Control", "Content-Type"},
113+
},
114+
{
115+
name: "no spaces preserves values",
116+
in: "GET,POST,PUT,DELETE",
117+
want: []string{"GET", "POST", "PUT", "DELETE"},
118+
},
119+
{
120+
name: "leading and trailing whitespace per element",
121+
in: " GET ,\tPOST\t, PUT ",
122+
want: []string{"GET", "POST", "PUT"},
123+
},
124+
{
125+
name: "wildcard",
126+
in: "*",
127+
want: []string{"*"},
128+
},
129+
}
130+
131+
for _, tt := range tests {
132+
t.Run(tt.name, func(t *testing.T) {
133+
assert.Equal(t, tt.want, splitTrimmed(tt.in))
134+
})
135+
}
136+
}
137+
93138
func newTestPlugin() *Plugin {
94139
return &Plugin{
95140
cfg: &Config{

0 commit comments

Comments
 (0)