Skip to content
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

Fix Hang on when GetRequestStreamAsync #113409

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

liveans
Copy link
Member

@liveans liveans commented Mar 12, 2025

Fixes #113398.

This is a regression, we should probably back port this to .NET 9.0

@Copilot Copilot bot review requested due to automatic review settings March 12, 2025 05:45
@liveans liveans requested a review from a team March 12, 2025 05:46
Copy link
Contributor

@Copilot Copilot AI left a 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 addresses a regression that caused GetRequestStreamAsync to hang by introducing timeout logic in the internal request stream retrieval and propagating underlying exceptions. Key changes include:

  • Wrapping the stream retrieval in a Task.WhenAny and WaitAsync-based timeout mechanism.
  • Propagating exceptions when the underlying send request task fails.
  • Adding a new unit test for requests with buffering disabled and an invalid host to verify correct exception handling.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs Modified InternalGetRequestStream to use timeout logic and propagate exceptions from SendRequest.
src/libraries/System.Net.Requests/tests/HttpWebRequestTest.cs Introduced a new test to ensure that an invalid host with buffering disabled causes the expected exception.

Task<Stream> getStreamTask = getStreamTcs.Task;
try
{
Task result = await Task.WhenAny((Task)getStreamTask, (Task)_sendRequestTask).WaitAsync(TimeSpan.FromMilliseconds(Timeout)).ConfigureAwait(false);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one thing that I've noticed is that, when user is using async path already they should implement their own timeout mechanism according to the doc: HttpWebRequest.Timeout - Remarks

Not sure, if we should stick to that behavior and limit propagating of Timeout here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WaitAsync will not cancel / stop the underlying tasks. What happens with them? I think this will at minimum generate unobserved exceptions.
It would be better to pass the timeout to the tasks themselves via cancellation token and them catch the exception and remap to TimeoutException if necessary. (we do this a lot around HttpClient).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Hang with HttpWebRequest.AllowWriteStreamBuffering = false in .NET 9
2 participants