Improve error message when TestServer finishes with a pending request read (#17164)

This commit is contained in:
James Newton-King 2019-12-03 17:25:59 +13:00 committed by GitHub
parent 3cc84ce3c5
commit 00ac95f72b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 1 deletions

View File

@ -160,7 +160,17 @@ namespace Microsoft.AspNetCore.TestHost
private async Task CompleteRequestAsync()
{
if (!_requestPipe.Reader.TryRead(out var result) || !result.IsCompleted)
bool requestBodyInProgress;
try
{
requestBodyInProgress = !_requestPipe.Reader.TryRead(out var result) || !result.IsCompleted;
}
catch (Exception ex)
{
throw new InvalidOperationException("An error occurred when completing the request. Request delegate may have finished while there is a pending read of the request body.", ex);
}
if (requestBodyInProgress)
{
// If request is still in progress then abort it.
CancelRequestBody();

View File

@ -385,6 +385,54 @@ namespace Microsoft.AspNetCore.TestHost
await writeTask;
}
[Fact]
public async Task ClientStreaming_ResponseCompletesWithPendingRead_ThrowError()
{
// Arrange
var requestStreamTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
RequestDelegate appDelegate = async ctx =>
{
var pendingReadTask = ctx.Request.Body.ReadAsync(new byte[1024], 0, 1024);
ctx.Response.Headers["test-header"] = "true";
await ctx.Response.Body.FlushAsync();
};
Stream requestStream = null;
var builder = new WebHostBuilder().Configure(app => app.Run(appDelegate));
var server = new TestServer(builder);
var client = server.CreateClient();
var httpRequest = new HttpRequestMessage(HttpMethod.Post, "http://localhost:12345");
httpRequest.Version = new Version(2, 0);
httpRequest.Content = new PushContent(async stream =>
{
requestStream = stream;
await requestStreamTcs.Task;
});
// Act
var response = await client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).WithTimeout();
var responseContent = await response.Content.ReadAsStreamAsync().WithTimeout();
// Assert
response.EnsureSuccessStatusCode();
Assert.Equal("true", response.Headers.GetValues("test-header").Single());
// Read response
var ex = await Assert.ThrowsAsync<IOException>(async () =>
{
byte[] buffer = new byte[1024];
var length = await responseContent.ReadAsync(buffer).AsTask().WithTimeout();
});
Assert.Equal("An error occurred when completing the request. Request delegate may have finished while there is a pending read of the request body.", ex.InnerException.Message);
// Unblock request
requestStreamTcs.TrySetResult(null);
}
[Fact]
public async Task ClientStreaming_ServerAbort()
{