Calling abort inside TestServer handler should set RequestAborted (#9975)

This commit is contained in:
huysentruitw 2019-05-09 07:00:42 +02:00 committed by Chris Ross
parent b3836954ed
commit 6d5b6b0c6f
3 changed files with 43 additions and 5 deletions

View File

@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.TestHost
private TaskCompletionSource<HttpContext> _responseTcs = new TaskCompletionSource<HttpContext>(TaskCreationOptions.RunContinuationsAsynchronously); private TaskCompletionSource<HttpContext> _responseTcs = new TaskCompletionSource<HttpContext>(TaskCreationOptions.RunContinuationsAsynchronously);
private ResponseStream _responseStream; private ResponseStream _responseStream;
private ResponseFeature _responseFeature = new ResponseFeature(); private ResponseFeature _responseFeature = new ResponseFeature();
private CancellationTokenSource _requestAbortedSource = new CancellationTokenSource(); private RequestLifetimeFeature _requestLifetimeFeature = new RequestLifetimeFeature();
private bool _pipelineFinished; private bool _pipelineFinished;
private Context _testContext; private Context _testContext;
@ -35,9 +35,7 @@ namespace Microsoft.AspNetCore.TestHost
_httpContext.Features.Set<IHttpBodyControlFeature>(this); _httpContext.Features.Set<IHttpBodyControlFeature>(this);
_httpContext.Features.Set<IHttpResponseFeature>(_responseFeature); _httpContext.Features.Set<IHttpResponseFeature>(_responseFeature);
var requestLifetimeFeature = new HttpRequestLifetimeFeature(); _httpContext.Features.Set<IHttpRequestLifetimeFeature>(_requestLifetimeFeature);
requestLifetimeFeature.RequestAborted = _requestAbortedSource.Token;
_httpContext.Features.Set<IHttpRequestLifetimeFeature>(requestLifetimeFeature);
_responseStream = new ResponseStream(ReturnResponseMessageAsync, AbortRequest, () => AllowSynchronousIO); _responseStream = new ResponseStream(ReturnResponseMessageAsync, AbortRequest, () => AllowSynchronousIO);
_responseFeature.Body = _responseStream; _responseFeature.Body = _responseStream;
@ -92,7 +90,7 @@ namespace Microsoft.AspNetCore.TestHost
{ {
if (!_pipelineFinished) if (!_pipelineFinished)
{ {
_requestAbortedSource.Cancel(); _requestLifetimeFeature.Abort();
} }
_responseStream.CompleteWrites(); _responseStream.CompleteWrites();
} }

View File

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.TestHost
{
internal class RequestLifetimeFeature : IHttpRequestLifetimeFeature
{
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
public RequestLifetimeFeature()
{
RequestAborted = _cancellationTokenSource.Token;
}
public CancellationToken RequestAborted { get; set; }
public void Abort() => _cancellationTokenSource.Cancel();
}
}

View File

@ -310,6 +310,24 @@ namespace Microsoft.AspNetCore.TestHost
var ctx = await server.SendAsync(c => { }); var ctx = await server.SendAsync(c => { });
} }
[Fact]
public async Task CallingAbortInsideHandlerShouldSetRequestAborted()
{
var builder = new WebHostBuilder()
.Configure(app =>
{
app.Run(context =>
{
context.Abort();
return Task.CompletedTask;
});
});
var server = new TestServer(builder);
var ctx = await server.SendAsync(c => { });
Assert.True(ctx.RequestAborted.IsCancellationRequested);
}
private class VerifierLogger : ILogger<IWebHost> private class VerifierLogger : ILogger<IWebHost>
{ {
public IDisposable BeginScope<TState>(TState state) => new NoopDispoasble(); public IDisposable BeginScope<TState>(TState state) => new NoopDispoasble();