Middlewares affected: - DefaultFilesMiddleware - DirectoryBrowserMiddleware
This commit is contained in:
parent
1bff37bec1
commit
c703093346
|
|
@ -120,12 +120,14 @@ namespace Microsoft.AspNetCore.StaticFiles.Infrastructure
|
||||||
{
|
{
|
||||||
public SharedOptions() { }
|
public SharedOptions() { }
|
||||||
public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||||
|
public bool RedirectToAppendTrailingSlash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||||
public Microsoft.AspNetCore.Http.PathString RequestPath { get { throw null; } set { } }
|
public Microsoft.AspNetCore.Http.PathString RequestPath { get { throw null; } set { } }
|
||||||
}
|
}
|
||||||
public abstract partial class SharedOptionsBase
|
public abstract partial class SharedOptionsBase
|
||||||
{
|
{
|
||||||
protected SharedOptionsBase(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions sharedOptions) { }
|
protected SharedOptionsBase(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions sharedOptions) { }
|
||||||
public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { get { throw null; } set { } }
|
public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { get { throw null; } set { } }
|
||||||
|
public bool RedirectToAppendTrailingSlash { get { throw null; } set { } }
|
||||||
public Microsoft.AspNetCore.Http.PathString RequestPath { get { throw null; } set { } }
|
public Microsoft.AspNetCore.Http.PathString RequestPath { get { throw null; } set { } }
|
||||||
protected Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions SharedOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
protected Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions SharedOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,17 +80,13 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
{
|
{
|
||||||
// If the path matches a directory but does not end in a slash, redirect to add the slash.
|
// If the path matches a directory but does not end in a slash, redirect to add the slash.
|
||||||
// This prevents relative links from breaking.
|
// This prevents relative links from breaking.
|
||||||
if (!Helpers.PathEndsInSlash(context.Request.Path))
|
if (!Helpers.PathEndsInSlash(context.Request.Path) && _options.RedirectToAppendTrailingSlash)
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = StatusCodes.Status301MovedPermanently;
|
Helpers.RedirectToPathWithSlash(context);
|
||||||
var request = context.Request;
|
|
||||||
var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString);
|
|
||||||
context.Response.Headers[HeaderNames.Location] = redirect;
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match found, re-write the url. A later middleware will actually serve the file.
|
// Match found, re-write the url. A later middleware will actually serve the file.
|
||||||
context.Request.Path = new PathString(context.Request.Path.Value + defaultFile);
|
context.Request.Path = new PathString(Helpers.GetPathValueWithSlash(context.Request.Path) + defaultFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,12 +87,9 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
{
|
{
|
||||||
// If the path matches a directory but does not end in a slash, redirect to add the slash.
|
// If the path matches a directory but does not end in a slash, redirect to add the slash.
|
||||||
// This prevents relative links from breaking.
|
// This prevents relative links from breaking.
|
||||||
if (!Helpers.PathEndsInSlash(context.Request.Path))
|
if (!Helpers.PathEndsInSlash(context.Request.Path) && _options.RedirectToAppendTrailingSlash)
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = StatusCodes.Status301MovedPermanently;
|
Helpers.RedirectToPathWithSlash(context);
|
||||||
var request = context.Request;
|
|
||||||
var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString);
|
|
||||||
context.Response.Headers[HeaderNames.Location] = redirect;
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,12 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.StaticFiles
|
namespace Microsoft.AspNetCore.StaticFiles
|
||||||
{
|
{
|
||||||
|
|
@ -12,7 +15,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
{
|
{
|
||||||
internal static IFileProvider ResolveFileProvider(IWebHostEnvironment hostingEnv)
|
internal static IFileProvider ResolveFileProvider(IWebHostEnvironment hostingEnv)
|
||||||
{
|
{
|
||||||
if (hostingEnv.WebRootFileProvider == null) {
|
if (hostingEnv.WebRootFileProvider == null)
|
||||||
|
{
|
||||||
throw new InvalidOperationException("Missing FileProvider.");
|
throw new InvalidOperationException("Missing FileProvider.");
|
||||||
}
|
}
|
||||||
return hostingEnv.WebRootFileProvider;
|
return hostingEnv.WebRootFileProvider;
|
||||||
|
|
@ -28,6 +32,23 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
return path.Value.EndsWith("/", StringComparison.Ordinal);
|
return path.Value.EndsWith("/", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static string GetPathValueWithSlash(PathString path)
|
||||||
|
{
|
||||||
|
if (!PathEndsInSlash(path))
|
||||||
|
{
|
||||||
|
return path.Value + "/";
|
||||||
|
}
|
||||||
|
return path.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void RedirectToPathWithSlash(HttpContext context)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = StatusCodes.Status301MovedPermanently;
|
||||||
|
var request = context.Request;
|
||||||
|
var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString);
|
||||||
|
context.Response.Headers[HeaderNames.Location] = redirect;
|
||||||
|
}
|
||||||
|
|
||||||
internal static bool TryMatchPath(HttpContext context, PathString matchUrl, bool forDirectory, out PathString subpath)
|
internal static bool TryMatchPath(HttpContext context, PathString matchUrl, bool forDirectory, out PathString subpath)
|
||||||
{
|
{
|
||||||
var path = context.Request.Path;
|
var path = context.Request.Path;
|
||||||
|
|
|
||||||
|
|
@ -42,5 +42,10 @@ namespace Microsoft.AspNetCore.StaticFiles.Infrastructure
|
||||||
/// The file system used to locate resources
|
/// The file system used to locate resources
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IFileProvider FileProvider { get; set; }
|
public IFileProvider FileProvider { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether to redirect to add a trailing slash at the end of path. Relative resource links may require this.
|
||||||
|
/// </summary>
|
||||||
|
public bool RedirectToAppendTrailingSlash { get; set; } = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,5 +48,14 @@ namespace Microsoft.AspNetCore.StaticFiles.Infrastructure
|
||||||
get { return SharedOptions.FileProvider; }
|
get { return SharedOptions.FileProvider; }
|
||||||
set { SharedOptions.FileProvider = value; }
|
set { SharedOptions.FileProvider = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether to redirect to add a trailing slash at the end of path. Relative resource links may require this.
|
||||||
|
/// </summary>
|
||||||
|
public bool RedirectToAppendTrailingSlash
|
||||||
|
{
|
||||||
|
get { return SharedOptions.RedirectToAppendTrailingSlash; }
|
||||||
|
set { SharedOptions.RedirectToAppendTrailingSlash = value; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,14 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("/subdir", @".", "/subdir/missing.dir")]
|
[InlineData("/subdir", @".", "/subdir/missing.dir")]
|
||||||
[InlineData("/subdir", @".", "/subdir/missing.dir/")]
|
[InlineData("/subdir", @".", "/subdir/missing.dir/")]
|
||||||
[InlineData("", @"./", "/missing.dir")]
|
[InlineData("", @"./", "/missing.dir")]
|
||||||
public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".", "/missing.dir", false)]
|
||||||
|
[InlineData("", @".", "/missing.dir/", false)]
|
||||||
|
[InlineData("/subdir", @".", "/subdir/missing.dir", false)]
|
||||||
|
[InlineData("/subdir", @".", "/subdir/missing.dir/", false)]
|
||||||
|
[InlineData("", @"./", "/missing.dir", false)]
|
||||||
|
public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl);
|
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
|
@ -48,12 +53,14 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||||
[InlineData("", @".\", "/missing.dir")]
|
[InlineData("", @".\", "/missing.dir")]
|
||||||
[InlineData("", @".\", "/Missing.dir")]
|
[InlineData("", @".\", "/Missing.dir")]
|
||||||
public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".\", "/missing.dir", false)]
|
||||||
|
[InlineData("", @".\", "/Missing.dir", false)]
|
||||||
|
public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl);
|
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl)
|
private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
||||||
{
|
{
|
||||||
|
|
@ -62,7 +69,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
app.UseDefaultFiles(new DefaultFilesOptions
|
app.UseDefaultFiles(new DefaultFilesOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(baseUrl),
|
RequestPath = new PathString(baseUrl),
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider,
|
||||||
|
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||||
});
|
});
|
||||||
app.Run(context => context.Response.WriteAsync(context.Request.Path.Value));
|
app.Run(context => context.Response.WriteAsync(context.Request.Path.Value));
|
||||||
});
|
});
|
||||||
|
|
@ -102,7 +110,7 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseEndpoints(endpoints => {});
|
app.UseEndpoints(endpoints => { });
|
||||||
},
|
},
|
||||||
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
||||||
|
|
||||||
|
|
@ -118,9 +126,19 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("", @"./SubFolder", "/")]
|
[InlineData("", @"./SubFolder", "/")]
|
||||||
[InlineData("", @"./SubFolder", "/你好/")]
|
[InlineData("", @"./SubFolder", "/你好/")]
|
||||||
[InlineData("", @"./SubFolder", "/你好/世界/")]
|
[InlineData("", @"./SubFolder", "/你好/世界/")]
|
||||||
public async Task FoundDirectoryWithDefaultFile_PathModified_All(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".", "/SubFolder/", false)]
|
||||||
|
[InlineData("", @"./", "/SubFolder/", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "/", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "/你好/", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "/你好/世界/", false)]
|
||||||
|
[InlineData("", @".", "/SubFolder", false)]
|
||||||
|
[InlineData("", @"./", "/SubFolder", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "/你好", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "/你好/世界", false)]
|
||||||
|
public async Task FoundDirectoryWithDefaultFile_PathModified_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl);
|
await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
|
@ -130,12 +148,20 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("", @".\subFolder", "/")]
|
[InlineData("", @".\subFolder", "/")]
|
||||||
[InlineData("", @".\SubFolder", "/你好/")]
|
[InlineData("", @".\SubFolder", "/你好/")]
|
||||||
[InlineData("", @".\SubFolder", "/你好/世界/")]
|
[InlineData("", @".\SubFolder", "/你好/世界/")]
|
||||||
public async Task FoundDirectoryWithDefaultFile_PathModified_Windows(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".\", "/SubFolder/", false)]
|
||||||
|
[InlineData("", @".\subFolder", "/", false)]
|
||||||
|
[InlineData("", @".\SubFolder", "/你好/", false)]
|
||||||
|
[InlineData("", @".\SubFolder", "/你好/世界/", false)]
|
||||||
|
[InlineData("", @".\", "/SubFolder", false)]
|
||||||
|
[InlineData("", @".\subFolder", "", false)]
|
||||||
|
[InlineData("", @".\SubFolder", "/你好", false)]
|
||||||
|
[InlineData("", @".\SubFolder", "/你好/世界", false)]
|
||||||
|
public async Task FoundDirectoryWithDefaultFile_PathModified_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl);
|
await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task FoundDirectoryWithDefaultFile_PathModified(string baseUrl, string baseDir, string requestUrl)
|
private async Task FoundDirectoryWithDefaultFile_PathModified(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
||||||
{
|
{
|
||||||
|
|
@ -144,14 +170,17 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
app.UseDefaultFiles(new DefaultFilesOptions
|
app.UseDefaultFiles(new DefaultFilesOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(baseUrl),
|
RequestPath = new PathString(baseUrl),
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider,
|
||||||
|
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||||
});
|
});
|
||||||
app.Run(context => context.Response.WriteAsync(context.Request.Path.Value));
|
app.Run(context => context.Response.WriteAsync(context.Request.Path.Value));
|
||||||
});
|
});
|
||||||
|
|
||||||
var response = await server.CreateClient().GetAsync(requestUrl);
|
var response = await server.CreateClient().GetAsync(requestUrl);
|
||||||
|
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.Equal(requestUrl + "default.html", await response.Content.ReadAsStringAsync()); // Should be modified
|
var requestUrlWithSlash = requestUrl.EndsWith("/") ? requestUrl : requestUrl + "/";
|
||||||
|
Assert.Equal(requestUrlWithSlash + "default.html", await response.Content.ReadAsStringAsync()); // Should be modified and be valid path to file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,9 +231,17 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("/SubFolder", @".", "/somedir/")]
|
[InlineData("/SubFolder", @".", "/somedir/")]
|
||||||
[InlineData("", @"./SubFolder", "/")]
|
[InlineData("", @"./SubFolder", "/")]
|
||||||
[InlineData("", @"./SubFolder/", "/")]
|
[InlineData("", @"./SubFolder/", "/")]
|
||||||
public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("/SubFolder", @"./", "/SubFolder/", false)]
|
||||||
|
[InlineData("/SubFolder", @".", "/somedir/", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "/", false)]
|
||||||
|
[InlineData("", @"./SubFolder/", "/", false)]
|
||||||
|
[InlineData("/SubFolder", @"./", "/SubFolder", false)]
|
||||||
|
[InlineData("/SubFolder", @".", "/somedir", false)]
|
||||||
|
[InlineData("", @"./SubFolder", "", false)]
|
||||||
|
[InlineData("", @"./SubFolder/", "", false)]
|
||||||
|
public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl);
|
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
|
@ -213,24 +250,37 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("/SubFolder", @".\", "/SubFolder/")]
|
[InlineData("/SubFolder", @".\", "/SubFolder/")]
|
||||||
[InlineData("", @".\SubFolder", "/")]
|
[InlineData("", @".\SubFolder", "/")]
|
||||||
[InlineData("", @".\SubFolder\", "/")]
|
[InlineData("", @".\SubFolder\", "/")]
|
||||||
public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("/SubFolder", @".\", "/SubFolder/", false)]
|
||||||
|
[InlineData("", @".\SubFolder", "/", false)]
|
||||||
|
[InlineData("", @".\SubFolder\", "/", false)]
|
||||||
|
[InlineData("/SubFolder", @".\", "/SubFolder", false)]
|
||||||
|
[InlineData("", @".\SubFolder", "", false)]
|
||||||
|
[InlineData("", @".\SubFolder\", "", false)]
|
||||||
|
public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl);
|
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl)
|
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 fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
||||||
{
|
{
|
||||||
var server = StaticFilesTestServer.Create(app => app.UseDefaultFiles(new DefaultFilesOptions
|
var server = StaticFilesTestServer.Create(app => app.UseDefaultFiles(new DefaultFilesOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(baseUrl),
|
RequestPath = new PathString(baseUrl),
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider,
|
||||||
|
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||||
}));
|
}));
|
||||||
var response = await server.CreateRequest(requestUrl).GetAsync();
|
var response = await server.CreateRequest(requestUrl).GetAsync();
|
||||||
|
|
||||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); // Passed through
|
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); // Passed through
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Options_AppendTrailingSlashByDefault()
|
||||||
|
{
|
||||||
|
Assert.True(new DefaultFilesOptions().RedirectToAppendTrailingSlash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,14 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("/subdir", @".", "/subdir/missing.dir")]
|
[InlineData("/subdir", @".", "/subdir/missing.dir")]
|
||||||
[InlineData("/subdir", @".", "/subdir/missing.dir/")]
|
[InlineData("/subdir", @".", "/subdir/missing.dir/")]
|
||||||
[InlineData("", @"./", "/missing.dir")]
|
[InlineData("", @"./", "/missing.dir")]
|
||||||
public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".", "/missing.dir", false)]
|
||||||
|
[InlineData("", @".", "/missing.dir/", false)]
|
||||||
|
[InlineData("/subdir", @".", "/subdir/missing.dir", false)]
|
||||||
|
[InlineData("/subdir", @".", "/subdir/missing.dir/", false)]
|
||||||
|
[InlineData("", @"./", "/missing.dir", false)]
|
||||||
|
public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl);
|
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
|
@ -66,12 +71,14 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||||
[InlineData("", @".\", "/missing.dir")]
|
[InlineData("", @".\", "/missing.dir")]
|
||||||
[InlineData("", @".\", "/Missing.dir")]
|
[InlineData("", @".\", "/Missing.dir")]
|
||||||
public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".\", "/missing.dir", false)]
|
||||||
|
[InlineData("", @".\", "/Missing.dir", false)]
|
||||||
|
public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl);
|
await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl)
|
private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
||||||
{
|
{
|
||||||
|
|
@ -79,7 +86,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(baseUrl),
|
RequestPath = new PathString(baseUrl),
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider,
|
||||||
|
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||||
}),
|
}),
|
||||||
services => services.AddDirectoryBrowser());
|
services => services.AddDirectoryBrowser());
|
||||||
var response = await server.CreateRequest(requestUrl).GetAsync();
|
var response = await server.CreateRequest(requestUrl).GetAsync();
|
||||||
|
|
@ -117,7 +125,7 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseEndpoints(endpoints => {});
|
app.UseEndpoints(endpoints => { });
|
||||||
},
|
},
|
||||||
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
||||||
|
|
||||||
|
|
@ -133,9 +141,19 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("/somedir", @".", "/somedir/")]
|
[InlineData("/somedir", @".", "/somedir/")]
|
||||||
[InlineData("/somedir", @"./", "/somedir/")]
|
[InlineData("/somedir", @"./", "/somedir/")]
|
||||||
[InlineData("/somedir", @".", "/somedir/SubFolder/")]
|
[InlineData("/somedir", @".", "/somedir/SubFolder/")]
|
||||||
public async Task FoundDirectory_Served_All(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".", "/", false)]
|
||||||
|
[InlineData("", @".", "/SubFolder/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/", false)]
|
||||||
|
[InlineData("/somedir", @"./", "/somedir/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/SubFolder/", false)]
|
||||||
|
[InlineData("", @".", "", false)]
|
||||||
|
[InlineData("", @".", "/SubFolder", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir", false)]
|
||||||
|
[InlineData("/somedir", @"./", "/somedir", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/SubFolder", false)]
|
||||||
|
public async Task FoundDirectory_Served_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await FoundDirectory_Served(baseUrl, baseDir, requestUrl);
|
await FoundDirectory_Served(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
|
@ -143,12 +161,16 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||||
[InlineData("/somedir", @".\", "/somedir/")]
|
[InlineData("/somedir", @".\", "/somedir/")]
|
||||||
[InlineData("/somedir", @".", "/somedir/subFolder/")]
|
[InlineData("/somedir", @".", "/somedir/subFolder/")]
|
||||||
public async Task FoundDirectory_Served_Windows(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("/somedir", @".\", "/somedir/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/subFolder/", false)]
|
||||||
|
[InlineData("/somedir", @".\", "/somedir", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/subFolder", false)]
|
||||||
|
public async Task FoundDirectory_Served_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await FoundDirectory_Served(baseUrl, baseDir, requestUrl);
|
await FoundDirectory_Served(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task FoundDirectory_Served(string baseUrl, string baseDir, string requestUrl)
|
private async Task FoundDirectory_Served(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
||||||
{
|
{
|
||||||
|
|
@ -156,7 +178,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(baseUrl),
|
RequestPath = new PathString(baseUrl),
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider,
|
||||||
|
RedirectToAppendTrailingSlash = appendTrailingSlash,
|
||||||
}),
|
}),
|
||||||
services => services.AddDirectoryBrowser());
|
services => services.AddDirectoryBrowser());
|
||||||
var response = await server.CreateRequest(requestUrl).GetAsync();
|
var response = await server.CreateRequest(requestUrl).GetAsync();
|
||||||
|
|
@ -215,21 +238,31 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("", @".", "/SubFolder/")]
|
[InlineData("", @".", "/SubFolder/")]
|
||||||
[InlineData("/somedir", @".", "/somedir/")]
|
[InlineData("/somedir", @".", "/somedir/")]
|
||||||
[InlineData("/somedir", @".", "/somedir/SubFolder/")]
|
[InlineData("/somedir", @".", "/somedir/SubFolder/")]
|
||||||
public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".", "/", false)]
|
||||||
|
[InlineData("", @".", "/SubFolder/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/SubFolder/", false)]
|
||||||
|
[InlineData("", @".", "", false)]
|
||||||
|
[InlineData("", @".", "/SubFolder", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/SubFolder", false)]
|
||||||
|
public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl);
|
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
[OSSkipCondition(OperatingSystems.Linux)]
|
[OSSkipCondition(OperatingSystems.Linux)]
|
||||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||||
[InlineData("/somedir", @".", "/somedir/subFolder/")]
|
[InlineData("/somedir", @".", "/somedir/subFolder/")]
|
||||||
public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("/somedir", @".", "/somedir/subFolder/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/subFolder", false)]
|
||||||
|
public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl);
|
await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl)
|
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 fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
||||||
{
|
{
|
||||||
|
|
@ -237,7 +270,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(baseUrl),
|
RequestPath = new PathString(baseUrl),
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider,
|
||||||
|
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||||
}),
|
}),
|
||||||
services => services.AddDirectoryBrowser());
|
services => services.AddDirectoryBrowser());
|
||||||
|
|
||||||
|
|
@ -251,21 +285,31 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
[InlineData("", @".", "/SubFolder/")]
|
[InlineData("", @".", "/SubFolder/")]
|
||||||
[InlineData("/somedir", @".", "/somedir/")]
|
[InlineData("/somedir", @".", "/somedir/")]
|
||||||
[InlineData("/somedir", @".", "/somedir/SubFolder/")]
|
[InlineData("/somedir", @".", "/somedir/SubFolder/")]
|
||||||
public async Task HeadDirectory_HeadersButNotBodyServed_All(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("", @".", "/", false)]
|
||||||
|
[InlineData("", @".", "/SubFolder/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/SubFolder/", false)]
|
||||||
|
[InlineData("", @".", "", false)]
|
||||||
|
[InlineData("", @".", "/SubFolder", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/SubFolder", false)]
|
||||||
|
public async Task HeadDirectory_HeadersButNotBodyServed_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl);
|
await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
[OSSkipCondition(OperatingSystems.Linux)]
|
[OSSkipCondition(OperatingSystems.Linux)]
|
||||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||||
[InlineData("/somedir", @".", "/somedir/subFolder/")]
|
[InlineData("/somedir", @".", "/somedir/subFolder/")]
|
||||||
public async Task HeadDirectory_HeadersButNotBodyServed_Windows(string baseUrl, string baseDir, string requestUrl)
|
[InlineData("/somedir", @".", "/somedir/subFolder/", false)]
|
||||||
|
[InlineData("/somedir", @".", "/somedir/subFolder", false)]
|
||||||
|
public async Task HeadDirectory_HeadersButNotBodyServed_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl);
|
await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl, appendTrailingSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HeadDirectory_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl)
|
private async Task HeadDirectory_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true)
|
||||||
{
|
{
|
||||||
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir)))
|
||||||
{
|
{
|
||||||
|
|
@ -273,7 +317,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(baseUrl),
|
RequestPath = new PathString(baseUrl),
|
||||||
FileProvider = fileProvider
|
FileProvider = fileProvider,
|
||||||
|
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||||
}),
|
}),
|
||||||
services => services.AddDirectoryBrowser());
|
services => services.AddDirectoryBrowser());
|
||||||
|
|
||||||
|
|
@ -285,5 +330,11 @@ namespace Microsoft.AspNetCore.StaticFiles
|
||||||
Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
|
Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Options_AppendTrailingSlashByDefault()
|
||||||
|
{
|
||||||
|
Assert.True(new DirectoryBrowserOptions().RedirectToAppendTrailingSlash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue