Skip to content

Commit

Permalink
Change metadata lookup to be case insensitive (#5646)
Browse files Browse the repository at this point in the history
* Change metadata lookup to be case insensitive

Before this change, users would make references to headers such as "authorization" and "X-CloudFront-Viewer-Latitude", which would potentially fail, as they would be stored in the context as "X-Cloudfront-Viewer-Latitude" or "Authorization".

This PR changes this behavior, to attempt a case insensitive lookup to the backing map in case the key wasn't found under the requested casing. Under the assumption that the lookup key specified by users won't change, on a subsequent lookup, we proactively copy the value to the looked up key, to make the next lookup faster.

Fixes #5610
Fixes open-telemetry/opentelemetry-collector-contrib#8994

Signed-off-by: Juraci Paixão Kröhling <[email protected]>

* Add changelog entry

Signed-off-by: Juraci Paixão Kröhling <[email protected]>
  • Loading branch information
jpkrohling authored Jul 13, 2022
1 parent 1b32ae0 commit 6417a3a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### 💡 Enhancements 💡

- Add `linux-ppc64le` architecture to cross build tests in CI
- `client`: perform case insensitive lookups in case the requested metadata value isn't found (#5646)

### 🧰 Bug fixes 🧰

Expand Down
15 changes: 14 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ package client // import "go.opentelemetry.io/collector/client"
import (
"context"
"net"
"strings"
)

type ctxKey struct{}
Expand Down Expand Up @@ -160,7 +161,19 @@ func NewMetadata(md map[string][]string) Metadata {
func (m Metadata) Get(key string) []string {
vals := m.data[key]
if len(vals) == 0 {
return nil
// we didn't find the key, but perhaps it just has different cases?
for k, v := range m.data {
if strings.EqualFold(key, k) {
vals = v
// we optimize for the next lookup
m.data[key] = v
}
}

// if it's still not found, it's really not here
if len(vals) == 0 {
return nil
}
}

ret := make([]string, len(vals))
Expand Down
1 change: 1 addition & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func TestMetadata(t *testing.T) {
source := map[string][]string{"test-key": {"test-val"}}
md := NewMetadata(source)
assert.Equal(t, []string{"test-val"}, md.Get("test-key"))
assert.Equal(t, []string{"test-val"}, md.Get("test-KEY")) // case insensitive lookup

// test if copy. In regular use, source cannot change
val := md.Get("test-key")
Expand Down

0 comments on commit 6417a3a

Please sign in to comment.