|
|
@@ -1,6 +1,7 @@
|
|
|
// 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;
|
|
|
using System.IO;
|
|
|
using System.IO.Pipelines;
|
|
|
using System.Threading;
|
|
|
@@ -29,18 +30,86 @@ namespace Microsoft.AspNetCore.Http.Extensions.Tests
|
|
|
|
|
|
await response.SendFileAsync("bob", 1, 3, CancellationToken.None);
|
|
|
|
|
|
- Assert.Equal("bob", fakeFeature.name);
|
|
|
- Assert.Equal(1, fakeFeature.offset);
|
|
|
- Assert.Equal(3, fakeFeature.length);
|
|
|
- Assert.Equal(CancellationToken.None, fakeFeature.token);
|
|
|
+ Assert.Equal("bob", fakeFeature.Name);
|
|
|
+ Assert.Equal(1, fakeFeature.Offset);
|
|
|
+ Assert.Equal(3, fakeFeature.Length);
|
|
|
+ Assert.Equal(CancellationToken.None, fakeFeature.Token);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public async Task SendFile_FallsBackToBodyStream()
|
|
|
+ {
|
|
|
+ var body = new MemoryStream();
|
|
|
+ var context = new DefaultHttpContext();
|
|
|
+ var response = context.Response;
|
|
|
+ response.Body = body;
|
|
|
+
|
|
|
+ await response.SendFileAsync("testfile1kb.txt", 1, 3, CancellationToken.None);
|
|
|
+
|
|
|
+ Assert.Equal(3, body.Length);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public async Task SendFile_Stream_ThrowsWhenCanceled()
|
|
|
+ {
|
|
|
+ var body = new MemoryStream();
|
|
|
+ var context = new DefaultHttpContext();
|
|
|
+ var response = context.Response;
|
|
|
+ response.Body = body;
|
|
|
+
|
|
|
+ await Assert.ThrowsAnyAsync<OperationCanceledException>(
|
|
|
+ () => response.SendFileAsync("testfile1kb.txt", 1, 3, new CancellationToken(canceled: true)));
|
|
|
+
|
|
|
+ Assert.Equal(0, body.Length);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public async Task SendFile_Feature_ThrowsWhenCanceled()
|
|
|
+ {
|
|
|
+ var context = new DefaultHttpContext();
|
|
|
+ var fakeFeature = new FakeResponseBodyFeature();
|
|
|
+ context.Features.Set<IHttpResponseBodyFeature>(fakeFeature);
|
|
|
+ var response = context.Response;
|
|
|
+
|
|
|
+ await Assert.ThrowsAsync<OperationCanceledException>(
|
|
|
+ () => response.SendFileAsync("testfile1kb.txt", 1, 3, new CancellationToken(canceled: true)));
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public async Task SendFile_Stream_AbortsSilentlyWhenRequestCanceled()
|
|
|
+ {
|
|
|
+ var body = new MemoryStream();
|
|
|
+ var context = new DefaultHttpContext();
|
|
|
+ context.RequestAborted = new CancellationToken(canceled: true);
|
|
|
+ var response = context.Response;
|
|
|
+ response.Body = body;
|
|
|
+
|
|
|
+ await response.SendFileAsync("testfile1kb.txt", 1, 3, CancellationToken.None);
|
|
|
+
|
|
|
+ Assert.Equal(0, body.Length);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public async Task SendFile_Feature_AbortsSilentlyWhenRequestCanceled()
|
|
|
+ {
|
|
|
+ var context = new DefaultHttpContext();
|
|
|
+ var fakeFeature = new FakeResponseBodyFeature();
|
|
|
+ context.Features.Set<IHttpResponseBodyFeature>(fakeFeature);
|
|
|
+ var token = new CancellationToken(canceled: true);
|
|
|
+ context.RequestAborted = token;
|
|
|
+ var response = context.Response;
|
|
|
+
|
|
|
+ await response.SendFileAsync("testfile1kb.txt", 1, 3, CancellationToken.None);
|
|
|
+
|
|
|
+ Assert.Equal(token, fakeFeature.Token);
|
|
|
}
|
|
|
|
|
|
private class FakeResponseBodyFeature : IHttpResponseBodyFeature
|
|
|
{
|
|
|
- public string name = null;
|
|
|
- public long offset = 0;
|
|
|
- public long? length = null;
|
|
|
- public CancellationToken token;
|
|
|
+ public string Name { get; set; } = null;
|
|
|
+ public long Offset { get; set; } = 0;
|
|
|
+ public long? Length { get; set; } = null;
|
|
|
+ public CancellationToken Token { get; set; }
|
|
|
|
|
|
public Stream Stream => throw new System.NotImplementedException();
|
|
|
|
|
|
@@ -58,10 +127,12 @@ namespace Microsoft.AspNetCore.Http.Extensions.Tests
|
|
|
|
|
|
public Task SendFileAsync(string path, long offset, long? length, CancellationToken cancellation)
|
|
|
{
|
|
|
- this.name = path;
|
|
|
- this.offset = offset;
|
|
|
- this.length = length;
|
|
|
- this.token = cancellation;
|
|
|
+ Name = path;
|
|
|
+ Offset = offset;
|
|
|
+ Length = length;
|
|
|
+ Token = cancellation;
|
|
|
+
|
|
|
+ cancellation.ThrowIfCancellationRequested();
|
|
|
return Task.FromResult(0);
|
|
|
}
|
|
|
|