diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e1c838e32e..9e1a6a7014e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Fixes the instrument kind for noop async instruments. (#2461) - Change the `otlpmetric.Client` interface's `UploadMetrics` method to accept a single `ResourceMetrics` instead of a slice of them. (#2491) - Specify explicit buckets in Prometheus example. (#2493) +- W3C baggage will now decode urlescaped values. (#2529) ## [1.3.0] - 2021-12-10 diff --git a/baggage/baggage.go b/baggage/baggage.go index 3427c51b477..d52a298ed1b 100644 --- a/baggage/baggage.go +++ b/baggage/baggage.go @@ -269,7 +269,12 @@ func parseMember(member string) (Member, error) { } // "Leading and trailing whitespaces are allowed but MUST be trimmed // when converting the header into a data structure." - key, value = strings.TrimSpace(kv[0]), strings.TrimSpace(kv[1]) + key = strings.TrimSpace(kv[0]) + var err error + value, err = url.QueryUnescape(strings.TrimSpace(kv[1])) + if err != nil { + return Member{}, fmt.Errorf("%w: %q", err, value) + } if !keyRe.MatchString(key) { return Member{}, fmt.Errorf("%w: %q", errInvalidKey, key) } diff --git a/baggage/baggage_test.go b/baggage/baggage_test.go index 0635c823e9e..88c820319b5 100644 --- a/baggage/baggage_test.go +++ b/baggage/baggage_test.go @@ -339,6 +339,13 @@ func TestBaggageParse(t *testing.T) { "foo": {Value: "2"}, }, }, + { + name: "url encoded value", + in: "key1=val%252", + want: baggage.List{ + "key1": {Value: "val%2"}, + }, + }, { name: "invalid member: empty", in: "foo=,,bar=", diff --git a/propagation/baggage_test.go b/propagation/baggage_test.go index 299e009e3cf..e98230a94ea 100644 --- a/propagation/baggage_test.go +++ b/propagation/baggage_test.go @@ -118,6 +118,13 @@ func TestExtractValidBaggageFromHTTPReq(t *testing.T) { {Key: "key2", Value: "val2"}, }, }, + { + name: "valid header with url encoded string", + header: "key1=val%252", + want: members{ + {Key: "key1", Value: "val%2"}, + }, + }, } for _, tt := range tests {