-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix cancellation token handling in LimitArrayPoolWriteStream.WriteAsync methods #121836
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
base: main
Are you sure you want to change the base?
Conversation
… methods Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
|
@copilot please add a test |
Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
Added regression test |
src/libraries/System.Net.Http/tests/FunctionalTests/HttpContentTest.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
|
Tagging subscribers to this area: @dotnet/ncl |
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 regression in .NET 10 where HttpContent.LoadIntoBufferAsync with a pre-canceled token no longer throws TaskCanceledException, breaking behavior from .NET 9. The fix adds cancellation token checks to both WriteAsync method overloads in LimitArrayPoolWriteStream, restoring the expected cancellation semantics.
- Added cancellation token checks to
LimitArrayPoolWriteStream.WriteAsyncmethods to properly handle pre-canceled tokens - Added regression test to verify the fix works with custom handlers returning pre-buffered content
- Changed visibility of
CustomResponseHandlerfromprivatetointernalto allow test reuse
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs | Added cancellation token checks in both WriteAsync overloads to return canceled tasks when token is already canceled |
| src/libraries/System.Net.Http/tests/FunctionalTests/HttpContentTest.cs | Added regression test validating that GetAsync with custom handler and pre-canceled token throws TaskCanceledException |
| src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs | Changed CustomResponseHandler visibility from private to internal to enable reuse in HttpContentTest |
src/libraries/System.Net.Http/tests/FunctionalTests/HttpContentTest.cs
Outdated
Show resolved
Hide resolved
…tTest.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Fix breaking change in HTTP response content reading with pre-canceled tokens
Issue: In .NET 10,
HttpContent.LoadIntoBufferAsyncwith an already-canceled token no longer throwsTaskCanceledException, breaking behavior from .NET 9.Root cause:
LimitArrayPoolWriteStream.WriteAsyncmethods ignore theCancellationTokenparameter and always return completed tasks.Solution: Added cancellation token checks to both
WriteAsyncmethods inLimitArrayPoolWriteStream:Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)Both methods now check
cancellationToken.IsCancellationRequestedand return a canceled task if needed, restoring .NET 9 behavior.Added regression test
GetAsync_WithCustomHandlerReturningStringContent_PreCanceledToken_ThrowsTaskCanceledExceptionthat specifically validates the fix using the exact scenario from the issue report.Customer Impact
Code relying on cancellation during HTTP content buffering silently succeeds instead of throwing
TaskCanceledException, breaking cancellation workflows and potentially causing resource leaks or unexpected behavior.Example impact:
Regression
Yes. Introduced by PR #109642 which replaced
LimitMemoryStreamwithLimitArrayPoolWriteStream. The old implementation inherited cancellation handling fromMemoryStream.WriteAsync; the new one does not.Testing
GetAsync_WithCustomHandlerReturningStringContent_PreCanceledToken_ThrowsTaskCanceledExceptionthat reproduces the exact issue scenarioLoadIntoBufferAsync_Unbuffered_CanBeCanceled_AlreadyCanceledCtspassesRisk
Low. Minimal change (10 lines) that only affects already-canceled tokens at write time. All writes are synchronous operations in
LimitArrayPoolWriteStream, so the check is purely for API correctness. No performance impact on non-canceled paths.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
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.