Skip to content

HttpWebRequest.GetRequestStream returns new stream instance on every invocation #41403

Closed
@dallmair

Description

@dallmair

Description

Some third-party code we're depending on does this:

var request = WebRequest.CreateHttp(url);
request.Method = "POST";

// Problem: Calling request.GetRequestStream() twice returns same stream object in .NET Framework,
// but different objects in .NET Core 3.1.
using (var writer = new StreamWriter(request.GetRequestStream()))
    writer.Write("Hello, world!");
request.GetRequestStream().Close();

request.GetResponse();

Of course, there are things to improve here; Unfortunately, this code is not under our control, so we have no way to change it.

Anyway, the code works fine on .NET Framework 4.7.2 as the GetRequestStream method returns the same System.Net.ConnectStream object on both calls. In contrast, it fails on .NET Core 3.1.400, because the method returns a new instance on every call, which means that the above code just sends empty POST requests.

Expectation: GetRequestStream should return the same object on every invocation.

Configuration

  • .NET Core 3.1.400
  • Windows 10.0.19041.388
  • x64

Regression?

Yes. As outlined above, this works fine on .NET Framework 4.7.2, but does not work on .NET Core 3.1.

Other information

Here's the relevant code section, which shows that a new RequestStream is created on every invocation:

public override Stream GetRequestStream()
{
return InternalGetRequestStream().Result;
}
private Task<Stream> InternalGetRequestStream()
{
CheckAbort();
// Match Desktop behavior: prevent someone from getting a request stream
// if the protocol verb/method doesn't support it. Note that this is not
// entirely compliant RFC2616 for the aforementioned compatibility reasons.
if (string.Equals(HttpMethod.Get.Method, _originVerb, StringComparison.OrdinalIgnoreCase) ||
string.Equals(HttpMethod.Head.Method, _originVerb, StringComparison.OrdinalIgnoreCase) ||
string.Equals("CONNECT", _originVerb, StringComparison.OrdinalIgnoreCase))
{
throw new ProtocolViolationException(SR.net_nouploadonget);
}
if (RequestSubmitted)
{
throw new InvalidOperationException(SR.net_reqsubmitted);
}
_requestStream = new RequestStream();
return Task.FromResult((Stream)_requestStream);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Netbuggood first issueIssue should be easy to implement, good for first-time contributorshelp wanted[up-for-grabs] Good issue for external contributorsin-prThere is an active PR which will close this issue when it is merged

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions