Artifact 8b3806e7a2a42604444f5fbcbf33b413399e8136fa08918b3324db54ee5dde66:
- File
leaf/agent/internal/natshdr/carrier.go
— part of check-in
[b53032d01f]
at
2026-04-24 16:02:07
on branch trunk
— notify: extract shared natshdr.Carrier to kill duplicate header-carrier
Two copies of natsHeaderCarrier existed (leaf/agent/nats.go and leaf/agent/notify/pubsub.go), both carrying the same latent case-sensitive Get bug that was fixed in Task 6. Extract the type to leaf/agent/internal/natshdr so the next bug can be fixed once.
While consolidating, drop the 4-tier fallback in Get in favor of a single EqualFold scan. Header maps are tiny (typically 3 entries) and tiers 1-3 were subsumed by tier 4 anyway. The new implementation is demonstrably correct and easier to read. (user: [email protected], size: 1584) [annotate] [blame] [check-ins using] [more...]
// Package natshdr provides a propagation.TextMapCarrier adapter for // nats.Header so OpenTelemetry propagators can read/write W3C trace // context directly on a NATS message's headers. // // NATS preserves header case on the send side but delivers headers // lower-cased on the receive side, so Get is case-insensitive; otherwise // subscribers would miss the injected "traceparent" because the wire // delivers it as "traceparent" while http.Header.Get canonicalizes the // lookup key to "Traceparent". package natshdr import ( "net/http" "strings" "github.com/nats-io/nats.go" "go.opentelemetry.io/otel/propagation" ) // Carrier adapts nats.Header to propagation.TextMapCarrier. type Carrier nats.Header // Get returns the first value for the header keyed by any case-variant // of key, or "" if none is set. Header maps are tiny (typically ≤3 // entries), so an EqualFold scan is simple and demonstrably correct. func (c Carrier) Get(key string) string { for k, v := range c { if len(v) > 0 && strings.EqualFold(k, key) { return v[0] } } return "" } // Set writes the canonical form so both publishers and subscribers // converge on the same key regardless of direction. func (c Carrier) Set(key, value string) { http.Header(c).Set(key, value) } // Keys returns the header names currently present on the carrier. func (c Carrier) Keys() []string { keys := make([]string, 0, len(c)) for k := range c { keys = append(keys, k) } return keys } // Verify Carrier implements TextMapCarrier at compile time. var _ propagation.TextMapCarrier = Carrier(nil)