Send delete request after poll ends (#2020)

* Added test and fixed other test
This commit is contained in:
David Fowler 2018-04-14 04:45:16 -07:00 committed by GitHub
parent 0f8485cafc
commit d6395a52bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 5 deletions

View File

@ -88,16 +88,16 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
// Set the sending error so we communicate that to the application
_error = sending.IsFaulted ? sending.Exception.InnerException : null;
// Send the DELETE request to clean-up the connection on the server.
// This will also cause the poll to return.
await SendDeleteRequest(url);
// Cancel the poll request
_transportCts.Cancel();
// Cancel any pending flush so that we can quit
_application.Output.CancelPendingFlush();
await receiving;
// Send the DELETE request to clean-up the connection on the server.
await SendDeleteRequest(url);
}
}

View File

@ -380,12 +380,13 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
}
else if (request.Method == HttpMethod.Get)
{
cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken));
// This is the poll task
return await tcs.Task;
}
else if (request.Method == HttpMethod.Delete)
{
tcs.TrySetResult(ResponseUtils.CreateResponse(HttpStatusCode.NoContent));
return ResponseUtils.CreateResponse(HttpStatusCode.Accepted);
}
return ResponseUtils.CreateResponse(HttpStatusCode.OK);
});
@ -419,6 +420,57 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
}
}
[Fact]
public async Task LongPollingTransportSendsDeleteAfterPollEnds()
{
var sentRequests = new List<byte[]>();
var pollTcs = new TaskCompletionSource<HttpResponseMessage>();
var deleteTcs = new TaskCompletionSource<object>();
var mockHttpHandler = new Mock<HttpMessageHandler>();
mockHttpHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.Returns<HttpRequestMessage, CancellationToken>(async (request, cancellationToken) =>
{
await Task.Yield();
if (request.Method == HttpMethod.Post)
{
// Build a new request object, but convert the entire payload to string
sentRequests.Add(await request.Content.ReadAsByteArrayAsync());
}
else if (request.Method == HttpMethod.Get)
{
cancellationToken.Register(() => pollTcs.TrySetCanceled(cancellationToken));
// This is the poll task
return await pollTcs.Task;
}
else if (request.Method == HttpMethod.Delete)
{
// The poll task should have been completed
Assert.True(pollTcs.Task.IsCompleted);
deleteTcs.TrySetResult(null);
return ResponseUtils.CreateResponse(HttpStatusCode.Accepted);
}
return ResponseUtils.CreateResponse(HttpStatusCode.OK);
});
using (var httpClient = new HttpClient(mockHttpHandler.Object))
{
var longPollingTransport = new LongPollingTransport(httpClient);
// Start the transport
await longPollingTransport.StartAsync(TestUri, TransferFormat.Binary);
var task = longPollingTransport.StopAsync();
await deleteTcs.Task.OrTimeout();
await task.OrTimeout();
}
}
[Theory]
[InlineData(TransferFormat.Binary)]
[InlineData(TransferFormat.Text)]