-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Fix baggage encoding by using Uri.EscapeDataString instead of WebUtility.UrlEncode #122951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ity.UrlEncode Replace WebUtility.UrlEncode with Uri.EscapeDataString in DistributedContextPropagator.cs and WebUtility.UrlDecode with Uri.UnescapeDataString in LegacyPropagator.cs to fix the issue where baggage values containing special characters (like quoted parentheses) would cause FormatException when parsed by NameValueHeaderValue. Fixes #27106 Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/LegacyPropagator.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a bug where baggage values containing spaces, parentheses, or quotes cause HTTP requests to fail with FormatException. The root cause is that WebUtility.UrlEncode encodes spaces as + instead of %20, which breaks parsing in NameValueHeaderValue.
Key Changes:
- Replace
WebUtility.UrlEncodewithUri.EscapeDataStringfor RFC 3986 compliant encoding (spaces as%20) - Replace
WebUtility.UrlDecodewithUri.UnescapeDataStringfor proper decoding - Add comprehensive test coverage for baggage values with special characters
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DistributedContextPropagator.cs | Replace WebUtility.UrlEncode with Uri.EscapeDataString in baggage injection logic; add null coalescing for value parameter; remove unused System.Net using |
| src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/LegacyPropagator.cs | Replace WebUtility.UrlDecode with Uri.UnescapeDataString in baggage extraction logic; remove unused System.Net using |
| src/libraries/System.Diagnostics.DiagnosticSource/tests/PropagatorTests.cs | Update test helper methods to use Uri.EscapeDataString/UnescapeDataString; add TestBaggageWithSpecialCharacters theory with 7 test cases covering quoted strings, spaces, plus signs, equals, ampersands, percent signs, and Unicode; remove unused System.Net using |
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/LegacyPropagator.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Head branch was pushed to by a user without write access
|
Is there a strong reason to address this now for the legacy propagator, given that the W3C propagator is already exposed, fully spec-compliant, and now the default? open-telemetry/opentelemetry-dotnet#5687 CC @noahfalk |
@tarekgh, are you suggesting closing this PR (and the corresponding issue) outright, or only reverting the changes to that one file but keeping the others? |
I was suggesting closing the PR. Using Uri.EscapeDataString instead WebUtility.UrlEncode may help but have some other side effect, according to open-telemetry/opentelemetry-dotnet#5687. Users should use W3C propagator now, which should work nicely without any problem. |
Description
WebUtility.UrlEncodeencodes spaces as+instead of%20, causingNameValueHeaderValueto throwFormatExceptionwhen parsing baggage values containing parentheses or quotes.Changes:
WebUtility.UrlEncode→Uri.EscapeDataStringinDistributedContextPropagator.InjectBaggage()WebUtility.UrlDecode→Uri.UnescapeDataStringinLegacyPropagator.TryExtractBaggage()AsSpaninstead ofSubstringforUri.UnescapeDataStringon .NET where the span overload is availableCustomer Impact
Any baggage value with parentheses, quotes, or spaces causes HTTP requests to fail with
FormatException.Regression
No. This has been broken since the original URL encoding was added.
Testing
TestBaggageWithSpecialCharacterstheory covering: quoted strings with parentheses, spaces, plus signs, equals signs, ampersands, percent signs, and UnicodeRisk
Low.
Uri.EscapeDataStringis RFC 3986 compliant andUri.UnescapeDataStringcorrectly decodes both%20and+as spaces for backwards compatibility.Package authoring no longer needed in .NET 9
IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.
Original prompt
This section details on the original issue you should resolve
<issue_title>System.Net.Http.DiagnosticsHandler.SendAsync throws if Activity.Current.Baggage contains values that can't be parsed by NameValueHeaderValue after UrlEncoding</issue_title>
<issue_description>### Description
This old issue #27106, was claimed to be fixed... but it is not fixed. In reality, the UrlEncoding used to "fix" the above issue breaks my workaround of quoting all the values.
This can be reproduced with:
This code throws the following exception
Configuration
.NET Core 3.1, on windows 10
This isn't specific to any configuration
Regression?
This was a bug in older versions of .net core, it is still broken.
Other information
The bug is here: https://source.dot.net/#System.Net.Http/System/Net/Http/DiagnosticsHandler.cs,284
This should 100% not be using something that explodes when strange values are passed. This means that anywhere in the code of any program, if something completely benign is added to Activity.Current.Baggage, any HttpClient calls will fail.
If using NameValueHeaderValue is important for some reason.... at least it shouldn't crash the entire asp.net request because of a single baggage thingy.</issue_description>
<agent_instructions>Implement MihaZupan's recommended fix and ensure it's tested well. </agent_instructions>
Comments on the Issue (you are @copilot in this section)
@ Tagging subscribers to this area: @dotnet/ncl Notify danmosemsft if you want to be subscribed. @karelz @lmolkova can you please take a look at this one? @MihaZupan We should really be using `Uri.EscapeDataString` instead of `WebUtility.UrlEncode` here. @MihaZupan Fix for this issue would be to use `Uri.EscapeDataString` instead of `WebUtility.UrlEncode` here: https://github.com/dotnet/runtime/blob/5399ee59e55a75a850011908a0f96d7abb8a91c7/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DistributedContextPropagator.cs#L120And
Uri.UnescapeDataStringinstead ofWebUtility.UrlDecodehere:runtime/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/LegacyPropagator.cs
Lines 172 to 173 in 5399ee5
Marking as up-for-grabs since it should be as simple as replacing the two calls and writing a test.
Moving to diagnostics area since all the changes belong in
DistributedContextPropagatorlogic now.</comment_new><comment_new>@
Tagging subscribers to this area: @tommcdon, @krwq
See info in area-owners.md if you want to be subscribed.
Issue Details
Description
This old issue #27106, was claimed to be fixed... but it is not fixed. In reality, the UrlEncoding used to "fix" the above issue breaks my workaround of quoting all the values.
This can be reproduced with:
This code throws the following exception
Configuration
.NET Core 3.1, on windows 10
This isn't specific to any configuration
Regression?
This was a bug in older versions of .net core, it is still broken.
Other information
The bug is here: https://source.dot.net/#System.Net.Http/System/Net/Http/DiagnosticsHandler.cs,284
This should 100% not be using something that explodes when strange values are passed. This means that anywhere in the code of any program, if something completely benign is added to Activity.Current.Baggage, any HttpClient calls will fail.
If using NameValueHeaderValue is important for some reason.... at least it shouldn't crash the entire asp.net request because of a single baggage thingy.
...💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.