From b12451025fa24180b6ff7a9687390e622d2ea0b4 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Thu, 17 Aug 2017 23:34:45 -0700 Subject: [PATCH] Exit OnConnected early if Negotiate fails (#733) --- .../HubEndPoint.cs | 11 +++++-- .../HubEndpointTests.cs | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs b/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs index d2db3c01de..eaa81799c5 100644 --- a/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs +++ b/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs @@ -61,7 +61,10 @@ namespace Microsoft.AspNetCore.SignalR var connectionContext = new HubConnectionContext(output, connection); - await ProcessNegotiate(connectionContext); + if (!await ProcessNegotiate(connectionContext)) + { + return; + } // Hubs support multiple producers so we set up this loop to copy // data written to the HubConnectionContext's channel to the transport channel @@ -103,7 +106,7 @@ namespace Microsoft.AspNetCore.SignalR } } - private async Task ProcessNegotiate(HubConnectionContext connection) + private async Task ProcessNegotiate(HubConnectionContext connection) { while (await connection.Input.WaitToReadAsync()) { @@ -130,10 +133,12 @@ namespace Microsoft.AspNetCore.SignalR connection.ProtocolReaderWriter = new HubProtocolReaderWriter(protocol, dataEncoder); - return; + return true; } } } + + return false; } private async Task RunHubAsync(HubConnectionContext connection) diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs index 4a50b22e66..3c0bde7433 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs @@ -39,6 +39,26 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public async Task MissingNegotiateAndMessageSentFromHubConnectionCanBeDisposedCleanly() + { + var serviceProvider = CreateServiceProvider(); + var endPoint = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + // TestClient automatically writes negotiate, for this test we want to assume negotiate never gets sent + client.Connection.Transport.In.TryRead(out var item); + + var endPointTask = endPoint.OnConnectedAsync(client.Connection); + + // kill the connection + client.Dispose(); + + await endPointTask; + } + } + [Fact] public async Task LifetimeManagerOnDisconnectedAsyncCalledIfLifetimeManagerOnConnectedAsyncThrows() { @@ -1094,5 +1114,14 @@ namespace Microsoft.AspNetCore.SignalR.Tests return base.OnConnectedAsync(); } } + + public class SimpleHub : Hub + { + public override async Task OnConnectedAsync() + { + await Clients.All.InvokeAsync("Send", $"{Context.ConnectionId} joined"); + await base.OnConnectedAsync(); + } + } } }