From 401cbcc72dbf37983e825c613dd858d89f9153d7 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Thu, 4 May 2017 16:14:09 -0700 Subject: [PATCH 1/5] netcoreapp2.0 --- .../HttpOverridesSample.csproj | 2 +- .../ResponseBufferingSample.csproj | 2 +- .../ResponseCompressionSample.csproj | 2 +- samples/RewriteSample/RewriteSample.csproj | 2 +- .../BufferingWriteStream.cs | 27 ---------- .../Microsoft.AspNetCore.Buffering.csproj | 2 +- .../Microsoft.AspNetCore.HttpOverrides.csproj | 2 +- .../BodyWrapperStream.cs | 52 ------------------- .../CompressionProviderCollection.cs | 2 - .../GzipCompressionProvider.cs | 6 --- ...soft.AspNetCore.ResponseCompression.csproj | 2 +- .../Microsoft.AspNetCore.Rewrite.csproj | 2 +- ...icrosoft.AspNetCore.Buffering.Tests.csproj | 3 +- ...soft.AspNetCore.HttpOverrides.Tests.csproj | 3 +- .../BodyWrapperStreamTests.cs | 30 ----------- ...spNetCore.ResponseCompression.Tests.csproj | 3 +- .../ResponseCompressionMiddlewareTest.cs | 14 ----- .../Microsoft.AspNetCore.Rewrite.Tests.csproj | 3 +- 18 files changed, 12 insertions(+), 147 deletions(-) diff --git a/samples/HttpOverridesSample/HttpOverridesSample.csproj b/samples/HttpOverridesSample/HttpOverridesSample.csproj index c163d00c..a81f0815 100644 --- a/samples/HttpOverridesSample/HttpOverridesSample.csproj +++ b/samples/HttpOverridesSample/HttpOverridesSample.csproj @@ -3,7 +3,7 @@ - net46;netcoreapp2.0 + netcoreapp2.0 diff --git a/samples/ResponseBufferingSample/ResponseBufferingSample.csproj b/samples/ResponseBufferingSample/ResponseBufferingSample.csproj index 0a99f501..cec354e0 100644 --- a/samples/ResponseBufferingSample/ResponseBufferingSample.csproj +++ b/samples/ResponseBufferingSample/ResponseBufferingSample.csproj @@ -3,7 +3,7 @@ - net46;netcoreapp2.0 + netcoreapp2.0 diff --git a/samples/ResponseCompressionSample/ResponseCompressionSample.csproj b/samples/ResponseCompressionSample/ResponseCompressionSample.csproj index 37e37f9c..7de989af 100644 --- a/samples/ResponseCompressionSample/ResponseCompressionSample.csproj +++ b/samples/ResponseCompressionSample/ResponseCompressionSample.csproj @@ -3,7 +3,7 @@ - net46;netcoreapp2.0 + netcoreapp2.0 diff --git a/samples/RewriteSample/RewriteSample.csproj b/samples/RewriteSample/RewriteSample.csproj index 8dc059dc..a63cca04 100644 --- a/samples/RewriteSample/RewriteSample.csproj +++ b/samples/RewriteSample/RewriteSample.csproj @@ -3,7 +3,7 @@ - net46;netcoreapp2.0 + netcoreapp2.0 diff --git a/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs b/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs index 29ab23bd..45c8843f 100644 --- a/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs +++ b/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs @@ -160,34 +160,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati return _innerStream.WriteAsync(buffer, offset, count, cancellationToken); } } -#if NET46 - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - if (_isBuffering) - { - return _buffer.BeginWrite(buffer, offset, count, callback, state); - } - else - { - return _innerStream.BeginWrite(buffer, offset, count, callback, state); - } - } - public override void EndWrite(IAsyncResult asyncResult) - { - if (_isBuffering) - { - _buffer.EndWrite(asyncResult); - } - else - { - _innerStream.EndWrite(asyncResult); - } - } -#elif NETSTANDARD1_3 -#else -#error target frameworks need to be updated -#endif public override void Flush() { _isBuffering = false; diff --git a/src/Microsoft.AspNetCore.Buffering/Microsoft.AspNetCore.Buffering.csproj b/src/Microsoft.AspNetCore.Buffering/Microsoft.AspNetCore.Buffering.csproj index 658f4a83..36915fa2 100644 --- a/src/Microsoft.AspNetCore.Buffering/Microsoft.AspNetCore.Buffering.csproj +++ b/src/Microsoft.AspNetCore.Buffering/Microsoft.AspNetCore.Buffering.csproj @@ -5,7 +5,7 @@ 0.3.0 ASP.NET Core middleware for buffering response bodies. - net46;netstandard1.3 + netcoreapp2.0 $(NoWarn);CS1591 true aspnetcore;buffer;buffering diff --git a/src/Microsoft.AspNetCore.HttpOverrides/Microsoft.AspNetCore.HttpOverrides.csproj b/src/Microsoft.AspNetCore.HttpOverrides/Microsoft.AspNetCore.HttpOverrides.csproj index ab49dd26..01cfb31f 100644 --- a/src/Microsoft.AspNetCore.HttpOverrides/Microsoft.AspNetCore.HttpOverrides.csproj +++ b/src/Microsoft.AspNetCore.HttpOverrides/Microsoft.AspNetCore.HttpOverrides.csproj @@ -7,7 +7,7 @@ ASP.NET Core basic middleware for supporting HTTP method overrides. Includes: * X-Forwarded-* headers to forward headers from a proxy. * HTTP method override header. - netstandard1.3 + netcoreapp2.0 $(NoWarn);CS1591 true aspnetcore;proxy;headers;xforwarded diff --git a/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs b/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs index ff25fe8b..4b7674f7 100644 --- a/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs +++ b/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs @@ -137,58 +137,6 @@ public override void Write(byte[] buffer, int offset, int count) } } -#if NET46 - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) - { - var tcs = new TaskCompletionSource(state); - InternalWriteAsync(buffer, offset, count, callback, tcs); - return tcs.Task; - } - - private async void InternalWriteAsync(byte[] buffer, int offset, int count, AsyncCallback callback, TaskCompletionSource tcs) - { - try - { - await WriteAsync(buffer, offset, count); - tcs.TrySetResult(null); - } - catch (Exception ex) - { - tcs.TrySetException(ex); - } - - if (callback != null) - { - // Offload callbacks to avoid stack dives on sync completions. - var ignored = Task.Run(() => - { - try - { - callback(tcs.Task); - } - catch (Exception) - { - // Suppress exceptions on background threads. - } - }); - } - } - - public override void EndWrite(IAsyncResult asyncResult) - { - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } - - var task = (Task)asyncResult; - task.GetAwaiter().GetResult(); - } -#elif NETSTANDARD1_3 -#else -#error target frameworks need to be updated -#endif - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { OnWrite(); diff --git a/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs b/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs index a04e9209..9d2a55d5 100644 --- a/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs +++ b/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs @@ -3,9 +3,7 @@ using System; using System.Collections.ObjectModel; -#if NETSTANDARD1_3 using System.Reflection; -#endif namespace Microsoft.AspNetCore.ResponseCompression { diff --git a/src/Microsoft.AspNetCore.ResponseCompression/GzipCompressionProvider.cs b/src/Microsoft.AspNetCore.ResponseCompression/GzipCompressionProvider.cs index 0588995d..b7716f17 100644 --- a/src/Microsoft.AspNetCore.ResponseCompression/GzipCompressionProvider.cs +++ b/src/Microsoft.AspNetCore.ResponseCompression/GzipCompressionProvider.cs @@ -37,13 +37,7 @@ public bool SupportsFlush { get { -#if NET46 - return false; -#elif NETSTANDARD1_3 return true; -#else -#error target frameworks need to be updated -#endif } } diff --git a/src/Microsoft.AspNetCore.ResponseCompression/Microsoft.AspNetCore.ResponseCompression.csproj b/src/Microsoft.AspNetCore.ResponseCompression/Microsoft.AspNetCore.ResponseCompression.csproj index 80e48518..fc5f1b53 100644 --- a/src/Microsoft.AspNetCore.ResponseCompression/Microsoft.AspNetCore.ResponseCompression.csproj +++ b/src/Microsoft.AspNetCore.ResponseCompression/Microsoft.AspNetCore.ResponseCompression.csproj @@ -5,7 +5,7 @@ 2.0.0 ASP.NET Core middleware for HTTP Response compression. - net46;netstandard1.3 + netcoreapp2.0 true aspnetcore diff --git a/src/Microsoft.AspNetCore.Rewrite/Microsoft.AspNetCore.Rewrite.csproj b/src/Microsoft.AspNetCore.Rewrite/Microsoft.AspNetCore.Rewrite.csproj index 028eaeaa..530e010f 100644 --- a/src/Microsoft.AspNetCore.Rewrite/Microsoft.AspNetCore.Rewrite.csproj +++ b/src/Microsoft.AspNetCore.Rewrite/Microsoft.AspNetCore.Rewrite.csproj @@ -8,7 +8,7 @@ * Support for custom URL rewrite rules * Support for running IIS URL Rewrite module rules * Support for running Apache mod_rewrite rules. - netstandard1.3 + netcoreapp2.0 $(NoWarn);CS1591 true aspnetcore;urlrewrite;mod_rewrite diff --git a/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj b/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj index 2af1f9b1..34e94afc 100644 --- a/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj +++ b/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj @@ -3,8 +3,7 @@ - netcoreapp2.0;net46 - netcoreapp2.0 + netcoreapp2.0 true true diff --git a/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj b/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj index b525b892..a5d95145 100644 --- a/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj +++ b/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj @@ -3,8 +3,7 @@ - netcoreapp2.0;net46 - netcoreapp2.0 + netcoreapp2.0 true true diff --git a/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs b/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs index a1efd4a4..63613d05 100644 --- a/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs +++ b/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs @@ -108,36 +108,6 @@ public async Task SendFileAsync_IsPassedToUnderlyingStream_WhenDisableResponseBu Assert.Equal(File.ReadAllBytes(path), written); } -#if NET46 - [Theory] - [InlineData(true)] - [InlineData(false)] - public void BeginWrite_IsPassedToUnderlyingStream_WhenDisableResponseBuffering(bool flushable) - { - var buffer = new byte[] { 1 }; - byte[] written = null; - - var mock = new Mock(); - mock.SetupGet(s => s.CanWrite).Returns(true); - mock.Setup(s => s.WriteAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((b, o, c, t) => - { - written = new ArraySegment(b, 0, c).ToArray(); - }) - .Returns(Task.FromResult(0)); - - var stream = new BodyWrapperStream(new DefaultHttpContext(), mock.Object, new MockResponseCompressionProvider(flushable), null, null); - - stream.DisableResponseBuffering(); - stream.BeginWrite(buffer, 0, buffer.Length, (o) => {}, null); - - Assert.Equal(buffer, written); - } -#elif NETCOREAPP2_0 -#else -#error Target framework needs to be updated -#endif - private class MockResponseCompressionProvider: IResponseCompressionProvider { private readonly bool _flushable; diff --git a/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj b/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj index 27ab9222..0d5747fc 100644 --- a/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj +++ b/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj @@ -3,8 +3,7 @@ - netcoreapp2.0;net46 - netcoreapp2.0 + netcoreapp2.0 true true diff --git a/test/Microsoft.AspNetCore.ResponseCompression.Tests/ResponseCompressionMiddlewareTest.cs b/test/Microsoft.AspNetCore.ResponseCompression.Tests/ResponseCompressionMiddlewareTest.cs index 34fd5f2c..4fa7b92e 100644 --- a/test/Microsoft.AspNetCore.ResponseCompression.Tests/ResponseCompressionMiddlewareTest.cs +++ b/test/Microsoft.AspNetCore.ResponseCompression.Tests/ResponseCompressionMiddlewareTest.cs @@ -505,16 +505,9 @@ public async Task TrickleWriteAndFlush_FlushesEachWrite() var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); -#if NET46 // Flush not supported, compression disabled - Assert.NotNull(response.Headers.GetValues(HeaderNames.ContentMD5)); - Assert.Empty(response.Content.Headers.ContentEncoding); -#elif NETCOREAPP2_0 // Flush supported, compression enabled IEnumerable contentMD5 = null; Assert.False(response.Headers.TryGetValues(HeaderNames.ContentMD5, out contentMD5)); Assert.Single(response.Content.Headers.ContentEncoding, "gzip"); -#else -#error Target frameworks need to be updated. -#endif var body = await response.Content.ReadAsStreamAsync(); @@ -570,16 +563,9 @@ public async Task TrickleWriteAndFlushAsync_FlushesEachWrite() var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); -#if NET46 // Flush not supported, compression disabled - Assert.NotNull(response.Headers.GetValues(HeaderNames.ContentMD5)); - Assert.Empty(response.Content.Headers.ContentEncoding); -#elif NETCOREAPP2_0 // Flush supported, compression enabled IEnumerable contentMD5 = null; Assert.False(response.Headers.TryGetValues(HeaderNames.ContentMD5, out contentMD5)); Assert.Single(response.Content.Headers.ContentEncoding, "gzip"); -#else -#error Target framework needs to be updated -#endif var body = await response.Content.ReadAsStreamAsync(); diff --git a/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj b/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj index 79c1c1c2..d0f15960 100644 --- a/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj +++ b/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj @@ -3,8 +3,7 @@ - netcoreapp2.0;net46 - netcoreapp2.0 + netcoreapp2.0 true true From 4123fb1efd1ae7c669f0e0044bb9670340eb40b6 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Thu, 4 May 2017 16:23:19 -0700 Subject: [PATCH 2/5] Thank you @anurse --- build/dependencies.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/dependencies.props b/build/dependencies.props index 50283ae2..a353b252 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -2,7 +2,7 @@ 2.0.0-preview1-* 4.3.0 - 2.0.0-* + 2.1.0-* 4.7.1 $(BundledNETStandardPackageVersion) 15.0.0 From cc5f1446a8df0ace237cc7261dbab3dad0445243 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Thu, 4 May 2017 16:28:46 -0700 Subject: [PATCH 3/5] Remove *BindingRedirects* things --- .../Microsoft.AspNetCore.Buffering.Tests.csproj | 2 -- .../Microsoft.AspNetCore.HttpOverrides.Tests.csproj | 2 -- .../Microsoft.AspNetCore.ResponseCompression.Tests.csproj | 2 -- .../Microsoft.AspNetCore.Rewrite.Tests.csproj | 2 -- 4 files changed, 8 deletions(-) diff --git a/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj b/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj index 34e94afc..1a2e0b4b 100644 --- a/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj +++ b/test/Microsoft.AspNetCore.Buffering.Tests/Microsoft.AspNetCore.Buffering.Tests.csproj @@ -4,8 +4,6 @@ netcoreapp2.0 - true - true diff --git a/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj b/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj index a5d95145..2b04e296 100644 --- a/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj +++ b/test/Microsoft.AspNetCore.HttpOverrides.Tests/Microsoft.AspNetCore.HttpOverrides.Tests.csproj @@ -4,8 +4,6 @@ netcoreapp2.0 - true - true diff --git a/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj b/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj index 0d5747fc..faf06497 100644 --- a/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj +++ b/test/Microsoft.AspNetCore.ResponseCompression.Tests/Microsoft.AspNetCore.ResponseCompression.Tests.csproj @@ -4,8 +4,6 @@ netcoreapp2.0 - true - true diff --git a/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj b/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj index d0f15960..bbff9efe 100644 --- a/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj +++ b/test/Microsoft.AspNetCore.Rewrite.Tests/Microsoft.AspNetCore.Rewrite.Tests.csproj @@ -4,8 +4,6 @@ netcoreapp2.0 - true - true From 07db00d0c8d7a3c3c185c796a23e530260b5fab5 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Fri, 5 May 2017 10:52:51 -0700 Subject: [PATCH 4/5] PR comments --- .../BufferingWriteStream.cs | 24 +++++++++++++++++++ .../CompressionProviderCollection.cs | 1 - 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs b/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs index 45c8843f..b81b7092 100644 --- a/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs +++ b/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs @@ -161,6 +161,30 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati } } + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + if (_isBuffering) + { + return _buffer.BeginWrite(buffer, offset, count, callback, state); + } + else + { + return _innerStream.BeginWrite(buffer, offset, count, callback, state); + } + } + + public override void EndWrite(IAsyncResult asyncResult) + { + if (_isBuffering) + { + _buffer.EndWrite(asyncResult); + } + else + { + _innerStream.EndWrite(asyncResult); + } + } + public override void Flush() { _isBuffering = false; diff --git a/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs b/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs index 9d2a55d5..e4d15ef5 100644 --- a/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs +++ b/src/Microsoft.AspNetCore.ResponseCompression/CompressionProviderCollection.cs @@ -3,7 +3,6 @@ using System; using System.Collections.ObjectModel; -using System.Reflection; namespace Microsoft.AspNetCore.ResponseCompression { From 9ed6be0aff29f255aaeffa88ee8b4a304bdf96a3 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Fri, 5 May 2017 11:07:40 -0700 Subject: [PATCH 5/5] undo changes --- .../BodyWrapperStream.cs | 47 +++++++++++++++++++ .../BodyWrapperStreamTests.cs | 25 ++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs b/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs index 4b7674f7..d315d82d 100644 --- a/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs +++ b/src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs @@ -137,6 +137,53 @@ public override void Write(byte[] buffer, int offset, int count) } } + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) + { + var tcs = new TaskCompletionSource(state); + InternalWriteAsync(buffer, offset, count, callback, tcs); + return tcs.Task; + } + + private async void InternalWriteAsync(byte[] buffer, int offset, int count, AsyncCallback callback, TaskCompletionSource tcs) + { + try + { + await WriteAsync(buffer, offset, count); + tcs.TrySetResult(null); + } + catch (Exception ex) + { + tcs.TrySetException(ex); + } + + if (callback != null) + { + // Offload callbacks to avoid stack dives on sync completions. + var ignored = Task.Run(() => + { + try + { + callback(tcs.Task); + } + catch (Exception) + { + // Suppress exceptions on background threads. + } + }); + } + } + + public override void EndWrite(IAsyncResult asyncResult) + { + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } + + var task = (Task)asyncResult; + task.GetAwaiter().GetResult(); + } + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { OnWrite(); diff --git a/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs b/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs index 63613d05..46c7fb46 100644 --- a/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs +++ b/test/Microsoft.AspNetCore.ResponseCompression.Tests/BodyWrapperStreamTests.cs @@ -108,6 +108,31 @@ public async Task SendFileAsync_IsPassedToUnderlyingStream_WhenDisableResponseBu Assert.Equal(File.ReadAllBytes(path), written); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void BeginWrite_IsPassedToUnderlyingStream_WhenDisableResponseBuffering(bool flushable) + { + var buffer = new byte[] { 1 }; + byte[] written = null; + + var mock = new Mock(); + mock.SetupGet(s => s.CanWrite).Returns(true); + mock.Setup(s => s.WriteAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((b, o, c, t) => + { + written = new ArraySegment(b, 0, c).ToArray(); + }) + .Returns(Task.FromResult(0)); + + var stream = new BodyWrapperStream(new DefaultHttpContext(), mock.Object, new MockResponseCompressionProvider(flushable), null, null); + + stream.DisableResponseBuffering(); + stream.BeginWrite(buffer, 0, buffer.Length, (o) => {}, null); + + Assert.Equal(buffer, written); + } + private class MockResponseCompressionProvider: IResponseCompressionProvider { private readonly bool _flushable;