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

HttpClient Response Stream hangs and doesn't respect timeout (only HttpCompletionOption.ResponseHeadersRead) #36822

Closed
prcdpr opened this issue May 21, 2020 · 21 comments
Labels
area-System.Net.Http tenet-reliability Reliability/stability related issue (stress, load problems, etc.)
Milestone

Comments

@prcdpr
Copy link

prcdpr commented May 21, 2020

Description

This is a bug that caused me to waste many hours debugging and is very hard to reproduce.

There are requirements for this bug to happen:

  • Send GET request via HTTPS to download a file from network (Content-Length is up to 4 MB, not larger)
  • Set flag HttpCompletionOption.ResponseHeadersRead
  • Set request cancelation token to 1 minute
  • Have poor internet connection
  • Copy response stream via CopyToAsync to MemoryStream

Sometimes, usually on poor internet connection it happens that Response stream is never closed even though cancelation token is set.

Therefore it causes CopyToAsync to hang forever.

I have found workaround in this article: https://www.danielcrabtree.com/blog/33/gotchas-with-httpclients-cancelpendingrequests-and-timeout-in-net

Workaround is pretty simple, you need to create another cancelation token and close response stream forcibly after timeout.

var cts = new CancellationTokenSource(60000)
cts.Token.Register(() => responseStream.Close());

Configuration

  • .NET Core 3.1
  • Windows 10 Pro x64

Regression?

Don't know.

Other information

In my company I had at least dozen user reports usually from remote workers with poor internet connection that the company's downloader app freezes and stops downloading.

Myself I have never experienced it which is probably because I have fast fiber internet at home.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Net.Http untriaged New issue has not been triaged by the area owner labels May 21, 2020
@ghost
Copy link

ghost commented May 21, 2020

Tagging subscribers to this area: @dotnet/ncl
Notify danmosemsft if you want to be subscribed.

@prcdpr prcdpr changed the title HttpClient Resopnse Stream hangs and doesn't respect timeout (only HttpCompletionOption.ResponseHeadersRead) HttpClient Response Stream hangs and doesn't respect timeout (only HttpCompletionOption.ResponseHeadersRead) May 21, 2020
@stephentoub
Copy link
Member

Set request cancelation token to 1 minute

Can you be more specific about exactly what you're doing here? Code would be helpful.

Copy response stream via CopyToAsync to MemoryStream

Are you passing the cancellation token to CopyToAsync?

@davidsh
Copy link
Contributor

davidsh commented May 21, 2020

Set flag HttpCompletionOption.ResponseHeadersRead
Set request cancelation token to 1 minute

Which cancellation token (cts.Token) is being set? Is it the one being passed to HttpClient APIs like:

HttpResponseMessage response = await client.GetAsync(uri, HttpCompletionOptions.ResponseHeadersRead, cts.Token);

That cancellation token only affects the initial call to the GetAsync() API. Once it returns, that cancellation token isn't used anymore for any further I/O on the HTTP response stream. And since you are using ResponseHeadersRead, the GetAsync() API should be returning quickly after just getting the response header.

Copy response stream via CopyToAsync to MemoryStream

Are you passing a cancellation token to the CopyToAsync() API? Can you show the C# code that you're using to call this API?

@prcdpr
Copy link
Author

prcdpr commented May 21, 2020

@stephentoub @davidsh

This is how I set timeout

using var cts = new CancellationTokenSource(timeout);
using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);

I pass cancelation token only to SendAsync, I didn't pass it to CopyToAsync.

But I would expect when underlying network socket breaks due to poor internet, the Response Stream would be automatically closed as there won't be any additional bytes to read from this socket.

@marklio marklio added the tenet-reliability Reliability/stability related issue (stress, load problems, etc.) label May 21, 2020
@prcdpr
Copy link
Author

prcdpr commented May 21, 2020

I could pass cancelation token to CopyToAsync method but consider this example.

  • I set CopyToAsync timeout to 5 minutes.
  • Internet breaks 1 minute into copying streams
  • 4 minutes my app is doing absolutely nothing, there is no underlying socket and I have to patiently wait for timeout to fire even though it's already known there won't be anything to read

@stephentoub
Copy link
Member

The read in CopyToAsync will wake up when the OS notifies it that the connection has closed. It's quite likely the OS simply hasn't recognized that the connection dropped. TCP is quite resilient.

@stephentoub
Copy link
Member

(And if you want your cancellation token to cancel all reading from the response stream, you should pass it to CopyToAsync.)

@prcdpr
Copy link
Author

prcdpr commented May 21, 2020

I had a case of my user waiting for more than 1 day in such frozen state for CopyToAsync to finish. It's quite possible what you say that that OS didn't recognize the connection drop.

In that case it wouldn't qualify as bug but to me it's still a gotcha that can be quite costly and maybe it should be documented how you should work with Response Stream when you set HttpCompletionOption.ResponseHeadersRead flag?

Especially that HttpClient user should be aware that Response Stream may become stuck and it's user responsibility to handle reading timeout once again.

@scalablecory
Copy link
Contributor

@prcdpr can you please supply some code demonstrating the issue?

@prcdpr
Copy link
Author

prcdpr commented May 22, 2020

OK so there is the repro I managed to pull off.
I have desktop computer connected via LAN cable to switch, and the switch is connected via LAN cable to router.

After around 10s after application start, I manually disconnect LAN cable between switch and router.
Then 1 minute later, I reconnect switch and router which immediately brings back internet connection and I can browse https://youtube.com and other sites.

using System;
using System.Globalization;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var httpClient = new HttpClient();

            var request = new HttpRequestMessage(HttpMethod.Get, "https://speed.hetzner.de/10GB.bin");
            var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
            Console.WriteLine($"Content-Length: {response.Content.Headers.ContentLength.Value}");
            
            
            var responseStream = await response.Content.ReadAsStreamAsync();
            var memoryStream = new MemoryStream();
            
            _ = Task.Run(async () =>
            {
                while (true)
                {
                    Console.WriteLine($"[{DateTimeOffset.Now.ToString(CultureInfo.InvariantCulture)}] Memory stream length: {memoryStream.Length}");
                    await Task.Delay(1000);
                }
            });

            await responseStream.CopyToAsync(memoryStream);
        }
    }
}
Content-Length: 10737418240
[05/22/2020 19:21:22 +02:00] Memory stream length: 48908
[05/22/2020 19:21:23 +02:00] Memory stream length: 6291456
[05/22/2020 19:21:24 +02:00] Memory stream length: 11616256
[05/22/2020 19:21:25 +02:00] Memory stream length: 18268160
[05/22/2020 19:21:26 +02:00] Memory stream length: 22052864
[05/22/2020 19:21:27 +02:00] Memory stream length: 29097984
[05/22/2020 19:21:28 +02:00] Memory stream length: 36143104
[05/22/2020 19:21:29 +02:00] Memory stream length: 41680896
[05/22/2020 19:21:30 +02:00] Memory stream length: 49610752
[05/22/2020 19:21:31 +02:00] Memory stream length: 56360960 // Disconnected LAN cable between switch and router.
[05/22/2020 19:21:32 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:33 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:34 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:35 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:36 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:37 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:38 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:39 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:40 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:41 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:42 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:43 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:44 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:45 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:46 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:47 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:48 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:49 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:50 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:51 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:52 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:53 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:54 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:55 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:56 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:57 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:58 +02:00] Memory stream length: 59654144
[05/22/2020 19:21:59 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:00 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:01 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:02 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:03 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:04 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:05 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:06 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:07 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:08 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:09 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:10 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:11 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:12 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:13 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:14 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:15 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:16 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:17 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:18 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:19 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:20 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:21 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:22 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:23 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:24 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:25 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:26 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:27 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:28 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:29 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:30 +02:00] Memory stream length: 59654144 // Around here I reconnect LAN cable between switch and router.
[05/22/2020 19:22:31 +02:00] Memory stream length: 59654144 // Nothing happens below.
[05/22/2020 19:22:32 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:33 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:34 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:35 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:36 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:37 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:38 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:39 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:40 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:41 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:42 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:43 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:44 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:45 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:46 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:47 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:48 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:49 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:50 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:51 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:52 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:53 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:54 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:55 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:56 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:57 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:58 +02:00] Memory stream length: 59654144
[05/22/2020 19:22:59 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:00 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:01 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:02 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:03 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:04 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:05 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:06 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:07 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:08 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:09 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:10 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:11 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:12 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:13 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:14 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:15 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:16 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:17 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:18 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:19 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:20 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:21 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:22 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:23 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:24 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:25 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:26 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:27 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:28 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:29 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:30 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:31 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:32 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:33 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:34 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:35 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:36 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:37 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:38 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:39 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:40 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:41 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:42 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:43 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:44 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:45 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:46 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:47 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:48 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:49 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:50 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:51 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:52 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:53 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:54 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:55 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:56 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:57 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:58 +02:00] Memory stream length: 59654144
[05/22/2020 19:23:59 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:00 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:01 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:02 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:03 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:04 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:05 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:06 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:07 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:08 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:09 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:10 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:11 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:12 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:13 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:14 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:15 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:16 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:17 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:18 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:19 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:20 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:21 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:22 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:23 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:24 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:25 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:26 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:27 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:28 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:29 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:30 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:31 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:32 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:33 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:34 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:35 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:36 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:37 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:38 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:39 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:40 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:41 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:42 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:43 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:44 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:45 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:46 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:47 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:48 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:49 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:50 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:51 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:52 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:53 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:54 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:55 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:56 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:57 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:58 +02:00] Memory stream length: 59654144
[05/22/2020 19:24:59 +02:00] Memory stream length: 59654144
[05/22/2020 19:25:00 +02:00] Memory stream length: 59654144
[05/22/2020 19:25:01 +02:00] Memory stream length: 59654144 // I manually killed the process as it seems to be stuck.

However, if I disconnect cable between my desktop computer and switch, it stops copying streams but as soon as I reconnect the cable it doesn't get stuck and it actually resumes download.

@prcdpr
Copy link
Author

prcdpr commented May 22, 2020

I wonder how is it related to following properties of response Stream

  • CanTimeout being false
  • ReadTimeout being not supported

image

It looks like setting ReadTimeout on the response stream is unsupported, it throws an exception when I try to do that.

@prcdpr
Copy link
Author

prcdpr commented May 22, 2020

TCP connection stays is in ESTABLISHED state even if network cable is disconnected for more than 10 minutes

I'm no expert on TCP stack but shouldn't there be some kind of timeout on the socket?

image

@wfurt
Copy link
Member

wfurt commented May 22, 2020

That depends if you have data flowing or not. In the former case, TCP should notice lack of ACK and abort. For idle connections, one can enable TCP Keepalive but that is not easily accessible with current HTTP API. On some OSes, that can be enabled globally via networking defaults.

@prcdpr
Copy link
Author

prcdpr commented May 22, 2020

So out of curiosity I tried to use this method on the beginning of my code
https://docs.microsoft.com/en-us/dotnet/api/system.net.servicepoint.settcpkeepalive?view=netcore-3.1

With timeout set to 5000ms and interval set to and 5000ms, but it doesn't unstuck the copying. Is this setting effective to HTTP API?

@davidsh
Copy link
Contributor

davidsh commented May 22, 2020

Is this setting effective to HTTP API?

No. ServicePointManager/ServicePoint are legacy objects that are from .NET Framework. They have no affect in .NET Core.

@wfurt
Copy link
Member

wfurt commented May 22, 2020

ServicePoint is not relevant in .NET Core. That is legacy .NET Framework API. The docs should make it more clear ;(

@prcdpr
Copy link
Author

prcdpr commented May 22, 2020

Well, so maybe my issue should qualify not as a bug but as a feature request to allow developers setting TCP KeepAlive in System.Net.Http.HttpClient?

There are hardly any alternatives to HttpClient other than using libcurl bindings or manually working with sockets so it may become a blocker for many people working with large streaming requests.

@wfurt
Copy link
Member

wfurt commented May 22, 2020

That work is coming in in 5.0 @prcdpr. If you don't want overall timeout but more timeout between reads, do not use CopyToAsync() but implement similar function with timer between reads. That would allow you to be more nimble on network failures.

@prcdpr
Copy link
Author

prcdpr commented May 22, 2020

I'll do it that way then.

Do you already have it tracked for 5.0 so I can close this issue and subscribe to the proper one?

@wfurt
Copy link
Member

wfurt commented May 22, 2020

#28721 and underlying #1793.

@prcdpr
Copy link
Author

prcdpr commented May 22, 2020

Thanks for help

@prcdpr prcdpr closed this as completed May 22, 2020
@karelz karelz added this to the 5.0.0 milestone Aug 18, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 9, 2020
@karelz karelz removed the untriaged New issue has not been triaged by the area owner label Sep 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Http tenet-reliability Reliability/stability related issue (stress, load problems, etc.)
Projects
None yet
Development

No branches or pull requests

8 participants