Skip to content

Commit 4340c2c

Browse files
committed
Revert "Undo use of pipewriter in FileBufferingWriteStream (#21833)"
This reverts commit 48261fd.
1 parent 7c0f02a commit 4340c2c

File tree

7 files changed

+30
-30
lines changed

7 files changed

+30
-30
lines changed

src/Http/WebUtilities/ref/Microsoft.AspNetCore.WebUtilities.netcoreapp.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ protected override void Dispose(bool disposing) { }
7777
[System.Diagnostics.DebuggerStepThroughAttribute]
7878
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
7979
[System.Diagnostics.DebuggerStepThroughAttribute]
80+
public System.Threading.Tasks.Task DrainBufferAsync(System.IO.Pipelines.PipeWriter destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
81+
[System.Diagnostics.DebuggerStepThroughAttribute]
8082
public System.Threading.Tasks.Task DrainBufferAsync(System.IO.Stream destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
8183
public override void Flush() { }
8284
public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }

src/Http/WebUtilities/src/FileBufferingWriteStream.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Diagnostics;
77
using System.Diagnostics.CodeAnalysis;
88
using System.IO;
9+
using System.IO.Pipelines;
910
using System.Threading;
1011
using System.Threading.Tasks;
1112
using Microsoft.AspNetCore.Internal;
@@ -185,8 +186,25 @@ public async Task DrainBufferAsync(Stream destination, CancellationToken cancell
185186
// unspooled content. Copy the FileStream content first when available.
186187
if (FileStream != null)
187188
{
188-
await FileStream.FlushAsync(cancellationToken);
189+
// We make a new stream for async reads from disk and async writes to the destination
190+
await using var readStream = new FileStream(FileStream.Name, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite, bufferSize: 1, useAsync: true);
191+
192+
await readStream.CopyToAsync(destination, cancellationToken);
193+
194+
// This is created with delete on close
195+
await FileStream.DisposeAsync();
196+
FileStream = null;
197+
}
189198

199+
await PagedByteBuffer.MoveToAsync(destination, cancellationToken);
200+
}
201+
202+
public async Task DrainBufferAsync(PipeWriter destination, CancellationToken cancellationToken = default)
203+
{
204+
// When not null, FileStream always has "older" spooled content. The PagedByteBuffer always has "newer"
205+
// unspooled content. Copy the FileStream content first when available.
206+
if (FileStream != null)
207+
{
190208
// We make a new stream for async reads from disk and async writes to the destination
191209
await using var readStream = new FileStream(FileStream.Name, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite, bufferSize: 1, useAsync: true);
192210

src/Http/WebUtilities/test/FileBufferingWriteStreamTests.cs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -371,24 +371,6 @@ public async Task DrainBufferAsync_WithContentInDisk_CopiesContentFromMemoryStre
371371
Assert.Equal(0, bufferingStream.Length);
372372
}
373373

374-
[Fact]
375-
public async Task DrainBufferAsync_IncludesContentPossiblyBufferedByFileStream()
376-
{
377-
// We want to ensure that the FileStream (which has a 1-byte buffer) flushes prior to the other read stream reading input.
378-
// Arrange
379-
var input = new byte[] { 3, };
380-
using var bufferingStream = new FileBufferingWriteStream(0, tempFileDirectoryAccessor: () => TempDirectory);
381-
bufferingStream.Write(input, 0, input.Length);
382-
var memoryStream = new MemoryStream();
383-
384-
// Act
385-
await bufferingStream.DrainBufferAsync(memoryStream, default);
386-
387-
// Assert
388-
Assert.Equal(input, memoryStream.ToArray());
389-
Assert.Equal(0, bufferingStream.Length);
390-
}
391-
392374
public void Dispose()
393375
{
394376
try

src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerOutputFormatter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext co
261261
if (fileBufferingWriteStream != null)
262262
{
263263
response.ContentLength = fileBufferingWriteStream.Length;
264-
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
264+
await fileBufferingWriteStream.DrainBufferAsync(response.BodyWriter);
265265
}
266266
}
267267
finally

src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext co
153153
if (fileBufferingWriteStream != null)
154154
{
155155
response.ContentLength = fileBufferingWriteStream.Length;
156-
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
156+
await fileBufferingWriteStream.DrainBufferAsync(response.BodyWriter);
157157
}
158158
}
159159
finally

src/Mvc/test/Mvc.FunctionalTests/JsonOutputFormatterTestBase.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,15 @@ public virtual async Task Formatting_DictionaryType()
154154
Assert.Equal(expected, await response.Content.ReadAsStringAsync());
155155
}
156156

157-
[Theory]
158-
[InlineData(65 * 1024)]
159-
[InlineData(2 * 1024 * 1024)]
160-
public virtual async Task Formatting_LargeObject(int size)
157+
[Fact]
158+
public virtual async Task Formatting_LargeObject()
161159
{
162160
// Arrange
163-
var expectedName = "This is long so we can test large objects " + new string('a', size);
161+
var expectedName = "This is long so we can test large objects " + new string('a', 1024 * 65);
164162
var expected = $"{{\"id\":10,\"name\":\"{expectedName}\",\"streetName\":null}}";
165163

166164
// Act
167-
var response = await Client.GetAsync($"/JsonOutputFormatter/{nameof(JsonOutputFormatterController.LargeObjectResult)}/{size}");
165+
var response = await Client.GetAsync($"/JsonOutputFormatter/{nameof(JsonOutputFormatterController.LargeObjectResult)}");
168166

169167
// Assert
170168
await response.AssertStatusCodeAsync(HttpStatusCode.OK);

src/Mvc/test/WebSites/FormatterWebSite/Controllers/JsonOutputFormatterController.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ public ActionResult<Dictionary<string, string>> DictionaryResult() =>
4444
["Key3"] = null,
4545
};
4646

47-
[HttpGet("{size:int}")]
48-
public ActionResult<SimpleModel> LargeObjectResult(int size) =>
47+
[HttpGet]
48+
public ActionResult<SimpleModel> LargeObjectResult() =>
4949
new SimpleModel
5050
{
5151
Id = 10,
52-
Name = "This is long so we can test large objects " + new string('a', size),
52+
Name = "This is long so we can test large objects " + new string('a', 1024 * 65),
5353
};
5454

5555
[HttpGet]

0 commit comments

Comments
 (0)