File results - logging

This commit is contained in:
Kiran Challa 2017-12-27 17:06:55 -08:00
parent 997544077a
commit 40d027fca3
10 changed files with 185 additions and 47 deletions

View File

@ -1551,7 +1551,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <returns>The created <see cref="PhysicalFileResult"/> for the response.</returns>
[NonAction]
@ -1564,7 +1564,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <param name="enableRangeProcessing">Set to <c>true</c> to enable range requests processing.</param>
/// <returns>The created <see cref="PhysicalFileResult"/> for the response.</returns>
@ -1579,7 +1579,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <param name="fileDownloadName">The suggested file name.</param>
/// <returns>The created <see cref="PhysicalFileResult"/> for the response.</returns>
@ -1597,7 +1597,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <param name="fileDownloadName">The suggested file name.</param>
/// <param name="enableRangeProcessing">Set to <c>true</c> to enable range requests processing.</param>
@ -1620,7 +1620,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.</param>
/// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> associated with the file.</param>
@ -1641,7 +1641,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.</param>
/// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> associated with the file.</param>
@ -1664,7 +1664,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <param name="fileDownloadName">The suggested file name.</param>
/// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.</param>
@ -1687,7 +1687,7 @@ namespace Microsoft.AspNetCore.Mvc
/// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
/// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
/// </summary>
/// <param name="physicalPath">The physical path of the file to be returned.</param>
/// <param name="physicalPath">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type of the file.</param>
/// <param name="fileDownloadName">The suggested file name.</param>
/// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.</param>

View File

@ -4,6 +4,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
@ -29,6 +30,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
throw new ArgumentNullException(nameof(result));
}
Logger.ExecutingFileResult(result);
var (range, rangeLength, serveBody) = SetHeadersAndLog(
context,
result,
@ -62,6 +65,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
return Task.CompletedTask;
}
if (range != null)
{
Logger.WritingRangeToBody();
}
var fileContentStream = new MemoryStream(result.FileContents);
return WriteFileAsync(context.HttpContext, fileContentStream, range, rangeLength);
}

View File

@ -56,7 +56,6 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
SetContentType(context, result);
SetContentDispositionHeader(context, result);
Logger.FileResultExecuting(result.FileDownloadName);
var request = context.HttpContext.Request;
var httpRequestHeaders = request.GetTypedHeaders();
@ -106,6 +105,10 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
return SetRangeHeaders(context, httpRequestHeaders, fileLength.Value);
}
}
else
{
Logger.NotEnabledForRangeProcessing();
}
}
return (range: null, rangeLength: 0, serveBody);
@ -150,7 +153,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
response.Headers[HeaderNames.AcceptRanges] = AcceptRangeHeaderValue;
}
internal static bool IfRangeValid(
internal bool IfRangeValid(
RequestHeaders httpRequestHeaders,
DateTimeOffset? lastModified = null,
EntityTagHeaderValue etag = null)
@ -168,11 +171,13 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
if (lastModified.HasValue && lastModified > ifRange.LastModified)
{
Logger.IfRangeLastModifiedPreconditionFailed(lastModified, ifRange.LastModified);
return false;
}
}
else if (etag != null && ifRange.EntityTag != null && !ifRange.EntityTag.Compare(etag, useStrongComparison: true))
{
Logger.IfRangeETagPreconditionFailed(etag, ifRange.EntityTag);
return false;
}
}
@ -181,7 +186,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
}
// Internal for testing
internal static PreconditionState GetPreconditionState(
internal PreconditionState GetPreconditionState(
RequestHeaders httpRequestHeaders,
DateTimeOffset? lastModified = null,
EntityTagHeaderValue etag = null)
@ -200,6 +205,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
etag: etag,
matchFoundState: PreconditionState.ShouldProcess,
matchNotFoundState: PreconditionState.PreconditionFailed);
if (ifMatchState == PreconditionState.PreconditionFailed)
{
Logger.IfMatchPreconditionFailed(etag);
}
}
// 14.26 If-None-Match
@ -229,6 +239,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
var unmodified = ifUnmodifiedSince >= lastModified;
ifUnmodifiedSinceState = unmodified ? PreconditionState.ShouldProcess : PreconditionState.PreconditionFailed;
if (ifUnmodifiedSinceState == PreconditionState.PreconditionFailed)
{
Logger.IfUnmodifiedSincePreconditionFailed(lastModified, ifUnmodifiedSince);
}
}
var state = GetMaxPreconditionState(ifMatchState, ifNoneMatchState, ifModifiedSinceState, ifUnmodifiedSinceState);
@ -273,7 +288,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
return max;
}
private static (RangeItemHeaderValue range, long rangeLength, bool serveBody) SetRangeHeaders(
private (RangeItemHeaderValue range, long rangeLength, bool serveBody) SetRangeHeaders(
ActionContext context,
RequestHeaders httpRequestHeaders,
long fileLength)
@ -286,7 +301,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
var (isRangeRequest, range) = RangeHelper.ParseRange(
context.HttpContext,
httpRequestHeaders,
fileLength);
fileLength,
Logger);
if (!isRangeRequest)
{

View File

@ -3,6 +3,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
@ -28,6 +29,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
throw new ArgumentNullException(nameof(result));
}
Logger.ExecutingFileResult(result);
long? fileLength = null;
if (result.FileStream.CanSeek)
{
@ -67,6 +70,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
return Task.CompletedTask;
}
if (range != null)
{
Logger.WritingRangeToBody();
}
return WriteFileAsync(context.HttpContext, result.FileStream, range, rangeLength);
}
}

View File

@ -7,6 +7,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
@ -39,6 +40,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
Resources.FormatFileResult_InvalidPath(result.FileName), result.FileName);
}
Logger.ExecutingFileResult(result, result.FileName);
var lastModified = result.LastModified ?? fileInfo.LastModified;
var (range, rangeLength, serveBody) = SetHeadersAndLog(
context,
@ -79,6 +82,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
throw new NotSupportedException(Resources.FormatFileResult_PathNotRooted(result.FileName));
}
if (range != null)
{
Logger.WritingRangeToBody();
}
var sendFile = response.HttpContext.Features.Get<IHttpSendFileFeature>();
if (sendFile != null)
{

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
@ -49,6 +50,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
Resources.FormatFileResult_InvalidPath(result.FileName), result.FileName);
}
Logger.ExecutingFileResult(result, result.FileName);
var lastModified = result.LastModified ?? fileInfo.LastModified;
var (range, rangeLength, serveBody) = SetHeadersAndLog(
context,
@ -85,6 +88,12 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
var response = context.HttpContext.Response;
var physicalPath = fileInfo.PhysicalPath;
if (range != null)
{
Logger.WritingRangeToBody();
}
var sendFile = response.HttpContext.Features.Get<IHttpSendFileFeature>();
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
{
@ -110,6 +119,10 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
private IFileInfo GetFileInformation(VirtualFileResult result)
{
var fileProvider = GetFileProvider(result);
if (fileProvider is NullFileProvider)
{
throw new InvalidOperationException(Resources.VirtualFileResultExecutor_NoFileProviderConfigured);
}
var normalizedPath = result.FileName;
if (normalizedPath.StartsWith("~", StringComparison.Ordinal))

View File

@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Formatters.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Mvc.Internal
{
@ -45,8 +46,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private static readonly Action<ILogger, string, Exception> _ambiguousActions;
private static readonly Action<ILogger, string, string, IActionConstraint, Exception> _constraintMismatch;
private static readonly Action<ILogger, string, Exception> _fileResultExecuting;
private static readonly Action<ILogger, FileResult, string, string, Exception> _executingFileResult;
private static readonly Action<ILogger, FileResult, string, Exception> _executingFileResultWithNoFileName;
private static readonly Action<ILogger, Exception> _notEnabledForRangeProcessing;
private static readonly Action<ILogger, Exception> _writingRangeToBody;
private static readonly Action<ILogger, object, Exception> _authorizationFailure;
private static readonly Action<ILogger, object, Exception> _resourceFilterShortCircuit;
private static readonly Action<ILogger, object, Exception> _resultFilterShortCircuit;
@ -101,6 +104,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
private static readonly Action<ILogger, string, Exception> _cannotApplyFormatFilterContentType;
private static readonly Action<ILogger, Exception> _actionDoesNotExplicitlySpecifyContentTypes;
private static readonly Action<ILogger, IEnumerable<MediaTypeSegmentWithQuality>, Exception> _selectingOutputFormatterUsingAcceptHeader;
private static readonly Action<ILogger, EntityTagHeaderValue, Exception> _ifMatchPreconditionFailed;
private static readonly Action<ILogger, DateTimeOffset?, DateTimeOffset?, Exception> _ifUnmodifiedSincePreconditionFailed;
private static readonly Action<ILogger, DateTimeOffset?, DateTimeOffset?, Exception> _ifRangeLastModifiedPreconditionFailed;
private static readonly Action<ILogger, EntityTagHeaderValue, EntityTagHeaderValue, Exception> _ifRangeETagPreconditionFailed;
private static readonly Action<ILogger, IEnumerable<MediaTypeSegmentWithQuality>, MediaTypeCollection, Exception> _selectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes;
private static readonly Action<ILogger, Exception> _selectingOutputFormatterWithoutUsingContentTypes;
private static readonly Action<ILogger, MediaTypeCollection, Exception> _selectingOutputFormatterUsingContentTypes;
@ -175,10 +182,15 @@ namespace Microsoft.AspNetCore.Mvc.Internal
2,
"Action '{ActionName}' with id '{ActionId}' did not match the constraint '{ActionConstraint}'");
_fileResultExecuting = LoggerMessage.Define<string>(
_executingFileResult = LoggerMessage.Define<FileResult, string, string>(
LogLevel.Information,
1,
"Executing FileResult, sending file as {FileDownloadName}");
"Executing {FileResultType}, sending file '{FileDownloadPath}' with download name '{FileDownloadName}' ...");
_executingFileResultWithNoFileName = LoggerMessage.Define<FileResult, string>(
LogLevel.Information,
2,
"Executing {FileResultType}, sending file with download name '{FileDownloadName}' ...");
_authorizationFailure = LoggerMessage.Define<object>(
LogLevel.Information,
@ -404,6 +416,36 @@ namespace Microsoft.AspNetCore.Mvc.Internal
LogLevel.Debug,
11,
"List of registered output formatters, in the following order: {OutputFormatters}");
_ifMatchPreconditionFailed = LoggerMessage.Define<EntityTagHeaderValue>(
LogLevel.Debug,
12,
"Current request's If-Match header check failed as the file's current etag '{CurrentETag}' does not match with any of the supplied etags.");
_ifUnmodifiedSincePreconditionFailed = LoggerMessage.Define<DateTimeOffset?, DateTimeOffset?>(
LogLevel.Debug,
13,
"Current request's If-Unmodified-Since header check failed as the file was modified (at '{lastModified}') after the If-Unmodified-Since date '{IfUnmodifiedSinceDate}'.");
_ifRangeLastModifiedPreconditionFailed = LoggerMessage.Define<DateTimeOffset?, DateTimeOffset?>(
LogLevel.Debug,
14,
"Could not serve range as the file was modified (at {LastModified}) after the if-Range's last modified date '{IfRangeLastModified}'.");
_ifRangeETagPreconditionFailed = LoggerMessage.Define<EntityTagHeaderValue, EntityTagHeaderValue>(
LogLevel.Debug,
15,
"Could not serve range as the file's current etag '{CurrentETag}' does not match the If-Range etag '{IfRangeETag}'.");
_notEnabledForRangeProcessing = LoggerMessage.Define(
LogLevel.Debug,
16,
$"The file result has not been enabled for processing range requests. To enable it, set the property '{nameof(FileResult.EnableRangeProcessing)}' on the result to 'true'.");
_writingRangeToBody = LoggerMessage.Define(
LogLevel.Debug,
17,
"Writing the requested range of bytes to the body...");
}
public static void RegisteredOutputFormatters(this ILogger logger, IEnumerable<IOutputFormatter> outputFormatters)
@ -412,8 +454,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}
public static void SelectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes(
this ILogger logger,
IEnumerable<MediaTypeSegmentWithQuality> acceptHeader,
this ILogger logger,
IEnumerable<MediaTypeSegmentWithQuality> acceptHeader,
MediaTypeCollection mediaTypeCollection)
{
_selectingOutputFormatterUsingAcceptHeaderAndExplicitContentTypes(logger, acceptHeader, mediaTypeCollection, null);
@ -624,9 +666,24 @@ namespace Microsoft.AspNetCore.Mvc.Internal
_constraintMismatch(logger, actionName, actionId, actionConstraint, null);
}
public static void FileResultExecuting(this ILogger logger, string fileDownloadName)
public static void ExecutingFileResult(this ILogger logger, FileResult fileResult)
{
_fileResultExecuting(logger, fileDownloadName, null);
_executingFileResultWithNoFileName(logger, fileResult, fileResult.FileDownloadName, null);
}
public static void ExecutingFileResult(this ILogger logger, FileResult fileResult, string fileName)
{
_executingFileResult(logger, fileResult, fileName, fileResult.FileDownloadName, null);
}
public static void NotEnabledForRangeProcessing(this ILogger logger)
{
_notEnabledForRangeProcessing(logger, null);
}
public static void WritingRangeToBody(this ILogger logger)
{
_writingRangeToBody(logger, null);
}
public static void AuthorizationFailure(
@ -881,6 +938,35 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}
}
public static void IfMatchPreconditionFailed(this ILogger logger, EntityTagHeaderValue etag)
{
_ifMatchPreconditionFailed(logger, etag, null);
}
public static void IfUnmodifiedSincePreconditionFailed(
this ILogger logger,
DateTimeOffset? lastModified,
DateTimeOffset? ifUnmodifiedSinceDate)
{
_ifUnmodifiedSincePreconditionFailed(logger, lastModified, ifUnmodifiedSinceDate, null);
}
public static void IfRangeLastModifiedPreconditionFailed(
this ILogger logger,
DateTimeOffset? lastModified,
DateTimeOffset? ifRangeLastModifiedDate)
{
_ifRangeLastModifiedPreconditionFailed(logger, lastModified, ifRangeLastModifiedDate, null);
}
public static void IfRangeETagPreconditionFailed(
this ILogger logger,
EntityTagHeaderValue currentETag,
EntityTagHeaderValue ifRangeTag)
{
_ifRangeETagPreconditionFailed(logger, currentETag, ifRangeTag, null);
}
private static void LogFilterExecutionPlan(
ILogger logger,
string filterType,

View File

@ -1354,6 +1354,20 @@ namespace Microsoft.AspNetCore.Mvc.Core
internal static string FormatApiController_AttributeRouteRequired(object p0)
=> string.Format(CultureInfo.CurrentCulture, GetString("ApiController_AttributeRouteRequired"), p0);
/// <summary>
/// No file provider has been configured to process the supplied file.
/// </summary>
internal static string VirtualFileResultExecutor_NoFileProviderConfigured
{
get => GetString("VirtualFileResultExecutor_NoFileProviderConfigured");
}
/// <summary>
/// No file provider has been configured to process the supplied file.
/// </summary>
internal static string FormatVirtualFileResultExecutor_NoFileProviderConfigured()
=> GetString("VirtualFileResultExecutor_NoFileProviderConfigured");
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -418,4 +418,7 @@
<data name="ApiController_AttributeRouteRequired" xml:space="preserve">
<value>Action methods on controllers annotated with {0} must have an attribute route.</value>
</data>
<data name="VirtualFileResultExecutor_NoFileProviderConfigured" xml:space="preserve">
<value>No file provider has been configured to process the supplied file.</value>
</data>
</root>

View File

@ -142,28 +142,6 @@ namespace Microsoft.AspNetCore.Mvc
await Assert.ThrowsAsync<InvalidOperationException>(() => result.ExecuteResultAsync(actionContext));
}
[ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.CLR, SkipReason = "Fails due to dotnet/standard#567")]
public async Task ExecuteResultAsync_LogsInformation_IfCanResolveLoggerFactory()
{
// Arrange
var httpContext = new DefaultHttpContext();
var services = new ServiceCollection();
var loggerSink = new TestSink();
services.AddSingleton<ILoggerFactory>(new TestLoggerFactory(loggerSink, true));
services.AddSingleton<EmptyFileResultExecutor>();
httpContext.RequestServices = services.BuildServiceProvider();
var actionContext = CreateActionContext(httpContext);
var result = new EmptyFileResult("application/my-type");
// Act
await result.ExecuteResultAsync(actionContext);
// Assert
Assert.Single(loggerSink.Writes);
}
public static TheoryData<string, string> ContentDispositionData
{
get
@ -302,9 +280,10 @@ namespace Microsoft.AspNetCore.Mvc
httpRequestHeaders.IfUnmodifiedSince = lastModified;
httpRequestHeaders.IfModifiedSince = DateTimeOffset.MinValue.AddDays(1);
actionContext.HttpContext = httpContext;
var fileResult = (new Mock<FileResultExecutorBase>(NullLogger.Instance)).Object;
// Act
var state = FileResultExecutorBase.GetPreconditionState(
var state = fileResult.GetPreconditionState(
httpRequestHeaders,
lastModified,
etag);
@ -338,9 +317,10 @@ namespace Microsoft.AspNetCore.Mvc
httpRequestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue;
httpRequestHeaders.IfModifiedSince = DateTimeOffset.MinValue.AddDays(2);
actionContext.HttpContext = httpContext;
var fileResult = (new Mock<FileResultExecutorBase>(NullLogger.Instance)).Object;
// Act
var state = FileResultExecutorBase.GetPreconditionState(
var state = fileResult.GetPreconditionState(
httpRequestHeaders,
lastModified,
etag);
@ -373,9 +353,10 @@ namespace Microsoft.AspNetCore.Mvc
};
httpRequestHeaders.IfModifiedSince = lastModified;
actionContext.HttpContext = httpContext;
var fileResult = (new Mock<FileResultExecutorBase>(NullLogger.Instance)).Object;
// Act
var state = FileResultExecutorBase.GetPreconditionState(
var state = fileResult.GetPreconditionState(
httpRequestHeaders,
lastModified,
etag);
@ -400,9 +381,10 @@ namespace Microsoft.AspNetCore.Mvc
httpRequestHeaders.IfRange = new RangeConditionHeaderValue(ifRangeString);
httpRequestHeaders.IfModifiedSince = lastModified;
actionContext.HttpContext = httpContext;
var fileResult = (new Mock<FileResultExecutorBase>(NullLogger.Instance)).Object;
// Act
var ifRangeIsValid = FileResultExecutorBase.IfRangeValid(
var ifRangeIsValid = fileResult.IfRangeValid(
httpRequestHeaders,
lastModified,
etag);