diff --git a/CHANGELOG.md b/CHANGELOG.md index 961faa2de0..87e0d7eb4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ Increment the: ## [Unreleased] +* [API] `Baggage::ToHeader` now percent-encodes spaces as `%20` instead of + `+`, as required by the W3C Baggage specification. Decoding is unchanged. + [#4765](https://github.com/open-telemetry/opentelemetry-cpp/pull/4765) * [SDK] Skip completely empty span links (invalid span context, no attributes and no trace state), so they no longer count against `link_count_limit` [#4772](https://github.com/open-telemetry/opentelemetry-cpp/pull/4772) diff --git a/api/include/opentelemetry/baggage/baggage.h b/api/include/opentelemetry/baggage/baggage.h index 8f71262d0f..85c887dcf7 100644 --- a/api/include/opentelemetry/baggage/baggage.h +++ b/api/include/opentelemetry/baggage/baggage.h @@ -320,10 +320,6 @@ class OPENTELEMETRY_EXPORT Baggage { ret.push_back(c); } - else if (c == ' ') - { - ret.push_back('+'); - } else { ret.push_back('%'); diff --git a/api/test/baggage/baggage_test.cc b/api/test/baggage/baggage_test.cc index 3d2110cfa7..57352acf11 100644 --- a/api/test/baggage/baggage_test.cc +++ b/api/test/baggage/baggage_test.cc @@ -201,7 +201,8 @@ TEST(BaggageTest, ValidateExtractHeader) {"v1", "v2; metadata"}}, // key and value are trimmed {"1a-2f%40foo=bar%251,a%2A%2Ffoo-_%2Fbar=bar+4", {"1a-2f@foo", "a*/foo-_/bar"}, - {"bar%1", "bar 4"}}, // decoding is done properly + {"bar%1", "bar 4"}}, // decoding is done properly, '+' still decodes as space + {"k=hello%20world", {"k"}, {"hello world"}}, // %20 decodes as space {"field=foo:bar", {"field"}, {"foo:bar"}}, // colon in value {"mixed=a/b:c?d=e", {"mixed"}, {"a/b:c?d=e"}}, // mixed special characters {"k1=v1,invalidmember,k2=v2", {"k1", "k2"}, {"v1", "v2"}}, // invalid member is skipped @@ -256,10 +257,10 @@ TEST(BaggageTest, ValidateInjectHeader) {{"k3", "k2", "k1"}, {"", "v2", "v1"}, "k1=v1,k2=v2,k3="}, // empty value {{"1a-2f@foo", "a*/foo-_/bar"}, {"bar%1", "bar 4"}, - "a%2A%2Ffoo-_%2Fbar=bar+4,1a-2f%40foo=bar%251"}, // encoding is done properly + "a%2A%2Ffoo-_%2Fbar=bar%204,1a-2f%40foo=bar%251"}, // encoding is done properly {{"foo 1"}, {"bar 1; metadata ; flag=encoded%20value"}, - "foo+1=bar+1; metadata ; flag=encoded%20value"}}; + "foo%201=bar%201; metadata ; flag=encoded%20value"}}; for (auto &testcase : testcases) { @@ -272,6 +273,17 @@ TEST(BaggageTest, ValidateInjectHeader) } } +TEST(BaggageTest, SpaceIsPercentEncoded) +{ + auto baggage = Baggage().Set("k", "hello world"); + auto header = baggage->ToHeader(); + EXPECT_EQ(header, "k=hello%20world"); + + std::string value; + EXPECT_TRUE(Baggage::FromHeader(header)->GetValue("k", value)); + EXPECT_EQ(value, "hello world"); +} + TEST(BaggageTest, BaggageGet) { auto header = header_with_custom_entries(Baggage::kMaxKeyValuePairs);