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
HttpWebRequest.GetRequestStreamAsync doesn't open the connection to the server - we always buffer the content #18632
Comments
This is actually the same design as .NET Framework (Desktop). The only difference is that in Desktop, there is a property on HttpWebRequest (.AllowWriteStreamBuffering) which can toggle this behavior. Eventually, when we add all the API surface back, we will have to solve it then. The difficulty at this point, though, is that the HttpWebRequest API surface is built on top of HttpClient and it has a different data model for handling when data actually starts going to a server. |
I am removing the 'bug' label because it isn't a bug, per se. It is the proper behavior if the .AllowWriteStreamBuffering option is TRUE, which it always is right now in the current implementation. |
Ok. Thanks, David. |
Will you actually come around to fixing these sorts of things though considering how it could break applications? I'm guessing I'm saying why not fix it now? |
We should evaluate it for 2.0 based on usage data of |
@weshaggard can you please help us evaluate usage of |
Usage data is on apisof.net (thanks @stephentoub for pointing it out): https://apisof.net/catalog/System.Net.HttpWebRequest.AllowWriteStreamBuffering
That seems above the threshold we went after in .NET Standard 2.0 - @danmosemsft, @weshaggard what do you think? |
@karelz I'm not sure I understand the question. AllowWriteStreamBuffering is part of .NET Standard 2.0 so the API has been added back, is the question whether or not we should fix the implementation to do the buffering correctly again? If so I would yes we probably should in order to be compatible as that flag is set in the default set of flags we use (https://github.com/dotnet/corefx/blob/ec2a6190efa743ab600317f44d757433e44e859b/src/System.Net.Requests/src/System/Net/HttpWebRequest.cs#L84). |
@weshaggard the buffering is hidden under |
I appologize (@weshaggard corrected me) - the flag is set in Default on .NET Core. |
The default value is TRUE (which works). And yes, "buffering" means that the data is held in a MemoryStream. The dev gets the request stream and writes to it. But those writes are not sent on the wire but fill up a MemoryStream. Later, when the request is sent to the HTTP server, the MemoryStream is replayed (usually by grabbing the stored buffer) and sent on the wire. The Desktop and .NET Core both use a MemoryStream for the buffering. |
Thanks! I think our usage analysis above is valid. Assuming people will (mostly) use the property only to set it to non-default value, which is |
Per the code at https://github.com/dotnet/corefx/blob/master/src/System.Net.Requests/src/System/Net/HttpWebRequest.cs#L137 |
Actually, I should not have linked these issues. The new issue you entered dotnet/corefx#18668 has nothing to do with this issue. Let's continue discussion on that issue instead. |
Triage discussion: While important, this is P2 at this moment and won't make it into 2.0, unless we get additional feedback from customers. |
Do i get this right, even when I set AllowWriteStreamBuffering to false, in .net core, when i call GetRequestStream, the stream always gets buffered in a MemoryStream till the stream is closed? So we have a memory issue when uploading big files to an endpoint? |
Yes. We recommend that you use HttpClient APIs and not the legacy HttpWebRequest APIs. HttpClient has APIs that can support the similar scenario where uploading the request body from a large source (i.e. filestream) will not be completely buffered into memory first. Instead, it will read directly from the filestream and write directly to the network. |
Triage: Related to @alnikola's effort in HttpWebRequest. This may be non-trivial. |
…Request by HttpClient. HttpWebRequest is buffering all Post uploads in .Net Core which initial caused migration from .Net Core to .Net framework. Solved with HttpClient. https://stackoverflow.com/questions/61383052/httpwebrequest-getrequeststream-returned-stream-does-not-send-data-immediately-i dotnet/runtime#18632
Fixed by #95001 |
The corefx implementation of HttpWebRequest.GetRequestStreamAsync effectively just returns an in-memory stream. The connection to the server isn't made and the data isn't uploaded until Stream.Dispose is called on the that Stream. This is problematic for several reasons, including that the actual asynchronous operation ends up happening in the synchronous Dispose call on the stream, and deadlocks can easily happen if code assumes that the server will respond once the supplied data has been written (but before Dispose is called).
The text was updated successfully, but these errors were encountered: