Special-case SocketsHttpHandler.MaxResponseDrainTime == 0 (#44568)
authorStephen Toub <stoub@microsoft.com>
Thu, 12 Nov 2020 18:12:10 +0000 (13:12 -0500)
committerGitHub <noreply@github.com>
Thu, 12 Nov 2020 18:12:10 +0000 (13:12 -0500)
If the drain size is set to 0, any attempts to drain end up failing with a 1st-chance exception that's logged and eaten, when we should just be skipping all the associated work and failing immediately.

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs

index a0f211a..837358c 100644 (file)
@@ -463,6 +463,12 @@ namespace System.Net.Http
                         if (cts == null) // only create the drain timer if we have to go async
                         {
                             TimeSpan drainTime = _connection._pool.Settings._maxResponseDrainTime;
+
+                            if (drainTime == TimeSpan.Zero)
+                            {
+                                return false;
+                            }
+
                             if (drainTime != Timeout.InfiniteTimeSpan)
                             {
                                 cts = new CancellationTokenSource((int)drainTime.TotalMilliseconds);
index d1c7389..96c6665 100644 (file)
@@ -212,11 +212,18 @@ namespace System.Net.Http
                 CancellationTokenSource? cts = null;
                 CancellationTokenRegistration ctr = default;
                 TimeSpan drainTime = _connection._pool.Settings._maxResponseDrainTime;
+
+                if (drainTime == TimeSpan.Zero)
+                {
+                    return false;
+                }
+
                 if (drainTime != Timeout.InfiniteTimeSpan)
                 {
                     cts = new CancellationTokenSource((int)drainTime.TotalMilliseconds);
                     ctr = cts.Token.Register(static s => ((HttpConnection)s!).Dispose(), _connection);
                 }
+
                 try
                 {
                     while (true)
index 7efc271..c4e8252 100644 (file)
@@ -70,7 +70,7 @@ namespace System.Net.Http
                     {
                         connection.Trace(drained ?
                             "Connection drain succeeded" :
-                            $"Connection drain failed because MaxResponseDrainSize of {connection._pool.Settings._maxResponseDrainSize} bytes was exceeded");
+                            $"Connection drain failed when MaxResponseDrainSize={connection._pool.Settings._maxResponseDrainSize} bytes or MaxResponseDrainTime=={connection._pool.Settings._maxResponseDrainTime} exceeded");
                     }
                 }
                 catch (Exception e)