Improve error message when TestServer finishes with a pending request read (#17164)
This commit is contained in:
parent
3cc84ce3c5
commit
00ac95f72b
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue