From 399ac267ca30c2f95f6925011defb57385a048b1 Mon Sep 17 00:00:00 2001
From: BrennanConroy <brecon@microsoft.com>
Date: Mon, 10 Sep 2018 15:09:05 -0700
Subject: [PATCH] Cancel previous request on close (#2923)

---
 .../Internal/HttpConnectionDispatcher.cs        | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs b/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs
index 6662dd72c0e..50910bccfec 100644
--- a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs
+++ b/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs
@@ -215,8 +215,18 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                         // Cancel the previous request
                         connection.Cancellation?.Cancel();
 
-                        // Wait for the previous request to drain
-                        await connection.PreviousPollTask;
+                        try
+                        {
+                            // Wait for the previous request to drain
+                            await connection.PreviousPollTask;
+                        }
+                        catch (OperationCanceledException)
+                        {
+                            // Previous poll canceled due to connection closing, close this poll too
+                            context.Response.ContentType = "text/plain";
+                            context.Response.StatusCode = StatusCodes.Status204NoContent;
+                            return;
+                        }
 
                         connection.PreviousPollTask = currentRequestTcs.Task;
                     }
@@ -286,6 +296,9 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
                         // If the status code is a 204 it means the connection is done
                         if (context.Response.StatusCode == StatusCodes.Status204NoContent)
                         {
+                            // Cancel current request to release any waiting poll and let dispose aquire the lock
+                            currentRequestTcs.TrySetCanceled();
+
                             // We should be able to safely dispose because there's no more data being written
                             // We don't need to wait for close here since we've already waited for both sides
                             await _manager.DisposeAndRemoveAsync(connection, closeGracefully: false);
-- 
GitLab