public async Task WriteFileAsync_PreconditionStateShouldProcess_WritesRangeRequested_IfRangeProcessingOn(long?start, long?end, string expectedString, long contentLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var readStream = new MemoryStream(byteArray); readStream.SetLength(11); var result = new FileStreamResult(readStream, contentType) { LastModified = lastModified, EntityTag = entityTag, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert start = start ?? 11 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal("Hello World", body); } }
public override Task ExecuteResultAsync(ActionContext context) { context.HttpContext.Response.Headers.Add("Accept-Ranges", "items"); context.HttpContext.Response.Headers.Add("Content-Range", _range.ToString()); return(base.ExecuteResultAsync(context)); }
public async Task WriteFileAsync_WritesRangeRequested(long?start, long?end, long contentLength) { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var sendFile = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(start, end); httpContext.Request.Method = HttpMethods.Get; // Act await ExecuteAsync(httpContext, path, "text/plain", enableRangeProcessing : true); // Assert var startResult = start ?? 34 - end; var endResult = startResult + contentLength - 1; var httpResponse = httpContext.Response; var contentRange = new ContentRangeHeaderValue(startResult.Value, endResult.Value, 34); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name); Assert.Equal(startResult, sendFile.Offset); Assert.Equal((long?)contentLength, sendFile.Length); }
public static async Task WriteFileAsync_IfRangeHeaderValid_WritesRangeRequest <TContext>( Func <FileContentResult, TContext, Task> function) { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue; var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag, EnableRangeProcessing = true, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(DateTimeOffset.MinValue); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); if (result.EnableRangeProcessing) { Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(0, 4, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(5, httpResponse.ContentLength); Assert.Equal("Hello", body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(11, httpResponse.ContentLength); Assert.Equal("Hello World", body); } }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange() { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var entityTag = new EntityTagHeaderValue("\"Etag\""); var sendFile = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(0, 3); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; // Act await ExecuteAsync(httpContext, path, "text/plain", entityTag : entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(0, 3, 34); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(4, httpResponse.ContentLength); Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name); Assert.Equal(0, sendFile.Offset); Assert.Equal(4, sendFile.Length); }
public async Task WriteFileAsync_RangeRequestedNotSatisfiable(string rangeString) { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var result = new TestPhysicalFileResult(path, "text/plain"); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; httpContext.Request.Headers[HeaderNames.Range] = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(34); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); Assert.Empty(body); }
public async Task WriteFileAsync_WritesRangeRequested(long?start, long?end, string expectedString, long contentLength) { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var result = new TestPhysicalFileResult(path, "text/plain"); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(start, end); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert start = start ?? 34 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, 34); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); }
public async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestedNotSatisfiable(string rangeString) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var httpContext = GetHttpContext(); httpContext.Request.Headers.Range = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, byteArray, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); }
public async Task WriteFileAsync_RangeRequestedNotSatisfiable(string rangeString) { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; httpContext.Request.Headers.Range = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, path, "text/plain", enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(34); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); }
public static async Task ExecuteResultAsync_CallsSendFileAsyncWithRequestedRange_IfIHttpSendFilePresent <TContext>( long?start, long?end, string expectedString, long contentLength, Func <VirtualFileResult, TContext, Task> function) { // Arrange var path = Path.Combine("TestFiles", "FilePathResultTestFile.txt"); var result = new TestVirtualFileResult(path, "text/plain") { FileProvider = GetFileProvider(path), EnableRangeProcessing = true, }; var sendFile = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); httpContext.RequestServices = new ServiceCollection() .AddSingleton(appEnvironment.Object) .AddTransient <IActionResultExecutor <VirtualFileResult>, TestVirtualFileResultExecutor>() .AddTransient <ILoggerFactory, LoggerFactory>() .BuildServiceProvider(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue.AddDays(1); httpContext.Request.Method = HttpMethods.Get; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object functionContext = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)functionContext); // Assert start = start ?? 33 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; Assert.Equal(Path.Combine("TestFiles", "FilePathResultTestFile.txt"), sendFile.Name); Assert.Equal(start, sendFile.Offset); Assert.Equal(contentLength, sendFile.Length); Assert.Equal(CancellationToken.None, sendFile.Token); var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, 33); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(contentLength, httpResponse.ContentLength); }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRangeRequest_IfRangeProcessingOn() { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue; var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(DateTimeOffset.MinValue); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); var contentRange = new ContentRangeHeaderValue(0, 4, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Equal(5, httpResponse.ContentLength); Assert.Equal("Hello", body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(11, httpResponse.ContentLength); Assert.Equal("Hello World", body); } }
public async Task WriteFileAsync_RangeRequested_FileLengthZeroOrNull(long?fileLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes(""); var readStream = new MemoryStream(byteArray); fileLength = fileLength ?? 0L; readStream.SetLength(fileLength.Value); var result = new FileStreamResult(readStream, contentType) { LastModified = lastModified, EntityTag = entityTag, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(0, 5); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Empty(body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Empty(body); } }
public static async Task WriteFileAsync_PreconditionStateShouldProcess_WritesRangeRequested <TContext>( long?start, long?end, string expectedString, long contentLength, Func <FileContentResult, TContext, Task> function) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag, EnableRangeProcessing = true, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert start = start ?? 11 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); }
public static async Task WriteFileAsync_WritesRangeRequested <TContext>( long?start, long?end, string expectedString, long contentLength, Func <VirtualFileResult, TContext, Task> function) { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var result = new TestVirtualFileResult(path, contentType); result.EnableRangeProcessing = true; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var sendFileFeature = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature); httpContext.RequestServices = new ServiceCollection() .AddSingleton(appEnvironment.Object) .AddTransient <IActionResultExecutor <VirtualFileResult>, TestVirtualFileResultExecutor>() .AddTransient <ILoggerFactory, LoggerFactory>() .BuildServiceProvider(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue.AddDays(1); httpContext.Request.Method = HttpMethods.Get; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var startResult = start ?? 33 - end; var endResult = startResult + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; var contentRange = new ContentRangeHeaderValue(startResult.Value, endResult.Value, 33); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(path, sendFileFeature.Name); Assert.Equal(startResult, sendFileFeature.Offset); Assert.Equal((long?)contentLength, sendFileFeature.Length); }
public static async Task WriteFileAsync_RangeRequestedNotSatisfiable <TContext>( string rangeString, Func <VirtualFileResult, TContext, Task> function) { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var result = new TestVirtualFileResult(path, contentType); result.EnableRangeProcessing = true; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); httpContext.RequestServices = new ServiceCollection() .AddSingleton(appEnvironment.Object) .AddTransient <IActionResultExecutor <VirtualFileResult>, TestVirtualFileResultExecutor>() .AddTransient <ILoggerFactory, LoggerFactory>() .BuildServiceProvider(); var requestHeaders = httpContext.Request.GetTypedHeaders(); httpContext.Request.Headers.Range = rangeString; requestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue.AddDays(1); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(33); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); }
public static async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange <TContext>( Func <VirtualFileResult, TContext, Task> function) { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var result = new TestVirtualFileResult(path, contentType); result.EnableRangeProcessing = true; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var sendFileFeature = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature); httpContext.RequestServices = new ServiceCollection() .AddSingleton(appEnvironment.Object) .AddTransient <IActionResultExecutor <VirtualFileResult>, TestVirtualFileResultExecutor>() .AddTransient <ILoggerFactory, LoggerFactory>() .BuildServiceProvider(); var entityTag = result.EntityTag = new EntityTagHeaderValue("\"Etag\""); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(0, 3); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var httpResponse = actionContext.HttpContext.Response; Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(0, 3, 33); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(4, httpResponse.ContentLength); Assert.Equal(path, sendFileFeature.Name); Assert.Equal(0, sendFileFeature.Offset); Assert.Equal(4, sendFileFeature.Length); }
public void ToString_UseDifferentRanges_AllSerializedCorrectly() { ContentRangeHeaderValue range = new ContentRangeHeaderValue(1, 2, 3); range.Unit = "myunit"; Assert.Equal("myunit 1-2/3", range.ToString()); // "Range with all fields set" range = new ContentRangeHeaderValue(123456789012345678, 123456789012345679); Assert.Equal("bytes 123456789012345678-123456789012345679/*", range.ToString()); // "Only range, no length" range = new ContentRangeHeaderValue(150); Assert.Equal("bytes */150", range.ToString()); // "Only length, no range" }
public void ToString_UseDifferentRanges_AllSerializedCorrectly() { var range = new ContentRangeHeaderValue(1, 2, 3); range.Unit = "myunit"; Assert.Equal("myunit 1-2/3", range.ToString()); range = new ContentRangeHeaderValue(123456789012345678, 123456789012345679); Assert.Equal("bytes 123456789012345678-123456789012345679/*", range.ToString()); range = new ContentRangeHeaderValue(150); Assert.Equal("bytes */150", range.ToString()); }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange() { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var result = new TestVirtualFileResult(path, contentType); result.EnableRangeProcessing = true; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); httpContext.RequestServices = new ServiceCollection() .AddSingleton(appEnvironment.Object) .AddTransient <IActionResultExecutor <VirtualFileResult>, TestVirtualFileResultExecutor>() .AddTransient <ILoggerFactory, LoggerFactory>() .BuildServiceProvider(); var entityTag = result.EntityTag = new EntityTagHeaderValue("\"Etag\""); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(0, 3); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); var contentRange = new ContentRangeHeaderValue(0, 3, 33); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); Assert.Equal(4, httpResponse.ContentLength); Assert.Equal("File", body); }
public async Task WriteFileAsync_WritesRangeRequested(long?start, long?end, string expectedString, long contentLength) { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var result = new TestVirtualFileResult(path, contentType); result.EnableRangeProcessing = true; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); httpContext.RequestServices = new ServiceCollection() .AddSingleton(appEnvironment.Object) .AddTransient <IActionResultExecutor <VirtualFileResult>, TestVirtualFileResultExecutor>() .AddTransient <ILoggerFactory, LoggerFactory>() .BuildServiceProvider(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue.AddDays(1); httpContext.Request.Method = HttpMethods.Get; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert start = start ?? 33 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, 33); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); }
public async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestedNotSatisfiable(string rangeString) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag }; var httpContext = GetHttpContext(); httpContext.Request.Headers[HeaderNames.Range] = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Empty(body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal("Hello World", body); } }
public async Task WriteFileAsync_PreconditionStateShouldProcess_WritesRangeRequested( long?start, long?end, string expectedString, long contentLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, byteArray, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert start = start ?? 11 - end; end = start + contentLength - 1; var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); }
public static async Task ExecuteResultAsync_CallsSendFileAsyncWithRequestedRange_IfIHttpSendFilePresent <TContext>( long?start, long?end, long contentLength, Func <PhysicalFileResult, TContext, Task> function) { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var result = new TestPhysicalFileResult(path, "text/plain"); result.EnableRangeProcessing = true; var sendFile = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue.AddDays(1); httpContext.Request.Method = HttpMethods.Get; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object functionContext = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)functionContext); // Assert start = start ?? 34 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name); Assert.Equal(start, sendFile.Offset); Assert.Equal(contentLength, sendFile.Length); Assert.Equal(CancellationToken.None, sendFile.Token); var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, 34); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(contentLength, httpResponse.ContentLength); }
public static async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestedNotSatisfiable <TContext>( string rangeString, Func <FileContentResult, TContext, Task> function) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag, EnableRangeProcessing = true, }; var httpContext = GetHttpContext(); httpContext.Request.Headers.Range = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); }
public async Task WriteFileAsync_RangeRequested_FileLengthZeroOrNull(long?fileLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes(""); var readStream = new MemoryStream(byteArray); fileLength = fileLength ?? 0L; readStream.SetLength(fileLength.Value); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(0, 5); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, readStream, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); Assert.False(readStream.CanSeek); }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange() { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue; var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var readStream = new MemoryStream(byteArray); readStream.SetLength(11); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, readStream, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); var contentRange = new ContentRangeHeaderValue(0, 4, byteArray.Length); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(5, httpResponse.ContentLength); Assert.Equal("Hello", body); Assert.False(readStream.CanSeek); }
public async Task WriteFileAsync_WritesRangeRequested( long?start, long?end, long contentLength) { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var sendFileFeature = new TestSendFileFeature(); var httpContext = GetHttpContext(GetFileProvider(path)); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue.AddDays(1); httpContext.Request.Method = HttpMethods.Get; // Act await ExecuteAsync(httpContext, path, contentType, enableRangeProcessing : true); // Assert var startResult = start ?? 33 - end; var endResult = startResult + contentLength - 1; var httpResponse = httpContext.Response; var contentRange = new ContentRangeHeaderValue(startResult.Value, endResult.Value, 33); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(path, sendFileFeature.Name); Assert.Equal(startResult, sendFileFeature.Offset); Assert.Equal((long?)contentLength, sendFileFeature.Length); }
public static async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange <TContext>( Func <PhysicalFileResult, TContext, Task> function) { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var result = new TestPhysicalFileResult(path, "text/plain"); var entityTag = result.EntityTag = new EntityTagHeaderValue("\"Etag\""); result.EnableRangeProcessing = true; var sendFile = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(0, 3); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var httpResponse = actionContext.HttpContext.Response; Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(0, 3, 34); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(4, httpResponse.ContentLength); Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name); Assert.Equal(0, sendFile.Offset); Assert.Equal(4, sendFile.Length); }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange() { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var sendFileFeature = new TestSendFileFeature(); var httpContext = GetHttpContext(GetFileProvider(path)); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature); var entityTag = new EntityTagHeaderValue("\"Etag\""); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(0, 3); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; // Act await ExecuteAsync(httpContext, path, contentType, entityTag : entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(0, 3, 33); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(4, httpResponse.ContentLength); Assert.Equal(path, sendFileFeature.Name); Assert.Equal(0, sendFileFeature.Offset); Assert.Equal(4, sendFileFeature.Length); }
public async Task ExecuteResultAsync_CallsSendFileAsyncWithRequestedRange_IfIHttpSendFilePresent(long?start, long?end, long contentLength) { // Arrange var path = Path.Combine("TestFiles", "FilePathResultTestFile.txt"); var sendFile = new TestSendFileFeature(); var httpContext = GetHttpContext(GetFileProvider(path)); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile); var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfUnmodifiedSince = DateTimeOffset.MinValue.AddDays(1); httpContext.Request.Method = HttpMethods.Get; // Act await ExecuteAsync(httpContext, path, "text/plain", enableRangeProcessing : true); // Assert start = start ?? 33 - end; end = start + contentLength - 1; var httpResponse = httpContext.Response; Assert.Equal(Path.Combine("TestFiles", "FilePathResultTestFile.txt"), sendFile.Name); Assert.Equal(start, sendFile.Offset); Assert.Equal(contentLength, sendFile.Length); Assert.Equal(CancellationToken.None, sendFile.Token); var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, 33); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(contentLength, httpResponse.ContentLength); }