diff --git a/src/Http/Http/src/StreamResponseBodyFeature.cs b/src/Http/Http/src/StreamResponseBodyFeature.cs index 1152761e6e274f78dfa5b5336f171ab54b669166..717b5c08d2d3b1c20650f05f81b1217ef6425db6 100644 --- a/src/Http/Http/src/StreamResponseBodyFeature.cs +++ b/src/Http/Http/src/StreamResponseBodyFeature.cs @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Http } /// <summary> - /// This calls StartAsync if it has not previoulsy been called. + /// This calls StartAsync if it has not previously been called. /// It will complete the adapted pipe if it exists. /// </summary> /// <returns></returns> @@ -128,6 +128,11 @@ namespace Microsoft.AspNetCore.Http return; } + if (!_started) + { + await StartAsync(); + } + _completed = true; if (_pipeWriter != null) diff --git a/src/Http/Http/test/Features/StreamResponseBodyFeatureTests.cs b/src/Http/Http/test/Features/StreamResponseBodyFeatureTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..a7624e09693f0cab6ccfd397ddbb62f3e55830f6 --- /dev/null +++ b/src/Http/Http/test/Features/StreamResponseBodyFeatureTests.cs @@ -0,0 +1,62 @@ +// 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.Buffers; +using System.IO; +using System.IO.Pipelines; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.AspNetCore.Http.Features +{ + public class StreamResponseBodyFeatureTests + { + [Fact] + public async Task CompleteAsyncCallsStartAsync() + { + // Arrange + var stream = new MemoryStream(); + var streamResponseBodyFeature = new TestStreamResponseBodyFeature(stream); + + // Act + await streamResponseBodyFeature.CompleteAsync(); + + //Assert + Assert.Equal(1, streamResponseBodyFeature.StartCalled); + } + + [Fact] + public async Task CompleteAsyncWontCallsStartAsyncIfAlreadyStarted() + { + // Arrange + var stream = new MemoryStream(); + var streamResponseBodyFeature = new TestStreamResponseBodyFeature(stream); + await streamResponseBodyFeature.StartAsync(); + + // Act + await streamResponseBodyFeature.CompleteAsync(); + + //Assert + Assert.Equal(1, streamResponseBodyFeature.StartCalled); + } + } + + public class TestStreamResponseBodyFeature : StreamResponseBodyFeature + { + public TestStreamResponseBodyFeature(Stream stream) + : base(stream) + { + + } + + public override Task StartAsync(CancellationToken cancellationToken = default) + { + StartCalled++; + return base.StartAsync(cancellationToken); + } + + public int StartCalled { get; private set; } + } +}