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_IfRangeHeaderInvalid_RangeRequestedIgnored()
        {
            // Arrange
            var path   = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt"));
            var result = new TestPhysicalFileResult(path, "text/plain");

            result.EnableRangeProcessing = true;
            var entityTag   = result.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("\"NotEtag\""));
            httpContext.Request.Method     = HttpMethods.Get;
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            await result.ExecuteResultAsync(actionContext);

            // Assert
            var httpResponse = actionContext.HttpContext.Response;

            Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode);
            Assert.NotEmpty(httpResponse.Headers[HeaderNames.LastModified]);
            Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name);
            Assert.Equal(0, sendFile.Offset);
            Assert.Null(sendFile.Length);
        }
        public async Task ExecuteResultAsync_FallsBackToWebRootFileProvider_IfNoFileProviderIsPresent()
        {
            // Arrange
            var path   = Path.Combine("TestFiles", "FilePathResultTestFile.txt");
            var result = new TestVirtualFileResult(path, "text/plain");

            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 context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            await result.ExecuteResultAsync(context);

            // Assert
            Assert.Equal(path, sendFileFeature.Name);
            Assert.Equal(0, sendFileFeature.Offset);
            Assert.Null(sendFileFeature.Length);
        }
示例#4
0
    public async Task WriteFileAsync_RangeRequested_NotModified()
    {
        // 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.IfModifiedSince    = DateTimeOffset.MinValue.AddDays(1);
        httpContext.Request.Headers.Range = "bytes = 0-6";
        httpContext.Request.Method        = HttpMethods.Get;

        // Act
        await ExecuteAsync(httpContext, path, contentType, enableRangeProcessing : true);

        // Assert
        var httpResponse = httpContext.Response;

        Assert.Equal(StatusCodes.Status304NotModified, httpResponse.StatusCode);
        Assert.Null(httpResponse.ContentLength);
        Assert.Empty(httpResponse.Headers.ContentRange);
        Assert.NotEmpty(httpResponse.Headers.LastModified);
        Assert.False(httpResponse.Headers.ContainsKey(HeaderNames.ContentType));
        Assert.Null(sendFileFeature.Name); // Not called
    }
    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_RangeHeaderMalformed_RangeRequestIgnored <TContext>(
            string rangeString,
            Func <PhysicalFileResult, TContext, Task> function)
        {
            // Arrange
            var path        = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt"));
            var result      = new TestPhysicalFileResult(path, "text/plain");
            var sendFile    = new TestSendFileFeature();
            var httpContext = GetHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile);
            var requestHeaders = httpContext.Request.GetTypedHeaders();

            requestHeaders.IfModifiedSince    = DateTimeOffset.MinValue;
            httpContext.Request.Headers.Range = rangeString;
            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.Status200OK, httpResponse.StatusCode);
            Assert.Empty(httpResponse.Headers.ContentRange);
            Assert.NotEmpty(httpResponse.Headers.LastModified);
            Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name);
            Assert.Equal(0, sendFile.Offset);
            Assert.Null(sendFile.Length);
        }
        public static async Task ExecuteResultAsync_WorksWithAbsolutePaths <TContext>(
            Func <PhysicalFileResult, TContext, Task> function)
        {
            // Arrange
            var path   = Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile.txt"));
            var result = new TestPhysicalFileResult(path, "text/plain");

            var sendFile    = new TestSendFileFeature();
            var httpContext = GetHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile);

            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext;

            await function(result, (TContext)context);

            // Assert
            Assert.Equal(Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile.txt")), sendFile.Name);
            Assert.Equal(0, sendFile.Offset);
            Assert.Null(sendFile.Length);
            Assert.Equal(CancellationToken.None, sendFile.Token);
        }
示例#8
0
        public static async Task ExecuteResultAsync_SetsSuppliedContentTypeAndEncoding <TContext>(
            Func <VirtualFileResult, TContext, Task> function)
        {
            // Arrange
            var expectedContentType = "text/foo; charset=us-ascii";
            var result = new TestVirtualFileResult(
                "FilePathResultTestFile_ASCII.txt", expectedContentType)
            {
                FileProvider = GetFileProvider("FilePathResultTestFile_ASCII.txt"),
            };

            var sendFileFeature = new TestSendFileFeature();
            var httpContext     = GetHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext;

            await function(result, (TContext)context);

            // Assert
            Assert.Equal(expectedContentType, httpContext.Response.ContentType);
            Assert.Equal("FilePathResultTestFile_ASCII.txt", sendFileFeature.Name);
        }
        public static async Task ExecuteResultAsync_SetsSuppliedContentTypeAndEncoding <TContext>(
            Func <PhysicalFileResult, TContext, Task> function)
        {
            // Arrange
            var expectedContentType = "text/foo; charset=us-ascii";
            var path        = Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile_ASCII.txt"));
            var result      = new TestPhysicalFileResult(path, expectedContentType);
            var sendFile    = new TestSendFileFeature();
            var httpContext = GetHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile);
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext;

            await function(result, (TContext)context);

            // Assert
            Assert.Equal(expectedContentType, httpContext.Response.ContentType);
            Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile_ASCII.txt")), sendFile.Name);
            Assert.Equal(0, sendFile.Offset);
            Assert.Null(sendFile.Length);
            Assert.Equal(CancellationToken.None, sendFile.Token);
        }
示例#10
0
    public async Task WriteFileAsync_IfRangeHeaderInvalid_RangeRequestedIgnored()
    {
        // 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("\"NotEtag\""));
        httpContext.Request.Method     = HttpMethods.Get;

        // Act
        await ExecuteAsync(httpContext, path, contentType, entityTag : entityTag, enableRangeProcessing : true);

        // Assert
        var httpResponse = httpContext.Response;

        Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode);
        Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag);
        Assert.Equal(path, sendFileFeature.Name);
        Assert.Equal(0, sendFileFeature.Offset);
        Assert.Null(sendFileFeature.Length);
    }
    public async Task WriteFileAsync_RangeHeaderMalformed_RangeRequestIgnored(string rangeString)
    {
        // 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;
        httpContext.Request.Headers.Range = rangeString;
        httpContext.Request.Method        = HttpMethods.Get;

        // Act
        await ExecuteAsync(httpContext, path, "text/plain");

        // Assert
        var httpResponse = httpContext.Response;

        Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode);
        Assert.Empty(httpResponse.Headers.ContentRange);
        Assert.NotEmpty(httpResponse.Headers.LastModified);
        Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name);
        Assert.Equal(0, sendFile.Offset);
        Assert.Null(sendFile.Length);
    }
示例#12
0
        public static async Task ExecuteResultAsync_TrimsTilde_BeforeInvokingFileProvider <TContext>(
            string path,
            Func <VirtualFileResult, TContext, Task> function)
        {
            // Arrange
            var expectedPath = path.Substring(1);
            var result       = new TestVirtualFileResult(path, "text/plain")
            {
                FileProvider = GetFileProvider(expectedPath),
            };

            var sendFileFeature = new TestSendFileFeature();
            var httpContext     = GetHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);

            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext;

            await function(result, (TContext)context);

            // Assert
            Mock.Get(result.FileProvider).Verify();
            Assert.Equal(expectedPath, sendFileFeature.Name);
        }
    public async Task WriteFileAsync_RangeProcessingNotEnabled_RangeRequestedIgnored()
    {
        // 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);

        // Assert
        var httpResponse = httpContext.Response;

        Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode);
        Assert.NotEmpty(httpResponse.Headers.LastModified);
        Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name);
        Assert.Equal(0, sendFile.Offset);
        Assert.Null(sendFile.Length);
    }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
    public async Task ExecuteResultAsync_ReturnsFiles_ForDifferentPaths(string path)
    {
        // Arrange
        var sendFileFeature     = new TestSendFileFeature();
        var webRootFileProvider = GetFileProvider(path);
        var httpContext         = GetHttpContext(webRootFileProvider);

        httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);

        // Act
        await ExecuteAsync(httpContext, path, "text/plain");

        // Assert
        Mock.Get(webRootFileProvider).Verify();
        Assert.Equal(path, sendFileFeature.Name);
    }
示例#18
0
    public async Task ExecuteResultAsync_ReturnsFileContentsForRelativePaths()
    {
        // Arrange
        var path = Path.Combine("TestFiles", "FilePathResultTestFile.txt");

        var sendFileFeature = new TestSendFileFeature();
        var httpContext     = GetHttpContext(GetFileProvider(path));

        httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);

        // Act
        await ExecuteAsync(httpContext, path, "text/plain");

        // Assert
        Assert.Equal(path, sendFileFeature.Name);
    }
示例#19
0
        public static async Task WriteFileAsync_RangeRequested_NotModified <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 requestHeaders = httpContext.Request.GetTypedHeaders();

            requestHeaders.IfModifiedSince    = DateTimeOffset.MinValue.AddDays(1);
            httpContext.Request.Headers.Range = "bytes = 0-6";
            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.Status304NotModified, httpResponse.StatusCode);
            Assert.Null(httpResponse.ContentLength);
            Assert.Empty(httpResponse.Headers.ContentRange);
            Assert.NotEmpty(httpResponse.Headers.LastModified);
            Assert.False(httpResponse.Headers.ContainsKey(HeaderNames.ContentType));
            Assert.Null(sendFileFeature.Name); // Not called
        }
示例#20
0
    public async Task ExecuteResultAsync_TrimsTilde_BeforeInvokingFileProvider(string path)
    {
        // Arrange
        var expectedPath        = path.Substring(1);
        var sendFileFeature     = new TestSendFileFeature();
        var webRootFileProvider = GetFileProvider(expectedPath);
        var httpContext         = GetHttpContext(webRootFileProvider);

        httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);

        // Act
        await ExecuteAsync(httpContext, path, "text/plain");

        // Assert
        Mock.Get(webRootFileProvider).Verify();
        Assert.Equal(expectedPath, sendFileFeature.Name);
    }
示例#21
0
    public async Task ExecuteResultAsync_SetsSuppliedContentTypeAndEncoding()
    {
        // Arrange
        var expectedContentType = "text/foo; charset=us-ascii";

        var sendFileFeature = new TestSendFileFeature();
        var httpContext     = GetHttpContext(GetFileProvider("FilePathResultTestFile_ASCII.txt"));

        httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);

        // Act
        await ExecuteAsync(httpContext, "FilePathResultTestFile_ASCII.txt", expectedContentType);

        // Assert
        Assert.Equal(expectedContentType, httpContext.Response.ContentType);
        Assert.Equal("FilePathResultTestFile_ASCII.txt", sendFileFeature.Name);
    }
        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 async Task WriteFileAsync_IfRangeHeaderInvalid_RangeRequestedIgnored()
        {
            // 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("\"NotEtag\""));
            httpContext.Request.Method     = HttpMethods.Get;
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            await result.ExecuteResultAsync(actionContext);

            // Assert
            var httpResponse = actionContext.HttpContext.Response;

            Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode);
            Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]);
            Assert.Equal(path, sendFileFeature.Name);
            Assert.Equal(0, sendFileFeature.Offset);
            Assert.Null(sendFileFeature.Length);
        }
    public async Task ExecuteResultAsync_WorksWithAbsolutePaths()
    {
        // Arrange
        var path = Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile.txt"));

        var sendFile    = new TestSendFileFeature();
        var httpContext = GetHttpContext();

        httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile);

        // Act
        await ExecuteAsync(httpContext, path, "text/plain");

        // Assert
        Assert.Equal(Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile.txt")), sendFile.Name);
        Assert.Equal(0, sendFile.Offset);
        Assert.Null(sendFile.Length);
        Assert.Equal(CancellationToken.None, sendFile.Token);
    }
示例#25
0
    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 async Task ExecuteResultAsync_SetsSuppliedContentTypeAndEncoding()
    {
        // Arrange
        var expectedContentType = "text/foo; charset=us-ascii";
        var path        = Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile_ASCII.txt"));
        var sendFile    = new TestSendFileFeature();
        var httpContext = GetHttpContext();

        httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile);

        // Act
        await ExecuteAsync(httpContext, path, expectedContentType);

        // Assert
        Assert.Equal(expectedContentType, httpContext.Response.ContentType);
        Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile_ASCII.txt")), sendFile.Name);
        Assert.Equal(0, sendFile.Offset);
        Assert.Null(sendFile.Length);
        Assert.Equal(CancellationToken.None, sendFile.Token);
    }
        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 ExecuteResultAsync_ReturnsFileContentsForRelativePaths()
        {
            // Arrange
            var path   = Path.Combine("TestFiles", "FilePathResultTestFile.txt");
            var result = new TestVirtualFileResult(path, "text/plain")
            {
                FileProvider = GetFileProvider(path),
            };

            var sendFileFeature = new TestSendFileFeature();
            var httpContext     = GetHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);
            var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            await result.ExecuteResultAsync(context);

            // Assert
            Assert.Equal(path, sendFileFeature.Name);
        }
示例#29
0
    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);
    }
        public async Task ExecuteResultAsync_ReturnsFiles_ForDifferentPaths(string path)
        {
            // Arrange
            var result = new TestVirtualFileResult(path, "text/plain")
            {
                FileProvider = GetFileProvider(path),
            };

            var sendFileFeature = new TestSendFileFeature();
            var httpContext     = GetHttpContext();

            httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature);

            var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            // Act
            await result.ExecuteResultAsync(context);

            // Assert
            Mock.Get(result.FileProvider).Verify();
            Assert.Equal(path, sendFileFeature.Name);
        }