Specify Content-Length for buffered responses (#9699)
This commit is contained in:
parent
0c11bb3194
commit
9ac2f52b22
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
public override bool CanWrite => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Length => throw new NotSupportedException();
|
||||
public override long Length => PagedByteBuffer.Length + (FileStream?.Length ?? 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Position
|
||||
|
|
@ -78,8 +78,6 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
internal long BufferedLength => PagedByteBuffer.Length + (FileStream?.Length ?? 0);
|
||||
|
||||
internal PagedByteBuffer PagedByteBuffer { get; }
|
||||
|
||||
internal FileStream FileStream { get; private set; }
|
||||
|
|
@ -103,7 +101,7 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
ThrowArgumentException(buffer, offset, count);
|
||||
ThrowIfDisposed();
|
||||
|
||||
if (_bufferLimit.HasValue && _bufferLimit - BufferedLength < count)
|
||||
if (_bufferLimit.HasValue && _bufferLimit - Length < count)
|
||||
{
|
||||
Dispose();
|
||||
throw new IOException("Buffer limit exceeded.");
|
||||
|
|
@ -136,7 +134,7 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
ThrowArgumentException(buffer, offset, count);
|
||||
ThrowIfDisposed();
|
||||
|
||||
if (_bufferLimit.HasValue && _bufferLimit - BufferedLength < count)
|
||||
if (_bufferLimit.HasValue && _bufferLimit - Length < count)
|
||||
{
|
||||
Dispose();
|
||||
throw new IOException("Buffer limit exceeded.");
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
bufferingStream.Write(input, 0, input.Length);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(input.Length, bufferingStream.Length);
|
||||
|
||||
// We should have written content to memory
|
||||
var pagedByteBuffer = bufferingStream.PagedByteBuffer;
|
||||
Assert.Equal(input, ReadBufferedContent(pagedByteBuffer));
|
||||
|
|
@ -53,6 +55,8 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
var pageBuffer = bufferingStream.PagedByteBuffer;
|
||||
var fileStream = bufferingStream.FileStream;
|
||||
|
||||
Assert.Equal(input.Length, bufferingStream.Length);
|
||||
|
||||
// File should have been created.
|
||||
Assert.Null(fileStream);
|
||||
|
||||
|
|
@ -238,6 +242,8 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
Assert.NotNull(fileStream);
|
||||
var fileBytes = ReadFileContent(fileStream);
|
||||
|
||||
Assert.Equal(input.Length, bufferingStream.Length);
|
||||
|
||||
Assert.Equal(new byte[] { 1, 2, 3, 4, 5, }, fileBytes);
|
||||
Assert.Equal(new byte[] { 6, 7 }, ReadBufferedContent(pageBuffer));
|
||||
}
|
||||
|
|
@ -344,6 +350,7 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
|
||||
// Assert
|
||||
Assert.Equal(input, memoryStream.ToArray());
|
||||
Assert.Equal(0, bufferingStream.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -360,6 +367,7 @@ namespace Microsoft.AspNetCore.WebUtilities
|
|||
|
||||
// Assert
|
||||
Assert.Equal(input, memoryStream.ToArray());
|
||||
Assert.Equal(0, bufferingStream.Length);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
public XmlWriterSettings WriterSettings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="DataContractSerializerSettings"/> used to configure the
|
||||
/// Gets or sets the <see cref="DataContractSerializerSettings"/> used to configure the
|
||||
/// <see cref="DataContractSerializer"/>.
|
||||
/// </summary>
|
||||
public DataContractSerializerSettings SerializerSettings
|
||||
|
|
@ -284,6 +284,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
if (fileBufferingWriteStream != null)
|
||||
{
|
||||
response.ContentLength = fileBufferingWriteStream.Length;
|
||||
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
if (fileBufferingWriteStream != null)
|
||||
{
|
||||
response.ContentLength = fileBufferingWriteStream.Length;
|
||||
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
/// <summary>
|
||||
/// Called during serialization to create the <see cref="JsonSerializer"/>.The formatter context
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="JsonSerializer"/> used during serialization and deserialization.</returns>
|
||||
protected virtual JsonSerializer CreateJsonSerializer()
|
||||
|
|
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
/// <summary>
|
||||
/// Called during serialization to create the <see cref="JsonSerializer"/>.The formatter context
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// that is passed gives an ability to create serializer specific to the context.
|
||||
/// </summary>
|
||||
/// <param name="context">A context object for <see cref="IOutputFormatter.WriteAsync(OutputFormatterWriteContext)"/>.</param>
|
||||
/// <returns>The <see cref="JsonSerializer"/> used during serialization and deserialization.</returns>
|
||||
|
|
@ -154,6 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
|
|||
|
||||
if (fileBufferingWriteStream != null)
|
||||
{
|
||||
response.ContentLength = fileBufferingWriteStream.Length;
|
||||
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
|
||||
using FormatterWebSite.Controllers;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -41,5 +42,16 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
var actualBody = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedBody, actualBody);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonOutputFormatter_SetsContentLength()
|
||||
{
|
||||
// Act
|
||||
var response = await Client.GetAsync($"/JsonOutputFormatter/{nameof(JsonOutputFormatterController.SimpleModelResult)}");
|
||||
|
||||
// Assert
|
||||
await response.AssertStatusCodeAsync(HttpStatusCode.OK);
|
||||
Assert.Equal(50, response.Content.Headers.ContentLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
"xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
Assert.Equal(167, response.Content.Headers.ContentLength);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -61,6 +62,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
await response.Content.ReadAsStringAsync());
|
||||
Assert.Equal(149, response.Content.Headers.ContentLength);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
|
|
|
|||
Loading…
Reference in New Issue