From a0d9b08f5806f5d3284e6453c28972cf1fefeba1 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Thu, 1 Jun 2017 11:27:49 -0700 Subject: [PATCH] Set Content-Length and increase BufferSize (#6347) Addresses #6045 --- .../Internal/FileResultExecutorBase.cs | 23 +++++++++++-------- .../FileContentResultTest.cs | 4 ++-- .../FileStreamResultTest.cs | 4 ++-- .../PhysicalFileResultTest.cs | 4 ++-- .../VirtualFileResultTest.cs | 4 ++-- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/FileResultExecutorBase.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/FileResultExecutorBase.cs index 45f89fb5a2..2a64c74601 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/FileResultExecutorBase.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/FileResultExecutorBase.cs @@ -19,8 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal { private const string AcceptRangeHeaderValue = "bytes"; - // default buffer size as defined in BufferedStream type - protected const int BufferSize = 0x1000; + protected const int BufferSize = 64 * 1024; public FileResultExecutorBase(ILogger logger) { @@ -40,9 +39,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal protected virtual (RangeItemHeaderValue range, long rangeLength, bool serveBody) SetHeadersAndLog( ActionContext context, - FileResult result, long? - fileLength, DateTimeOffset? - lastModified = null, + FileResult result, + long? fileLength, + DateTimeOffset? lastModified = null, EntityTagHeaderValue etag = null) { if (context == null) @@ -57,15 +56,20 @@ namespace Microsoft.AspNetCore.Mvc.Internal SetContentType(context, result); SetContentDispositionHeader(context, result); Logger.FileResultExecuting(result.FileDownloadName); - if (fileLength.HasValue) - { - SetAcceptRangeHeader(context); - } var request = context.HttpContext.Request; var httpRequestHeaders = request.GetTypedHeaders(); var response = context.HttpContext.Response; var httpResponseHeaders = response.GetTypedHeaders(); + if (fileLength.HasValue) + { + SetAcceptRangeHeader(context); + // Assuming the request is not a range request, the Content-Length header is set to the length of the entire file. + // If the request is a valid range request, this header is overwritten with the length of the range as part of the + // range processing (see method SetContentLength). + response.ContentLength = fileLength.Value; + } + if (lastModified.HasValue) { httpResponseHeaders.LastModified = lastModified; @@ -276,6 +280,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal fileLength.Value); response.StatusCode = StatusCodes.Status206PartialContent; + // Overwrite the Content-Length header for valid range requests with the range length. var rangeLength = SetContentLength(context, range); return (range, rangeLength, serveBody: true); } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/FileContentResultTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/FileContentResultTest.cs index 0c913f5c7e..cd3b94e62b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/FileContentResultTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/FileContentResultTest.cs @@ -308,9 +308,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status412PreconditionFailed, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(11, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); } @@ -350,9 +350,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status304NotModified, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(11, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/FileStreamResultTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/FileStreamResultTest.cs index cb8ab453ce..4ff7ecc8ec 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/FileStreamResultTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/FileStreamResultTest.cs @@ -297,9 +297,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status412PreconditionFailed, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(11, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); } @@ -340,9 +340,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status304NotModified, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(11, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/PhysicalFileResultTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/PhysicalFileResultTest.cs index 210b64c6a6..0bc08d9746 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/PhysicalFileResultTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/PhysicalFileResultTest.cs @@ -208,9 +208,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status412PreconditionFailed, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(34, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); } @@ -238,9 +238,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status304NotModified, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(34, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/VirtualFileResultTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/VirtualFileResultTest.cs index 4034bbb0c1..5c424ab4d2 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/VirtualFileResultTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/VirtualFileResultTest.cs @@ -270,9 +270,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status412PreconditionFailed, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(33, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); } @@ -312,9 +312,9 @@ namespace Microsoft.AspNetCore.Mvc var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status304NotModified, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); + Assert.Equal(33, httpResponse.ContentLength); Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); - Assert.Null(httpResponse.ContentLength); Assert.Empty(body); }