Example #1
0
    public async Task ServerShouldReturnETag()
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();

        HttpResponseMessage response = await server.CreateClient().GetAsync("http://localhost/SubFolder/extra.xml");

        Assert.NotNull(response.Headers.ETag);
        Assert.NotNull(response.Headers.ETag.Tag);
    }
Example #2
0
    public async Task SameETagShouldBeReturnedAgain()
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();

        HttpResponseMessage response1 = await server.CreateClient().GetAsync("http://localhost/SubFolder/extra.xml");

        HttpResponseMessage response2 = await server.CreateClient().GetAsync("http://localhost/SubFolder/extra.xml");

        Assert.Equal(response2.Headers.ETag, response1.Headers.ETag);
    }
Example #3
0
    public async Task SingleValidRangeShouldServeRequestedRangeNotSatisfiableEmptyFile(string range)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/Empty.txt");

        req.Headers.Add("Range", "bytes=" + range);
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.RequestedRangeNotSatisfiable, resp.StatusCode);
    }
Example #4
0
    public async Task IfMatchShouldReturn412WhenNotListed(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(method, "http://localhost/SubFolder/extra.xml");

        req.Headers.Add("If-Match", "\"fake\"");
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.PreconditionFailed, resp.StatusCode);
    }
Example #5
0
    public async Task IfMatchShouldBeServedForAsterisk(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(method, "http://localhost/SubFolder/extra.xml");

        req.Headers.Add("If-Match", "*");
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
    }
Example #6
0
    [InlineData("1000-1001")] // Out of range
    public async Task HEADSingleNotSatisfiableRangeReturnsOk(string range)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");

        req.Headers.TryAddWithoutValidation("Range", "bytes=" + range);
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        Assert.Null(resp.Content.Headers.ContentRange);
    }
Example #7
0
    public async Task FutureIfUnmodifiedSinceDateFormatGivesNormalGet(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();

        HttpResponseMessage res = await server
                                  .CreateRequest("/SubFolder/extra.xml")
                                  .And(req => req.Headers.IfUnmodifiedSince = DateTimeOffset.Now.AddYears(1))
                                  .SendAsync(method.Method);

        Assert.Equal(HttpStatusCode.OK, res.StatusCode);
    }
Example #8
0
    public async Task InvalidIfUnmodifiedSinceDateFormatGivesNormalGet(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();

        HttpResponseMessage res = await server
                                  .CreateRequest("/SubFolder/extra.xml")
                                  .AddHeader("If-Unmodified-Since", "bad-date")
                                  .SendAsync(method.Method);

        Assert.Equal(HttpStatusCode.OK, res.StatusCode);
    }
Example #9
0
    public async Task ServerShouldReturnLastModified(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();

        HttpResponseMessage response = await server.CreateClient().SendAsync(
            new HttpRequestMessage(method, "http://localhost/SubFolder/extra.xml"));

        Assert.NotNull(response.Content.Headers.LastModified);
        // Verify that DateTimeOffset is UTC
        Assert.Equal(response.Content.Headers.LastModified.Value.Offset, TimeSpan.Zero);
    }
Example #10
0
    public async Task IfNoneMatchAllShouldReturn304ForMatching(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        HttpResponseMessage resp1 = await server.CreateClient().GetAsync("http://localhost/SubFolder/extra.xml");

        var req2 = new HttpRequestMessage(method, "http://localhost/SubFolder/extra.xml");

        req2.Headers.Add("If-None-Match", "*");
        HttpResponseMessage resp2 = await server.CreateClient().SendAsync(req2);

        Assert.Equal(HttpStatusCode.NotModified, resp2.StatusCode);
    }
Example #11
0
    public async Task IfNoneMatchShouldBeIgnoredForNonTwoHundredAnd304Responses(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        HttpResponseMessage resp1 = await server.CreateClient().GetAsync("http://localhost/SubFolder/extra.xml");

        var req2 = new HttpRequestMessage(method, "http://localhost/SubFolder/extra.xml");

        req2.Headers.Add("If-None-Match", resp1.Headers.ETag.ToString());
        HttpResponseMessage resp2 = await server.CreateClient().SendAsync(req2);

        Assert.Equal(HttpStatusCode.NotFound, resp2.StatusCode);
    }
Example #12
0
    [InlineData("2-2,0-0")] // SHOULD send in the requested order.
    public async Task HEADMultipleValidRangesShouldServeFullContent(string range)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");

        req.Headers.Add("Range", "bytes=" + range);
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        Assert.Equal("text/plain", resp.Content.Headers.ContentType.ToString());
        Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
    }
Example #13
0
    public async Task IfModifiedSinceWithCurrentDateShouldReturn304()
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");

        var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");

        req.Headers.Add("If-Modified-Since", original.Content.Headers.LastModified.Value.ToString("r"));
        req.Headers.Add("Range", "bytes=0-10");
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.NotModified, resp.StatusCode);
    }
Example #14
0
    public async Task SingleInvalidRangeIgnored(string range)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");

        req.Headers.TryAddWithoutValidation("Range", "bytes=" + range);
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        Assert.Null(resp.Content.Headers.ContentRange);
        Assert.Equal(62, resp.Content.Headers.ContentLength);
        Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
    }
Example #15
0
    public async Task HEADIfRangeWithOldEtagShouldServeFullContent()
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");

        req.Headers.Add("If-Range", "\"OldEtag\"");
        req.Headers.Add("Range", "bytes=0-10");
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        Assert.Null(resp.Content.Headers.ContentRange);
        Assert.Equal(62, resp.Content.Headers.ContentLength);
        Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
    }
    public async Task NullArguments()
    {
        // No exception, default provided
        using (await StaticFilesTestServer.Create(app => app.UseDefaultFiles(new DefaultFilesOptions {
            FileProvider = null
        })))
        { }

        // PathString(null) is OK.
        using var host = await StaticFilesTestServer.Create(app => app.UseDefaultFiles((string)null));

        using var server = host.GetTestServer();
        var response = await server.CreateClient().GetAsync("/");

        Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
    }
Example #17
0
    public async Task SingleValidRangeShouldServePartialContentSingleByteFile(string range, string expectedRange, int length, string expectedData)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/SingleByte.txt");

        req.Headers.Add("Range", "bytes=" + range);
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.PartialContent, resp.StatusCode);
        Assert.NotNull(resp.Content.Headers.ContentRange);
        Assert.Equal("bytes " + expectedRange + "/1", resp.Content.Headers.ContentRange.ToString());
        Assert.Equal(length, resp.Content.Headers.ContentLength);
        Assert.Equal(expectedData, await resp.Content.ReadAsStringAsync());
    }
Example #18
0
    public async Task IfRangeWithOldEtagShouldServeFullContent()
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");

        req.Headers.Add("If-Range", "\"OldEtag\"");
        req.Headers.Add("Range", "bytes=0-10");
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        Assert.Null(resp.Content.Headers.ContentRange);
        Assert.Equal(62, resp.Content.Headers.ContentLength);
        Assert.Equal("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", await resp.Content.ReadAsStringAsync());
    }
    private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
    {
        using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
        {
            using var host = await StaticFilesTestServer.Create(app => app.UseDefaultFiles(new DefaultFilesOptions
            {
                RequestPath  = new PathString(baseUrl),
                FileProvider = fileProvider,
                RedirectToAppendTrailingSlash = appendTrailingSlash
            }));

            using var server = host.GetTestServer();
            var response = await server.CreateRequest(requestUrl).GetAsync();

            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); // Passed through
        }
    }
Example #20
0
    public async Task MatchingBothConditionsReturnsNotModified(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        HttpResponseMessage resp1 = await server
                                    .CreateRequest("/SubFolder/extra.xml")
                                    .SendAsync(method.Method);

        HttpResponseMessage resp2 = await server
                                    .CreateRequest("/SubFolder/extra.xml")
                                    .AddHeader("If-None-Match", resp1.Headers.ETag.ToString())
                                    .And(req => req.Headers.IfModifiedSince = resp1.Content.Headers.LastModified)
                                    .SendAsync(method.Method);

        Assert.Equal(HttpStatusCode.NotModified, resp2.StatusCode);
    }
Example #21
0
    public async Task IfUnmodifiedSinceDateLessThanLastModifiedShouldReturn412(HttpMethod method)
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();

        HttpResponseMessage res1 = await server
                                   .CreateRequest("/SubFolder/extra.xml")
                                   .SendAsync(method.Method);

        HttpResponseMessage res2 = await server
                                   .CreateRequest("/SubFolder/extra.xml")
                                   .And(req => req.Headers.IfUnmodifiedSince = DateTimeOffset.MinValue)
                                   .SendAsync(method.Method);

        Assert.Equal(HttpStatusCode.PreconditionFailed, res2.StatusCode);
    }
    private async Task PassesThrough(string method, string baseUrl, string baseDir, string requestUrl)
    {
        using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
        {
            using var host = await StaticFilesTestServer.Create(app => app.UseStaticFiles(new StaticFileOptions
            {
                RequestPath  = new PathString(baseUrl),
                FileProvider = fileProvider
            }));

            using var server = host.GetTestServer();
            var response = await server.CreateRequest(requestUrl).SendAsync(method);

            Assert.Null(response.Content.Headers.LastModified);
            Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
        }
    }
Example #23
0
    public async Task IfModifiedSinceWithPastDateShouldServePartialContent()
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");

        var req = new HttpRequestMessage(HttpMethod.Get, "http://localhost/SubFolder/ranges.txt");

        req.Headers.Add("If-Modified-Since", original.Content.Headers.LastModified.Value.AddHours(-1).ToString("r"));
        req.Headers.Add("Range", "bytes=0-10");
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.PartialContent, resp.StatusCode);
        Assert.Equal("bytes 0-10/62", resp.Content.Headers.ContentRange.ToString());
        Assert.Equal(11, resp.Content.Headers.ContentLength);
        Assert.Equal("0123456789a", await resp.Content.ReadAsStringAsync());
    }
Example #24
0
    public async Task HEADIfRangeWithOldDateShouldServeFullContent()
    {
        using var host = await StaticFilesTestServer.Create(app => app.UseFileServer());

        using var server = host.GetTestServer();
        HttpResponseMessage original = await server.CreateClient().GetAsync("http://localhost/SubFolder/ranges.txt");

        var req = new HttpRequestMessage(HttpMethod.Head, "http://localhost/SubFolder/ranges.txt");

        req.Headers.Add("If-Range", original.Content.Headers.LastModified.Value.Subtract(TimeSpan.FromDays(1)).ToString("r"));
        req.Headers.Add("Range", "bytes=0-10");
        HttpResponseMessage resp = await server.CreateClient().SendAsync(req);

        Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        Assert.Null(resp.Content.Headers.ContentRange);
        Assert.Equal(62, resp.Content.Headers.ContentLength);
        Assert.Equal(string.Empty, await resp.Content.ReadAsStringAsync());
    }
    public async Task Endpoint_With_RequestDelegate_PassesThrough()
    {
        using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, ".")))
        {
            using var host = await StaticFilesTestServer.Create(
                      app =>
            {
                app.UseRouting();

                app.Use(next => context =>
                {
                    // Assign an endpoint, this will make the default files noop.
                    context.SetEndpoint(new Endpoint((c) =>
                    {
                        return(context.Response.WriteAsync(context.Request.Path.Value));
                    },
                                                     new EndpointMetadataCollection(),
                                                     "test"));

                    return(next(context));
                });

                app.UseDefaultFiles(new DefaultFilesOptions
                {
                    RequestPath  = new PathString(""),
                    FileProvider = fileProvider
                });

                app.UseEndpoints(endpoints => { });

                // Echo back the current request path value
                app.Run(context => context.Response.WriteAsync(context.Request.Path.Value));
            },
                      services => { services.AddDirectoryBrowser(); services.AddRouting(); });

            using var server = host.GetTestServer();

            var response = await server.CreateRequest("/SubFolder/").GetAsync();

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal("/SubFolder/", await response.Content.ReadAsStringAsync()); // Should not be modified
        }
    }
    public async Task FoundFile_LastModifiedTrimsSeconds()
    {
        using (var fileProvider = new PhysicalFileProvider(AppContext.BaseDirectory))
        {
            using var host = await StaticFilesTestServer.Create(app => app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = fileProvider
            }));

            using var server = host.GetTestServer();
            var fileInfo = fileProvider.GetFileInfo("TestDocument.txt");
            var response = await server.CreateRequest("TestDocument.txt").GetAsync();

            var last    = fileInfo.LastModified;
            var trimmed = new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, last.Offset).ToUniversalTime();

            Assert.Equal(response.Content.Headers.LastModified.Value, trimmed);
        }
    }
    public async Task HeadFile_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl)
    {
        using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
        {
            using var host = await StaticFilesTestServer.Create(app => app.UseStaticFiles(new StaticFileOptions
            {
                RequestPath  = new PathString(baseUrl),
                FileProvider = fileProvider
            }));

            using var server = host.GetTestServer();
            var fileInfo = fileProvider.GetFileInfo(Path.GetFileName(requestUrl));
            var response = await server.CreateRequest(requestUrl).SendAsync("HEAD");

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal("text/plain", response.Content.Headers.ContentType.ToString());
            Assert.True(response.Content.Headers.ContentLength == fileInfo.Length);
            Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
        }
    }
    private async Task NearMatch_RedirectAddSlash(string baseUrl, string baseDir, string requestUrl, string queryString)
    {
        using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
        {
            using var host = await StaticFilesTestServer.Create(app => app.UseDefaultFiles(new DefaultFilesOptions
            {
                RequestPath  = new PathString(baseUrl),
                FileProvider = fileProvider
            }));

            using var server = host.GetTestServer();
            var response = await server.CreateRequest(requestUrl + queryString).GetAsync();

            Assert.Equal(HttpStatusCode.Moved, response.StatusCode);
            // the url in the header of `Location: /xxx/xxx` should be encoded
            var actualURL = response.Headers.GetValues("Location").FirstOrDefault();
            Assert.Equal("http://localhost" + baseUrl + new PathString(requestUrl + "/") + queryString, actualURL);
            Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
        }
    }
    public async Task File_Served_If_Endpoint_With_Null_RequestDelegate_Is_Active()
    {
        using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, ".")))
        {
            using var host = await StaticFilesTestServer.Create(app =>
            {
                app.UseRouting();
                app.Use((ctx, next) =>
                {
                    ctx.SetEndpoint(new Endpoint(requestDelegate: null, new EndpointMetadataCollection(), "NullRequestDelegateEndpoint"));
                    return(next());
                });
                app.UseStaticFiles(new StaticFileOptions
                {
                    RequestPath  = new PathString(),
                    FileProvider = fileProvider
                });
                app.UseEndpoints(endpoints => { });
            }, services => services.AddRouting());

            using var server = host.GetTestServer();
            var requestUrl = "/TestDocument.txt";
            var fileInfo   = fileProvider.GetFileInfo(Path.GetFileName(requestUrl));
            var response   = await server.CreateRequest(requestUrl).GetAsync();

            var responseContent = await response.Content.ReadAsByteArrayAsync();

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal("text/plain", response.Content.Headers.ContentType.ToString());
            Assert.True(response.Content.Headers.ContentLength == fileInfo.Length);
            Assert.Equal(response.Content.Headers.ContentLength, responseContent.Length);
            Assert.NotNull(response.Headers.ETag);

            using (var stream = fileInfo.CreateReadStream())
            {
                var fileContents = new byte[stream.Length];
                stream.Read(fileContents, 0, (int)stream.Length);
                Assert.True(responseContent.SequenceEqual(fileContents));
            }
        }
    }
Example #30
0
    public async Task Endpoint_With_RequestDelegate_PassesThrough()
    {
        using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, ".")))
        {
            using var host = await StaticFilesTestServer.Create(
                      app =>
            {
                app.UseRouting();

                app.Use(next => context =>
                {
                    // Assign an endpoint, this will make the directory browser noop
                    context.SetEndpoint(new Endpoint((c) =>
                    {
                        c.Response.StatusCode = (int)HttpStatusCode.NotAcceptable;
                        return(c.Response.WriteAsync("Hi from endpoint."));
                    },
                                                     new EndpointMetadataCollection(),
                                                     "test"));

                    return(next(context));
                });

                app.UseDirectoryBrowser(new DirectoryBrowserOptions
                {
                    RequestPath  = new PathString(""),
                    FileProvider = fileProvider
                });

                app.UseEndpoints(endpoints => { });
            },
                      services => { services.AddDirectoryBrowser(); services.AddRouting(); });

            using var server = host.GetTestServer();

            var response = await server.CreateRequest("/").GetAsync();

            Assert.Equal(HttpStatusCode.NotAcceptable, response.StatusCode);
            Assert.Equal("Hi from endpoint.", await response.Content.ReadAsStringAsync());
        }
    }