[Foundation] Add KeepHeadersAfterDecompression app context switch to NSUrlSessionHandler#24957
Conversation
…NSUrlSessionHandler Add an opt-out switch 'Foundation.NSUrlSessionHandler.KeepHeadersAfterDecompression' that, when enabled, preserves the original Content-Encoding and Content-Length headers on auto-decompressed responses instead of removing them. This allows apps that depend on the original headers to restore the previous behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds an app-context switch to allow opting out of NSUrlSessionHandler’s header-stripping behavior after automatic response decompression, and introduces a regression test to validate the opt-out.
Changes:
- Added
Foundation.NSUrlSessionHandler.KeepHeadersAfterDecompressionAppContext switch handling inNSUrlSessionHandlerto preserveContent-Encoding/Content-Lengthafter auto-decompression. - Added a new monotouch test to validate preserved headers when the switch is enabled.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/Foundation/NSUrlSessionHandler.cs | Reads an AppContext switch to conditionally keep Content-Encoding/Content-Length headers on auto-decompressed responses. |
| tests/monotouch-test/System.Net.Http/NSUrlSessionHandlerTest.cs | Adds a test that enables the switch and asserts the headers are preserved for a gzip response. |
| AppContext.SetSwitch ("Foundation.NSUrlSessionHandler.KeepHeadersAfterDecompression", true); | ||
| try { | ||
| var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => { | ||
| using var handler = new NSUrlSessionHandler (); | ||
| using var client = new HttpClient (handler); | ||
| using var request = new HttpRequestMessage (HttpMethod.Get, $"{NetworkResources.Httpbin.Url}/gzip"); | ||
| request.Headers.TryAddWithoutValidation ("Accept-Encoding", "gzip"); | ||
| var response = await client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead); | ||
|
|
||
| if (!response.IsSuccessStatusCode) { | ||
| Assert.Inconclusive ($"Request failed with status {response.StatusCode}"); | ||
| return; | ||
| } | ||
|
|
||
| hasContentEncoding = response.Content.Headers.ContentEncoding.Count > 0; | ||
| hasContentLength = response.Content.Headers.ContentLength is not null; | ||
| body = await response.Content.ReadAsStringAsync (); | ||
| }, out var ex); | ||
|
|
||
| if (!done) { | ||
| TestRuntime.IgnoreInCI ("Transient network failure - ignore in CI"); | ||
| Assert.Inconclusive ("Request timed out."); | ||
| } | ||
| TestRuntime.IgnoreInCIIfBadNetwork (ex); | ||
| Assert.IsNull (ex, $"Exception: {ex}"); | ||
| Assert.IsTrue (hasContentEncoding, "Content-Encoding header should be preserved when KeepHeadersAfterDecompression is enabled"); | ||
| Assert.IsTrue (hasContentLength, "Content-Length header should be preserved when KeepHeadersAfterDecompression is enabled"); | ||
| Assert.IsTrue (body.Contains ("\"gzipped\"", StringComparison.OrdinalIgnoreCase), "Response body should contain decompressed gzip data"); | ||
| } finally { | ||
| AppContext.SetSwitch ("Foundation.NSUrlSessionHandler.KeepHeadersAfterDecompression", false); | ||
| } |
There was a problem hiding this comment.
This test mutates a process-wide AppContext switch and then unconditionally sets it to false in the finally block. If the switch was already set (e.g., by the test harness or another test), this will clobber the previous value. Capture the previous switch state/value (via AppContext.TryGetSwitch) before setting it, and restore that value in finally (and consider clearing the switch if it was not previously set).
✅ [CI Build #c8fe287] Build passed (Build packages) ✅Pipeline on Agent |
✅ [PR Build #c8fe287] Build passed (Detect API changes) ✅Pipeline on Agent |
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
✅ [CI Build #c8fe287] Build passed (Build macOS tests) ✅Pipeline on Agent |
This comment has been minimized.
This comment has been minimized.
🚀 [CI Build #c8fe287] Test results 🚀Test results✅ All tests passed on VSTS: test results. 🎉 All 156 tests passed 🎉 Tests counts✅ cecil: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download Pipeline on Agent |
Add an opt-out switch 'Foundation.NSUrlSessionHandler.KeepHeadersAfterDecompression'
that, when enabled, preserves the original Content-Encoding and Content-Length headers
on auto-decompressed responses instead of removing them.
This allows apps that depend on the original headers to restore the previous behavior.