Add timeout to Negotiate (#736)

This commit is contained in:
BrennanConroy 2017-08-18 15:51:01 -07:00 committed by GitHub
parent a4053acd06
commit 345190e6a9
2 changed files with 44 additions and 17 deletions

View File

@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.SignalR
{ {
private static readonly Base64Encoder Base64Encoder = new Base64Encoder(); private static readonly Base64Encoder Base64Encoder = new Base64Encoder();
private static readonly PassThroughEncoder PassThroughEncoder = new PassThroughEncoder(); private static readonly PassThroughEncoder PassThroughEncoder = new PassThroughEncoder();
private static readonly TimeSpan NegotiateTimeout = TimeSpan.FromSeconds(5);
private readonly Dictionary<string, HubMethodDescriptor> _methods = new Dictionary<string, HubMethodDescriptor>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, HubMethodDescriptor> _methods = new Dictionary<string, HubMethodDescriptor>(StringComparer.OrdinalIgnoreCase);
@ -108,7 +109,12 @@ namespace Microsoft.AspNetCore.SignalR
private async Task<bool> ProcessNegotiate(HubConnectionContext connection) private async Task<bool> ProcessNegotiate(HubConnectionContext connection)
{ {
while (await connection.Input.WaitToReadAsync()) try
{
using (var cts = new CancellationTokenSource())
{
cts.CancelAfter(NegotiateTimeout);
while (await connection.Input.WaitToReadAsync(cts.Token))
{ {
while (connection.Input.TryRead(out var buffer)) while (connection.Input.TryRead(out var buffer))
{ {
@ -137,6 +143,12 @@ namespace Microsoft.AspNetCore.SignalR
} }
} }
} }
}
}
catch (OperationCanceledException)
{
_logger.LogDebug("Negotiate was canceled.");
}
return false; return false;
} }

View File

@ -59,6 +59,21 @@ namespace Microsoft.AspNetCore.SignalR.Tests
} }
} }
[Fact]
public async Task NegotiateTimesOut()
{
var serviceProvider = CreateServiceProvider();
var endPoint = serviceProvider.GetService<HubEndPoint<SimpleHub>>();
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);
await endPoint.OnConnectedAsync(client.Connection).OrTimeout(TimeSpan.FromSeconds(10));
}
}
[Fact] [Fact]
public async Task LifetimeManagerOnDisconnectedAsyncCalledIfLifetimeManagerOnConnectedAsyncThrows() public async Task LifetimeManagerOnDisconnectedAsyncCalledIfLifetimeManagerOnConnectedAsyncThrows()
{ {