Skip to content

Commit 6d5b6b0

Browse files
huysentruitwTratcher
authored andcommitted
Calling abort inside TestServer handler should set RequestAborted (#9975)
1 parent b383695 commit 6d5b6b0

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

src/Hosting/TestHost/src/HttpContextBuilder.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal class HttpContextBuilder : IHttpBodyControlFeature
1919
private TaskCompletionSource<HttpContext> _responseTcs = new TaskCompletionSource<HttpContext>(TaskCreationOptions.RunContinuationsAsynchronously);
2020
private ResponseStream _responseStream;
2121
private ResponseFeature _responseFeature = new ResponseFeature();
22-
private CancellationTokenSource _requestAbortedSource = new CancellationTokenSource();
22+
private RequestLifetimeFeature _requestLifetimeFeature = new RequestLifetimeFeature();
2323
private bool _pipelineFinished;
2424
private Context _testContext;
2525

@@ -35,9 +35,7 @@ internal HttpContextBuilder(IHttpApplication<Context> application, bool allowSyn
3535

3636
_httpContext.Features.Set<IHttpBodyControlFeature>(this);
3737
_httpContext.Features.Set<IHttpResponseFeature>(_responseFeature);
38-
var requestLifetimeFeature = new HttpRequestLifetimeFeature();
39-
requestLifetimeFeature.RequestAborted = _requestAbortedSource.Token;
40-
_httpContext.Features.Set<IHttpRequestLifetimeFeature>(requestLifetimeFeature);
38+
_httpContext.Features.Set<IHttpRequestLifetimeFeature>(_requestLifetimeFeature);
4139

4240
_responseStream = new ResponseStream(ReturnResponseMessageAsync, AbortRequest, () => AllowSynchronousIO);
4341
_responseFeature.Body = _responseStream;
@@ -92,7 +90,7 @@ internal void AbortRequest()
9290
{
9391
if (!_pipelineFinished)
9492
{
95-
_requestAbortedSource.Cancel();
93+
_requestLifetimeFeature.Abort();
9694
}
9795
_responseStream.CompleteWrites();
9896
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Threading;
5+
using Microsoft.AspNetCore.Http.Features;
6+
7+
namespace Microsoft.AspNetCore.TestHost
8+
{
9+
internal class RequestLifetimeFeature : IHttpRequestLifetimeFeature
10+
{
11+
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
12+
13+
public RequestLifetimeFeature()
14+
{
15+
RequestAborted = _cancellationTokenSource.Token;
16+
}
17+
18+
public CancellationToken RequestAborted { get; set; }
19+
20+
public void Abort() => _cancellationTokenSource.Cancel();
21+
}
22+
}

src/Hosting/TestHost/test/HttpContextBuilderTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,24 @@ public async Task ClientHandlerCreateContextWithDefaultRequestParameters()
310310
var ctx = await server.SendAsync(c => { });
311311
}
312312

313+
[Fact]
314+
public async Task CallingAbortInsideHandlerShouldSetRequestAborted()
315+
{
316+
var builder = new WebHostBuilder()
317+
.Configure(app =>
318+
{
319+
app.Run(context =>
320+
{
321+
context.Abort();
322+
return Task.CompletedTask;
323+
});
324+
});
325+
var server = new TestServer(builder);
326+
327+
var ctx = await server.SendAsync(c => { });
328+
Assert.True(ctx.RequestAborted.IsCancellationRequested);
329+
}
330+
313331
private class VerifierLogger : ILogger<IWebHost>
314332
{
315333
public IDisposable BeginScope<TState>(TState state) => new NoopDispoasble();

0 commit comments

Comments
 (0)