public void IfRangeValid_IgnoreRangeRequest(string ifRangeString, bool expected) { // Arrange var actionContext = new ActionContext(); var httpContext = new DefaultHttpContext(); httpContext.Request.Method = HttpMethods.Get; var httpRequestHeaders = httpContext.Request.GetTypedHeaders(); var lastModified = DateTimeOffset.MinValue; lastModified = new DateTimeOffset(lastModified.Year, lastModified.Month, lastModified.Day, lastModified.Hour, lastModified.Minute, lastModified.Second, TimeSpan.FromSeconds(0)); var etag = new EntityTagHeaderValue("\"Etag\""); httpRequestHeaders.IfRange = new RangeConditionHeaderValue(ifRangeString); httpRequestHeaders.IfModifiedSince = lastModified; actionContext.HttpContext = httpContext; // Act var ifRangeIsValid = FileResultHelper.IfRangeValid( httpRequestHeaders, lastModified, etag, NullLogger.Instance); // Assert Assert.Equal(expected, ifRangeIsValid); }
public void GetPreconditionState_ShouldNotProcess_NotModified(string ifMatch, string ifNoneMatch, bool isWeak) { // Arrange var actionContext = new ActionContext(); var httpContext = new DefaultHttpContext(); httpContext.Request.Method = HttpMethods.Get; var httpRequestHeaders = httpContext.Request.GetTypedHeaders(); var lastModified = DateTimeOffset.MinValue; lastModified = new DateTimeOffset(lastModified.Year, lastModified.Month, lastModified.Day, lastModified.Hour, lastModified.Minute, lastModified.Second, TimeSpan.FromSeconds(0)); var etag = new EntityTagHeaderValue("\"Etag\""); httpRequestHeaders.IfMatch = ifMatch == null ? null : new[] { new EntityTagHeaderValue(ifMatch), }; httpRequestHeaders.IfNoneMatch = ifNoneMatch == null ? null : new[] { new EntityTagHeaderValue(ifNoneMatch, isWeak), }; httpRequestHeaders.IfModifiedSince = lastModified; actionContext.HttpContext = httpContext; // Act var state = FileResultHelper.GetPreconditionState( httpRequestHeaders, lastModified, etag, NullLogger.Instance); // Assert Assert.Equal(FileResultHelper.PreconditionState.NotModified, state); }
public void GetPreconditionState_ShouldNotProcess_PreconditionFailed(string ifMatch, string ifNoneMatch, bool isWeak) { // Arrange var actionContext = new ActionContext(); var httpContext = new DefaultHttpContext(); httpContext.Request.Method = HttpMethods.Delete; var httpRequestHeaders = httpContext.Request.GetTypedHeaders(); var lastModified = DateTimeOffset.MinValue.AddDays(1); var etag = new EntityTagHeaderValue("\"Etag\""); httpRequestHeaders.IfMatch = ifMatch == null ? null : new[] { new EntityTagHeaderValue(ifMatch), }; httpRequestHeaders.IfNoneMatch = ifNoneMatch == null ? null : new[] { new EntityTagHeaderValue(ifNoneMatch, isWeak), }; httpRequestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue; httpRequestHeaders.IfModifiedSince = DateTimeOffset.MinValue.AddDays(2); actionContext.HttpContext = httpContext; // Act var state = FileResultHelper.GetPreconditionState( httpRequestHeaders, lastModified, etag, NullLogger.Instance); // Assert Assert.Equal(FileResultHelper.PreconditionState.PreconditionFailed, state); }
public static (RangeItemHeaderValue?range, long rangeLength, bool completed) WriteResultAsFileCore( HttpContext httpContext, ILogger logger, string?fileDownloadName, long?fileLength, string contentType, bool enableRangeProcessing, DateTimeOffset?lastModified, EntityTagHeaderValue?entityTag) { var completed = false; fileDownloadName ??= string.Empty; Log.WritingResultAsFile(logger, fileDownloadName); var fileResultInfo = new FileResultInfo { ContentType = contentType, EnableRangeProcessing = enableRangeProcessing, EntityTag = entityTag, FileDownloadName = fileDownloadName, LastModified = lastModified, }; var(range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( httpContext, fileResultInfo, fileLength, enableRangeProcessing, lastModified, entityTag, logger); if (range != null) { FileResultHelper.Log.WritingRangeToBody(logger); } if (!serveBody) { completed = true; } if (range != null && rangeLength == 0) { completed = true; } return(range, rangeLength, completed); }
public async Task ExecuteAsync(HttpContext httpContext) { var logger = httpContext.RequestServices.GetRequiredService <ILogger <FileStreamResult> >(); await using (FileStream) { Log.ExecutingFileResult(logger, this); long?fileLength = null; if (FileStream.CanSeek) { fileLength = FileStream.Length; } var fileResultInfo = new FileResultInfo { ContentType = ContentType, EnableRangeProcessing = EnableRangeProcessing, EntityTag = EntityTag, FileDownloadName = FileDownloadName, }; var(range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( httpContext, fileResultInfo, fileLength, EnableRangeProcessing, LastModified, EntityTag, logger); if (!serveBody) { return; } if (range != null && rangeLength == 0) { return; } if (range != null) { FileResultHelper.Log.WritingRangeToBody(logger); } await FileResultHelper.WriteFileAsync(httpContext, FileStream, range, rangeLength); } }
/// <summary> /// Sets etag and last modified headers. /// </summary> /// <param name="context">The <see cref="ActionContext"/>.</param> /// <param name="result">The <see cref="FileResult"/>.</param> /// <param name="fileLength">The nullable file length.</param> /// <param name="enableRangeProcessing">Whether range processing is enabled.</param> /// <param name="lastModified">The nullable lastModified date.</param> /// <param name="etag">The <see cref="EntityTagHeaderValue"/>.</param> /// <returns>A tuple with the <see cref="RangeItemHeaderValue"/> range, length, and whether the body was served.</returns> protected virtual (RangeItemHeaderValue?range, long rangeLength, bool serveBody) SetHeadersAndLog( ActionContext context, FileResult result, long?fileLength, bool enableRangeProcessing, DateTimeOffset?lastModified = null, EntityTagHeaderValue?etag = null) { var fileResultInfo = new FileResultInfo { ContentType = result.ContentType, EnableRangeProcessing = result.EnableRangeProcessing, EntityTag = result.EntityTag, FileDownloadName = result.FileDownloadName, LastModified = result.LastModified, }; return(FileResultHelper.SetHeadersAndLog(context.HttpContext, fileResultInfo, fileLength, enableRangeProcessing, lastModified, etag, Logger)); }
public virtual Task ExecuteAsync(HttpContext httpContext) { var logger = GetLogger(httpContext); Log.ExecutingFileResult(logger, this); var fileResultInfo = new FileResultInfo { ContentType = ContentType, EnableRangeProcessing = EnableRangeProcessing, EntityTag = EntityTag, FileDownloadName = FileDownloadName, LastModified = LastModified, }; var(range, rangeLength, serveBody) = FileResultHelper.SetHeadersAndLog( httpContext, fileResultInfo, FileLength, EnableRangeProcessing, LastModified, EntityTag, logger); if (!serveBody) { return(Task.CompletedTask); } if (range != null && rangeLength == 0) { return(Task.CompletedTask); } if (range != null) { FileResultHelper.Log.WritingRangeToBody(logger); } return(ExecuteCoreAsync(httpContext, range, rangeLength)); }
/// <summary> /// Write the contents of the fileStream to the response body. /// </summary> /// <param name="context">The <see cref="HttpContext"/>.</param> /// <param name="fileStream">The fileStream to write.</param> /// <param name="range">The <see cref="RangeItemHeaderValue"/>.</param> /// <param name="rangeLength">The range length.</param> /// <returns>The async task.</returns> protected static async Task WriteFileAsync(HttpContext context, Stream fileStream, RangeItemHeaderValue?range, long rangeLength) { await FileResultHelper.WriteFileAsync(context, fileStream, range, rangeLength); }
protected override Task ExecuteCoreAsync(HttpContext context, RangeItemHeaderValue?range, long rangeLength) { return(FileResultHelper.WriteFileAsync(context, FileStream, range, rangeLength)); }