Undo use of pipewriter in FileBufferingWriteStream (#21833)

This commit is contained in:
Pranav K 2020-05-14 12:38:49 -07:00 committed by GitHub
parent 0e652d1aba
commit 48261fdada
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 29 deletions

View File

@ -77,8 +77,6 @@ namespace Microsoft.AspNetCore.WebUtilities
[System.Diagnostics.DebuggerStepThroughAttribute]
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task DrainBufferAsync(System.IO.Pipelines.PipeWriter destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task DrainBufferAsync(System.IO.Stream destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override void Flush() { }
public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }

View File

@ -186,25 +186,8 @@ namespace Microsoft.AspNetCore.WebUtilities
// unspooled content. Copy the FileStream content first when available.
if (FileStream != null)
{
// We make a new stream for async reads from disk and async writes to the destination
await using var readStream = new FileStream(FileStream.Name, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite, bufferSize: 1, useAsync: true);
await FileStream.FlushAsync(cancellationToken);
await readStream.CopyToAsync(destination, cancellationToken);
// This is created with delete on close
await FileStream.DisposeAsync();
FileStream = null;
}
await PagedByteBuffer.MoveToAsync(destination, cancellationToken);
}
public async Task DrainBufferAsync(PipeWriter destination, CancellationToken cancellationToken = default)
{
// When not null, FileStream always has "older" spooled content. The PagedByteBuffer always has "newer"
// unspooled content. Copy the FileStream content first when available.
if (FileStream != null)
{
// We make a new stream for async reads from disk and async writes to the destination
await using var readStream = new FileStream(FileStream.Name, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite, bufferSize: 1, useAsync: true);

View File

@ -371,6 +371,24 @@ namespace Microsoft.AspNetCore.WebUtilities
Assert.Equal(0, bufferingStream.Length);
}
[Fact]
public async Task DrainBufferAsync_IncludesContentPossiblyBufferedByFileStream()
{
// We want to ensure that the FileStream (which has a 1-byte buffer) flushes prior to the other read stream reading input.
// Arrange
var input = new byte[] { 3, };
using var bufferingStream = new FileBufferingWriteStream(0, tempFileDirectoryAccessor: () => TempDirectory);
bufferingStream.Write(input, 0, input.Length);
var memoryStream = new MemoryStream();
// Act
await bufferingStream.DrainBufferAsync(memoryStream, default);
// Assert
Assert.Equal(input, memoryStream.ToArray());
Assert.Equal(0, bufferingStream.Length);
}
public void Dispose()
{
try

View File

@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
if (fileBufferingWriteStream != null)
{
response.ContentLength = fileBufferingWriteStream.Length;
await fileBufferingWriteStream.DrainBufferAsync(response.BodyWriter);
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
}
}
finally

View File

@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
if (fileBufferingWriteStream != null)
{
response.ContentLength = fileBufferingWriteStream.Length;
await fileBufferingWriteStream.DrainBufferAsync(response.BodyWriter);
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
}
}
finally

View File

@ -154,15 +154,17 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal(expected, await response.Content.ReadAsStringAsync());
}
[Fact]
public virtual async Task Formatting_LargeObject()
[Theory]
[InlineData(65 * 1024)]
[InlineData(2 * 1024 * 1024)]
public virtual async Task Formatting_LargeObject(int size)
{
// Arrange
var expectedName = "This is long so we can test large objects " + new string('a', 1024 * 65);
var expectedName = "This is long so we can test large objects " + new string('a', size);
var expected = $"{{\"id\":10,\"name\":\"{expectedName}\",\"streetName\":null}}";
// Act
var response = await Client.GetAsync($"/JsonOutputFormatter/{nameof(JsonOutputFormatterController.LargeObjectResult)}");
var response = await Client.GetAsync($"/JsonOutputFormatter/{nameof(JsonOutputFormatterController.LargeObjectResult)}/{size}");
// Assert
await response.AssertStatusCodeAsync(HttpStatusCode.OK);

View File

@ -44,12 +44,12 @@ namespace FormatterWebSite.Controllers
["Key3"] = null,
};
[HttpGet]
public ActionResult<SimpleModel> LargeObjectResult() =>
[HttpGet("{size:int}")]
public ActionResult<SimpleModel> LargeObjectResult(int size) =>
new SimpleModel
{
Id = 10,
Name = "This is long so we can test large objects " + new string('a', 1024 * 65),
Name = "This is long so we can test large objects " + new string('a', size),
};
[HttpGet]