Browse Source

Merge pull request #25884 from abpframework/maliming/remote-stream-content-cancellation-token

Pass `HttpContext.RequestAborted` to the response stream copy
pull/25886/head
Engincan VESKE 2 months ago
committed by GitHub
parent
commit
9544beba44
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 13
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs
  2. 40
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter_Tests.cs

13
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs

@ -34,9 +34,20 @@ public class RemoteStreamContentOutputFormatter : OutputFormatter
context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString(); context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();
} }
var cancellationToken = context.HttpContext.RequestAborted;
using (remoteStream) using (remoteStream)
{ {
await remoteStream.GetStream().CopyToAsync(context.HttpContext.Response.Body); var stream = remoteStream.GetStream();
try
{
await stream.CopyToAsync(context.HttpContext.Response.Body, cancellationToken);
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
// The request was aborted, nothing can be written to the response anymore.
}
} }
} }
} }

40
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter_Tests.cs

@ -0,0 +1,40 @@
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Formatters;
using Shouldly;
using Volo.Abp.Content;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters;
public class RemoteStreamContentOutputFormatter_Tests
{
[Fact]
public async Task Should_Not_Copy_The_Stream_When_The_Request_Is_Aborted()
{
using (var cancellationTokenSource = new CancellationTokenSource())
{
await cancellationTokenSource.CancelAsync();
var httpContext = new DefaultHttpContext();
httpContext.RequestAborted = cancellationTokenSource.Token;
httpContext.Response.Body = new MemoryStream();
var writeContext = new OutputFormatterWriteContext(
httpContext,
(stream, encoding) => new StreamWriter(stream, encoding),
typeof(IRemoteStreamContent),
new RemoteStreamContent(
new MemoryStream(Encoding.UTF8.GetBytes("DownloadAsync")),
"download.rtf",
"application/rtf"));
await new RemoteStreamContentOutputFormatter().WriteResponseBodyAsync(writeContext);
httpContext.Response.Body.Length.ShouldBe(0);
}
}
}
Loading…
Cancel
Save