dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.94k stars 4.64k forks source link

Httpclient throwing Response ended Prematurely #106322

Open aneeketMangalAtMS opened 1 month ago

aneeketMangalAtMS commented 1 month ago

Description

We are trying to call a GET endpoint inside our service code (NetCore 8). And we are getting the following exception

System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.Net.Http.HttpIOException: The response ended prematurely. (ResponseEnded)
   at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)

We tried making the same request with Postman, Insomnia and curl and it works pretty fine there. But surprisingly does not work in NetCore runtime. We call several other GET APIs via httpClient in our c# code and they all work fine.

Setup NetCore version : 8 Docker, WSL

Things I have tried:

  1. Disabling the SSL validation
  2. Increasing the timeout

Reproduction Steps

NA

Expected behavior

The call should have succeeded and shouldn't have thrown this exception.

Actual behavior

Throwing an exception

System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.Net.Http.HttpIOException: The response ended prematurely. (ResponseEnded)
   at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)

Regression?

Used to work in NET Framework.

Known Workarounds

No response

Configuration

NetCore 8.0.3 Docker, Linux

Other information

One observation

  1. If we keep the fiddler open and disable the SSL validation, the request succeeds and do not throw an exception
rzikm commented 1 month ago

Is this against some publicly reachable server? This is going to be difficult to diagnose without a repro.

If this reproduces without SSL, can you collect wireshark packet captures and share them?

aneeketMangalAtMS commented 4 weeks ago

wireSharkCapture2.zip

Added the wireshark trace

aneeketMangalAtMS commented 4 weeks ago

Confirmed with the logs from downstream API, that the request is indeed reaching the servers but somehow HttpClient is throwing an exception.

wfurt commented 4 weeks ago

what server are you connecting too @aneeketMangalAtMS ? There is way too much noise in the capture. (you can capture relevant exchange using filer host my server.com.

And is this large PUT or POST by any chance? If so, try to add 100Continue .

aneeketMangalAtMS commented 4 weeks ago

My bad, kindly use this display filter ip.dst == 52.102.22.25

It is a get request @wfurt

wfurt commented 4 weeks ago

It is server who closes the connection. Since it is TLS it is hard to know what is exactly happening. I think next step would be to peek inside of the TLS. Since this is WSL e.g. Linux https://github.com/dotnet/runtime/issues/37915 should work - wither stock 9.0 or you would need to build 8.0 debug build if you cannot upgrade. Alternatively, the post has reference to PcapStream and that should work on either version.