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 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 abstract partial class SharedOptionsBase
|
||||
{
|
||||
protected SharedOptionsBase(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions sharedOptions) { }
|
||||
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 { } }
|
||||
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.
|
||||
// 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;
|
||||
var request = context.Request;
|
||||
var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString);
|
||||
context.Response.Headers[HeaderNames.Location] = redirect;
|
||||
Helpers.RedirectToPathWithSlash(context);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
// 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;
|
||||
var request = context.Request;
|
||||
var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString);
|
||||
context.Response.Headers[HeaderNames.Location] = redirect;
|
||||
Helpers.RedirectToPathWithSlash(context);
|
||||
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.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.StaticFiles
|
||||
{
|
||||
|
|
@ -12,7 +15,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
{
|
||||
internal static IFileProvider ResolveFileProvider(IWebHostEnvironment hostingEnv)
|
||||
{
|
||||
if (hostingEnv.WebRootFileProvider == null) {
|
||||
if (hostingEnv.WebRootFileProvider == null)
|
||||
{
|
||||
throw new InvalidOperationException("Missing FileProvider.");
|
||||
}
|
||||
return hostingEnv.WebRootFileProvider;
|
||||
|
|
@ -28,6 +32,23 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
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)
|
||||
{
|
||||
var path = context.Request.Path;
|
||||
|
|
|
|||
|
|
@ -42,5 +42,10 @@ namespace Microsoft.AspNetCore.StaticFiles.Infrastructure
|
|||
/// The file system used to locate resources
|
||||
/// </summary>
|
||||
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; }
|
||||
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("", @"./", "/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]
|
||||
|
|
@ -48,12 +53,14 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[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)))
|
||||
{
|
||||
|
|
@ -62,7 +69,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
app.UseDefaultFiles(new DefaultFilesOptions
|
||||
{
|
||||
RequestPath = new PathString(baseUrl),
|
||||
FileProvider = fileProvider
|
||||
FileProvider = fileProvider,
|
||||
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||
});
|
||||
app.Run(context => context.Response.WriteAsync(context.Request.Path.Value));
|
||||
});
|
||||
|
|
@ -102,7 +110,7 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
FileProvider = fileProvider
|
||||
});
|
||||
|
||||
app.UseEndpoints(endpoints => {});
|
||||
app.UseEndpoints(endpoints => { });
|
||||
},
|
||||
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
||||
|
||||
|
|
@ -118,9 +126,19 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[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]
|
||||
|
|
@ -130,12 +148,20 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[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)))
|
||||
{
|
||||
|
|
@ -144,14 +170,17 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
app.UseDefaultFiles(new DefaultFilesOptions
|
||||
{
|
||||
RequestPath = new PathString(baseUrl),
|
||||
FileProvider = fileProvider
|
||||
FileProvider = fileProvider,
|
||||
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||
});
|
||||
app.Run(context => context.Response.WriteAsync(context.Request.Path.Value));
|
||||
});
|
||||
|
||||
var response = await server.CreateClient().GetAsync(requestUrl);
|
||||
|
||||
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", "/")]
|
||||
[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]
|
||||
|
|
@ -213,24 +250,37 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[InlineData("/SubFolder", @".\", "/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)))
|
||||
{
|
||||
var server = StaticFilesTestServer.Create(app => app.UseDefaultFiles(new DefaultFilesOptions
|
||||
{
|
||||
RequestPath = new PathString(baseUrl),
|
||||
FileProvider = fileProvider
|
||||
FileProvider = fileProvider,
|
||||
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||
}));
|
||||
var response = await server.CreateRequest(requestUrl).GetAsync();
|
||||
|
||||
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("", @"./", "/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]
|
||||
|
|
@ -66,12 +71,14 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[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)))
|
||||
{
|
||||
|
|
@ -79,7 +86,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||
{
|
||||
RequestPath = new PathString(baseUrl),
|
||||
FileProvider = fileProvider
|
||||
FileProvider = fileProvider,
|
||||
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||
}),
|
||||
services => services.AddDirectoryBrowser());
|
||||
var response = await server.CreateRequest(requestUrl).GetAsync();
|
||||
|
|
@ -117,7 +125,7 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
FileProvider = fileProvider
|
||||
});
|
||||
|
||||
app.UseEndpoints(endpoints => {});
|
||||
app.UseEndpoints(endpoints => { });
|
||||
},
|
||||
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
||||
|
||||
|
|
@ -133,9 +141,19 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[InlineData("/somedir", @".", "/somedir/")]
|
||||
[InlineData("/somedir", @"./", "/somedir/")]
|
||||
[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]
|
||||
|
|
@ -143,12 +161,16 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[InlineData("/somedir", @".\", "/somedir/")]
|
||||
[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)))
|
||||
{
|
||||
|
|
@ -156,7 +178,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||
{
|
||||
RequestPath = new PathString(baseUrl),
|
||||
FileProvider = fileProvider
|
||||
FileProvider = fileProvider,
|
||||
RedirectToAppendTrailingSlash = appendTrailingSlash,
|
||||
}),
|
||||
services => services.AddDirectoryBrowser());
|
||||
var response = await server.CreateRequest(requestUrl).GetAsync();
|
||||
|
|
@ -215,21 +238,31 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[InlineData("", @".", "/SubFolder/")]
|
||||
[InlineData("/somedir", @".", "/somedir/")]
|
||||
[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]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[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)))
|
||||
{
|
||||
|
|
@ -237,7 +270,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||
{
|
||||
RequestPath = new PathString(baseUrl),
|
||||
FileProvider = fileProvider
|
||||
FileProvider = fileProvider,
|
||||
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||
}),
|
||||
services => services.AddDirectoryBrowser());
|
||||
|
||||
|
|
@ -251,21 +285,31 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
[InlineData("", @".", "/SubFolder/")]
|
||||
[InlineData("/somedir", @".", "/somedir/")]
|
||||
[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]
|
||||
[OSSkipCondition(OperatingSystems.Linux)]
|
||||
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||
[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)))
|
||||
{
|
||||
|
|
@ -273,7 +317,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
app => app.UseDirectoryBrowser(new DirectoryBrowserOptions
|
||||
{
|
||||
RequestPath = new PathString(baseUrl),
|
||||
FileProvider = fileProvider
|
||||
FileProvider = fileProvider,
|
||||
RedirectToAppendTrailingSlash = appendTrailingSlash
|
||||
}),
|
||||
services => services.AddDirectoryBrowser());
|
||||
|
||||
|
|
@ -285,5 +330,11 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Options_AppendTrailingSlashByDefault()
|
||||
{
|
||||
Assert.True(new DirectoryBrowserOptions().RedirectToAppendTrailingSlash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue