Merge remote-tracking branch 'StaticFiles/rybrande/release22ToSrc' into rybrande/Mondo2.2

This commit is contained in:
Ryan Brandenburg 2018-11-21 11:15:02 -08:00
commit 7b708c291c
20 changed files with 138 additions and 96 deletions

View File

@ -14,7 +14,6 @@
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot> <RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup> </PropertyGroup>

View File

@ -1,7 +1,10 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion> <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion> <RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.2' ">$(MicrosoftNETCoreApp22PackageVersion)</RuntimeFrameworkVersion>
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion> <NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
<!-- aspnet/BuildTools#662 Don't police what version of NetCoreApp we use -->
<NETCoreAppMaximumVersion>99.9</NETCoreAppMaximumVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -31,6 +31,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.AspNetCore.RangeH
shared\Microsoft.AspNetCore.RangeHelper.Sources\RangeHelper.cs = shared\Microsoft.AspNetCore.RangeHelper.Sources\RangeHelper.cs shared\Microsoft.AspNetCore.RangeHelper.Sources\RangeHelper.cs = shared\Microsoft.AspNetCore.RangeHelper.Sources\RangeHelper.cs
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DE015849-E126-4DFA-A754-E1AC3B1E7925}"
ProjectSection(SolutionItems) = preProject
.appveyor.yml = .appveyor.yml
.travis.yml = .travis.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{D3F67455-9FB9-4354-93EC-B05D755114E9}"
ProjectSection(SolutionItems) = preProject
build\dependencies.props = build\dependencies.props
build\repo.props = build\repo.props
build\sources.props = build\sources.props
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -106,5 +119,9 @@ Global
{FDF0539C-1F62-4B78-91B1-C687886931CA} = {EF02AFE8-7C15-4DDB-8B2C-58A676112A98} {FDF0539C-1F62-4B78-91B1-C687886931CA} = {EF02AFE8-7C15-4DDB-8B2C-58A676112A98}
{D3D752C4-4CDF-4F18-AC7F-48CB980A69DA} = {EF02AFE8-7C15-4DDB-8B2C-58A676112A98} {D3D752C4-4CDF-4F18-AC7F-48CB980A69DA} = {EF02AFE8-7C15-4DDB-8B2C-58A676112A98}
{DB6A1D14-B8A2-488F-9C4B-422FD45C8853} = {360DC2F8-EEB4-4C69-9784-C686EAD78279} {DB6A1D14-B8A2-488F-9C4B-422FD45C8853} = {360DC2F8-EEB4-4C69-9784-C686EAD78279}
{D3F67455-9FB9-4354-93EC-B05D755114E9} = {DE015849-E126-4DFA-A754-E1AC3B1E7925}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AF7F03BE-0DB2-48EF-8185-7698995658A6}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -2,38 +2,32 @@
<PropertyGroup> <PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="Package Versions">
<!-- These package versions may be overridden or updated by automation. --> <InternalAspNetCoreSdkPackageVersion>2.2.0-preview2-20181004.6</InternalAspNetCoreSdkPackageVersion>
<PropertyGroup Label="Package Versions: Auto"> <MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<InternalAspNetCoreSdkPackageVersion>2.1.3-rtm-15802</InternalAspNetCoreSdkPackageVersion> <MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion> <MicrosoftAspNetCoreHttpPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.2</MicrosoftNETCoreApp21PackageVersion> <MicrosoftAspNetCoreServerHttpSysPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreServerHttpSysPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.6.0-preview3-35425</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-preview3-35425</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>2.2.0-preview3-35425</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0-preview3-35425</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-preview3-35425</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>2.2.0-preview3-35425</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>2.2.0-preview3-35425</MicrosoftExtensionsWebEncodersPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview3-27001-02</MicrosoftNETCoreApp22PackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion> <MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
<MoqPackageVersion>4.7.49</MoqPackageVersion> <MoqPackageVersion>4.7.49</MoqPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion> <NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
<XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion> <XunitAnalyzersPackageVersion>0.10.0</XunitAnalyzersPackageVersion>
<XunitPackageVersion>2.3.1</XunitPackageVersion> <XunitPackageVersion>2.3.1</XunitPackageVersion>
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3945</XunitRunnerVisualStudioPackageVersion> <XunitRunnerVisualStudioPackageVersion>2.4.0</XunitRunnerVisualStudioPackageVersion>
</PropertyGroup> </PropertyGroup>
<!-- This may import a generated file which may override the variables above. -->
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " /> <Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
<PropertyGroup Label="Package Versions: Pinned" />
<!-- These are package versions that should not be overridden or updated by automation. --> </Project>
<PropertyGroup Label="Package Versions: Pinned">
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.1</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.1.1</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>2.1.1</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreServerHttpSysPackageVersion>2.1.1</MicrosoftAspNetCoreServerHttpSysPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.1.1</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.5.1</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.2</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>2.1.1</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>2.1.1</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.1.1</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.1</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>2.1.1</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>2.1.1</MicrosoftExtensionsWebEncodersPackageVersion>
</PropertyGroup>
</Project>

View File

@ -4,12 +4,13 @@
<PropertyGroup> <PropertyGroup>
<!-- These properties are use by the automation that updates dependencies.props --> <!-- These properties are use by the automation that updates dependencies.props -->
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId> <LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
<LineupPackageVersion>2.1.0-rc1-*</LineupPackageVersion> <LineupPackageVersion>2.2.0-*</LineupPackageVersion>
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource> <LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp20PackageVersion)" /> <DotNetCoreRuntime Include="$(MicrosoftNETCoreApp20PackageVersion)" />
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp21PackageVersion)" /> <DotNetCoreRuntime Include="$(MicrosoftNETCoreApp21PackageVersion)" />
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp22PackageVersion)" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -62,9 +62,8 @@ namespace Microsoft.AspNetCore.StaticFiles
/// <returns></returns> /// <returns></returns>
public Task Invoke(HttpContext context) public Task Invoke(HttpContext context)
{ {
PathString subpath;
if (Helpers.IsGetOrHeadMethod(context.Request.Method) if (Helpers.IsGetOrHeadMethod(context.Request.Method)
&& Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out subpath)) && Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out var subpath))
{ {
var dirContents = _fileProvider.GetDirectoryContents(subpath.Value); var dirContents = _fileProvider.GetDirectoryContents(subpath.Value);
if (dirContents.Exists) if (dirContents.Exists)
@ -73,7 +72,7 @@ namespace Microsoft.AspNetCore.StaticFiles
for (int matchIndex = 0; matchIndex < _options.DefaultFileNames.Count; matchIndex++) for (int matchIndex = 0; matchIndex < _options.DefaultFileNames.Count; matchIndex++)
{ {
string defaultFile = _options.DefaultFileNames[matchIndex]; string defaultFile = _options.DefaultFileNames[matchIndex];
var file = _fileProvider.GetFileInfo(subpath + defaultFile); var file = _fileProvider.GetFileInfo(subpath.Value + defaultFile);
// TryMatchPath will make sure subpath always ends with a "/" by adding it if needed. // TryMatchPath will make sure subpath always ends with a "/" by adding it if needed.
if (file.Exists) if (file.Exists)
{ {

View File

@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Builder
: base(sharedOptions) : base(sharedOptions)
{ {
// Prioritized list // Prioritized list
DefaultFileNames = new List<string>() DefaultFileNames = new List<string>
{ {
"default.htm", "default.htm",
"default.html", "default.html",

View File

@ -79,11 +79,9 @@ namespace Microsoft.AspNetCore.StaticFiles
public Task Invoke(HttpContext context) public Task Invoke(HttpContext context)
{ {
// Check if the URL matches any expected paths // Check if the URL matches any expected paths
PathString subpath;
IDirectoryContents contents;
if (Helpers.IsGetOrHeadMethod(context.Request.Method) if (Helpers.IsGetOrHeadMethod(context.Request.Method)
&& Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out subpath) && Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out var subpath)
&& TryGetDirectoryInfo(subpath, out contents)) && TryGetDirectoryInfo(subpath, out var contents))
{ {
// 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.

View File

@ -331,7 +331,8 @@ namespace Microsoft.AspNetCore.StaticFiles
{ ".vsto", "application/x-ms-vsto" }, { ".vsto", "application/x-ms-vsto" },
{ ".vsw", "application/vnd.visio" }, { ".vsw", "application/vnd.visio" },
{ ".vsx", "application/vnd.visio" }, { ".vsx", "application/vnd.visio" },
{ ".vtx", "application/vnd.visio" }, { ".vtx", "application/vnd.visio" },
{ ".wasm", "application/wasm" },
{ ".wav", "audio/wav" }, { ".wav", "audio/wav" },
{ ".wax", "audio/x-ms-wax" }, { ".wax", "audio/x-ms-wax" },
{ ".wbmp", "image/vnd.wap.wbmp" }, { ".wbmp", "image/vnd.wap.wbmp" },
@ -456,4 +457,4 @@ namespace Microsoft.AspNetCore.StaticFiles
return path.Substring(index); return path.Substring(index);
} }
} }
} }

View File

@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.StaticFiles
// it is not returned for 304, 412, and 416 // it is not returned for 304, 412, and 416
_response.ContentLength = _length; _response.ContentLength = _length;
} }
_options.OnPrepareResponse(new StaticFileResponseContext() _options.OnPrepareResponse(new StaticFileResponseContext
{ {
Context = _context, Context = _context,
File = _fileInfo, File = _fileInfo,
@ -360,8 +360,7 @@ namespace Microsoft.AspNetCore.StaticFiles
return; return;
} }
long start, length; _responseHeaders.ContentRange = ComputeContentRange(_range, out var start, out var length);
_responseHeaders.ContentRange = ComputeContentRange(_range, out start, out length);
_response.ContentLength = length; _response.ContentLength = length;
ApplyResponseHeaders(Constants.Status206PartialContent); ApplyResponseHeaders(Constants.Status206PartialContent);

View File

@ -1,10 +1,10 @@
<Project> <Project>
<Import Project="..\Directory.Build.props" /> <Import Project="..\Directory.Build.props" />
<PropertyGroup> <PropertyGroup>
<DeveloperBuildTestTfms>netcoreapp2.1</DeveloperBuildTestTfms> <DeveloperBuildTestTfms>netcoreapp2.2</DeveloperBuildTestTfms>
<StandardTestTfms>$(DeveloperBuildTestTfms)</StandardTestTfms> <StandardTestTfms>$(DeveloperBuildTestTfms)</StandardTestTfms>
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' ">netcoreapp2.1;netcoreapp2.0</StandardTestTfms>
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms> <StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms>
</PropertyGroup> </PropertyGroup>

View File

@ -15,25 +15,27 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Testing;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.StaticFiles namespace Microsoft.AspNetCore.StaticFiles
{ {
public class StaticFileMiddlewareTests public class StaticFileMiddlewareTests : LoggedTest
{ {
[Fact] [Fact]
public async Task ReturnsNotFoundWithoutWwwroot() public async Task ReturnsNotFoundWithoutWwwroot()
{ {
var baseAddress = "http://localhost:12345";
var builder = new WebHostBuilder() var builder = new WebHostBuilder()
.ConfigureServices(services => services.AddSingleton(LoggerFactory))
.UseKestrel() .UseKestrel()
.Configure(app => app.UseStaticFiles()); .Configure(app => app.UseStaticFiles());
using (var server = builder.Start(baseAddress)) using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel)))
{ {
using (var client = new HttpClient() { BaseAddress = new Uri(baseAddress) }) using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) })
{ {
var response = await client.GetAsync("TestDocument.txt"); var response = await client.GetAsync("TestDocument.txt");
@ -45,22 +47,22 @@ namespace Microsoft.AspNetCore.StaticFiles
[Fact] [Fact]
public async Task FoundFile_LastModifiedTrimsSeconds() public async Task FoundFile_LastModifiedTrimsSeconds()
{ {
var baseAddress = "http://localhost:12345";
var builder = new WebHostBuilder() var builder = new WebHostBuilder()
.ConfigureServices(services => services.AddSingleton(LoggerFactory))
.UseKestrel() .UseKestrel()
.UseWebRoot(AppContext.BaseDirectory) .UseWebRoot(AppContext.BaseDirectory)
.Configure(app => app.UseStaticFiles()); .Configure(app => app.UseStaticFiles());
using (var server = builder.Start(baseAddress)) using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel)))
{ {
using (var client = new HttpClient() { BaseAddress = new Uri(baseAddress) }) using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) })
{ {
var last = File.GetLastWriteTimeUtc(Path.Combine(AppContext.BaseDirectory, "TestDocument.txt")); var last = File.GetLastWriteTimeUtc(Path.Combine(AppContext.BaseDirectory, "TestDocument.txt"));
var response = await client.GetAsync("TestDocument.txt"); var response = await client.GetAsync("TestDocument.txt");
var trimed = new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, TimeSpan.Zero).ToUniversalTime(); var trimmed = new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, TimeSpan.Zero).ToUniversalTime();
Assert.Equal(response.Content.Headers.LastModified.Value, trimed); Assert.Equal(response.Content.Headers.LastModified.Value, trimmed);
} }
} }
} }
@ -86,20 +88,20 @@ namespace Microsoft.AspNetCore.StaticFiles
private async Task FoundFile_Served(string baseUrl, string baseDir, string requestUrl) private async Task FoundFile_Served(string baseUrl, string baseDir, string requestUrl)
{ {
var baseAddress = "http://localhost:12345";
var builder = new WebHostBuilder() var builder = new WebHostBuilder()
.ConfigureServices(services => services.AddSingleton(LoggerFactory))
.UseKestrel() .UseKestrel()
.UseWebRoot(Path.Combine(AppContext.BaseDirectory, baseDir)) .UseWebRoot(Path.Combine(AppContext.BaseDirectory, baseDir))
.Configure(app => app.UseStaticFiles(new StaticFileOptions() .Configure(app => app.UseStaticFiles(new StaticFileOptions
{ {
RequestPath = new PathString(baseUrl), RequestPath = new PathString(baseUrl),
})); }));
using (var server = builder.Start(baseAddress)) using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel)))
{ {
var hostingEnvironment = server.Services.GetService<IHostingEnvironment>(); var hostingEnvironment = server.Services.GetService<IHostingEnvironment>();
using (var client = new HttpClient() { BaseAddress = new Uri(baseAddress) }) using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) })
{ {
var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl)); var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl));
var response = await client.GetAsync(requestUrl); var response = await client.GetAsync(requestUrl);
@ -124,20 +126,20 @@ namespace Microsoft.AspNetCore.StaticFiles
[MemberData(nameof(ExistingFiles))] [MemberData(nameof(ExistingFiles))]
public async Task HeadFile_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl) public async Task HeadFile_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl)
{ {
var baseAddress = "http://localhost:12345";
var builder = new WebHostBuilder() var builder = new WebHostBuilder()
.ConfigureServices(services => services.AddSingleton(LoggerFactory))
.UseKestrel() .UseKestrel()
.UseWebRoot(Path.Combine(AppContext.BaseDirectory, baseDir)) .UseWebRoot(Path.Combine(AppContext.BaseDirectory, baseDir))
.Configure(app => app.UseStaticFiles(new StaticFileOptions() .Configure(app => app.UseStaticFiles(new StaticFileOptions
{ {
RequestPath = new PathString(baseUrl), RequestPath = new PathString(baseUrl),
})); }));
using (var server = builder.Start(baseAddress)) using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel)))
{ {
var hostingEnvironment = server.Services.GetService<IHostingEnvironment>(); var hostingEnvironment = server.Services.GetService<IHostingEnvironment>();
using (var client = new HttpClient() { BaseAddress = new Uri(baseAddress) }) using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) })
{ {
var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl)); var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl));
var request = new HttpRequestMessage(HttpMethod.Head, requestUrl); var request = new HttpRequestMessage(HttpMethod.Head, requestUrl);
@ -172,18 +174,18 @@ namespace Microsoft.AspNetCore.StaticFiles
[OSSkipCondition(OperatingSystems.MacOSX)] [OSSkipCondition(OperatingSystems.MacOSX)]
public void ClientDisconnect_WebListener_NoWriteExceptionThrown() public void ClientDisconnect_WebListener_NoWriteExceptionThrown()
{ {
ClientDisconnect_NoWriteExceptionThrown(ServerType.WebListener); ClientDisconnect_NoWriteExceptionThrown(ServerType.HttpSys);
} }
private void ClientDisconnect_NoWriteExceptionThrown(ServerType serverType) private void ClientDisconnect_NoWriteExceptionThrown(ServerType serverType)
{ {
var interval = TimeSpan.FromSeconds(15); var interval = TimeSpan.FromSeconds(15);
var baseAddress = "http://localhost:12345";
var requestReceived = new ManualResetEvent(false); var requestReceived = new ManualResetEvent(false);
var requestCacelled = new ManualResetEvent(false); var requestCancelled = new ManualResetEvent(false);
var responseComplete = new ManualResetEvent(false); var responseComplete = new ManualResetEvent(false);
Exception exception = null; Exception exception = null;
var builder = new WebHostBuilder() var builder = new WebHostBuilder()
.ConfigureServices(services => services.AddSingleton(LoggerFactory))
.UseWebRoot(Path.Combine(AppContext.BaseDirectory)) .UseWebRoot(Path.Combine(AppContext.BaseDirectory))
.Configure(app => .Configure(app =>
{ {
@ -192,7 +194,7 @@ namespace Microsoft.AspNetCore.StaticFiles
try try
{ {
requestReceived.Set(); requestReceived.Set();
Assert.True(requestCacelled.WaitOne(interval), "not cancelled"); Assert.True(requestCancelled.WaitOne(interval), "not cancelled");
Assert.True(context.RequestAborted.WaitHandle.WaitOne(interval), "not aborted"); Assert.True(context.RequestAborted.WaitHandle.WaitOne(interval), "not aborted");
await next(); await next();
} }
@ -205,7 +207,7 @@ namespace Microsoft.AspNetCore.StaticFiles
app.UseStaticFiles(); app.UseStaticFiles();
}); });
if (serverType == ServerType.WebListener) if (serverType == ServerType.HttpSys)
{ {
builder.UseHttpSys(); builder.UseHttpSys();
} }
@ -214,15 +216,15 @@ namespace Microsoft.AspNetCore.StaticFiles
builder.UseKestrel(); builder.UseKestrel();
} }
using (var server = builder.Start(baseAddress)) using (var server = builder.Start(TestUrlHelper.GetTestUrl(serverType)))
{ {
// We don't use HttpClient here because it's disconnect behavior varies across platforms. // We don't use HttpClient here because it's disconnect behavior varies across platforms.
var socket = SendSocketRequestAsync(baseAddress, "/TestDocument1MB.txt"); var socket = SendSocketRequestAsync(server.GetAddress(), "/TestDocument1MB.txt");
Assert.True(requestReceived.WaitOne(interval), "not received"); Assert.True(requestReceived.WaitOne(interval), "not received");
socket.LingerState = new LingerOption(true, 0); socket.LingerState = new LingerOption(true, 0);
socket.Dispose(); socket.Dispose();
requestCacelled.Set(); requestCancelled.Set();
Assert.True(responseComplete.WaitOne(interval), "not completed"); Assert.True(responseComplete.WaitOne(interval), "not completed");
Assert.Null(exception); Assert.Null(exception);

View File

@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.StaticFiles
[Theory] [Theory]
[MemberData(nameof(SupportedMethods))] [MemberData(nameof(SupportedMethods))]
public async Task IfMatchShouldBeServedForAstrisk(HttpMethod method) public async Task IfMatchShouldBeServedForAsterisk(HttpMethod method)
{ {
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer()); TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
var req = new HttpRequestMessage(method, "http://localhost/SubFolder/extra.xml"); var req = new HttpRequestMessage(method, "http://localhost/SubFolder/extra.xml");
@ -230,7 +230,7 @@ namespace Microsoft.AspNetCore.StaticFiles
DateTimeOffset lastModified = resp1.Content.Headers.LastModified.Value; DateTimeOffset lastModified = resp1.Content.Headers.LastModified.Value;
DateTimeOffset pastDate = lastModified.AddHours(-1); DateTimeOffset pastDate = lastModified.AddHours(-1);
DateTimeOffset furtureDate = lastModified.AddHours(1); DateTimeOffset futureDate = lastModified.AddHours(1);
HttpResponseMessage resp2 = await server HttpResponseMessage resp2 = await server
.CreateRequest("/SubFolder/extra.xml") .CreateRequest("/SubFolder/extra.xml")
@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.StaticFiles
HttpResponseMessage resp4 = await server HttpResponseMessage resp4 = await server
.CreateRequest("/SubFolder/extra.xml") .CreateRequest("/SubFolder/extra.xml")
.AddHeader("If-None-Match", "\"fake\"") .AddHeader("If-None-Match", "\"fake\"")
.And(req => req.Headers.IfModifiedSince = furtureDate) .And(req => req.Headers.IfModifiedSince = futureDate)
.SendAsync(method.Method); .SendAsync(method.Method);
Assert.Equal(HttpStatusCode.OK, resp2.StatusCode); Assert.Equal(HttpStatusCode.OK, resp2.StatusCode);
@ -322,7 +322,7 @@ namespace Microsoft.AspNetCore.StaticFiles
[Theory] [Theory]
[MemberData(nameof(SupportedMethods))] [MemberData(nameof(SupportedMethods))]
public async Task SuppportsIfModifiedDateFormats(HttpMethod method) public async Task SupportsIfModifiedDateFormats(HttpMethod method)
{ {
TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer()); TestServer server = StaticFilesTestServer.Create(app => app.UseFileServer());
HttpResponseMessage res1 = await server HttpResponseMessage res1 = await server

View File

@ -16,11 +16,10 @@ namespace Microsoft.AspNetCore.StaticFiles
} }
[Fact] [Fact]
public void KnownExtensionsReturnTrye() public void KnownExtensionsReturnType()
{ {
var provider = new FileExtensionContentTypeProvider(); var provider = new FileExtensionContentTypeProvider();
string contentType; Assert.True(provider.TryGetContentType("known.txt", out var contentType));
Assert.True(provider.TryGetContentType("known.txt", out contentType));
Assert.Equal("text/plain", contentType); Assert.Equal("text/plain", contentType);
} }
@ -36,8 +35,7 @@ namespace Microsoft.AspNetCore.StaticFiles
public void DashedExtensionsShouldBeMatched() public void DashedExtensionsShouldBeMatched()
{ {
var provider = new FileExtensionContentTypeProvider(); var provider = new FileExtensionContentTypeProvider();
string contentType; Assert.True(provider.TryGetContentType("known.dvr-ms", out var contentType));
Assert.True(provider.TryGetContentType("known.dvr-ms", out contentType));
Assert.Equal("video/x-ms-dvr", contentType); Assert.Equal("video/x-ms-dvr", contentType);
} }
@ -45,8 +43,7 @@ namespace Microsoft.AspNetCore.StaticFiles
public void BothSlashFormatsAreUnderstood() public void BothSlashFormatsAreUnderstood()
{ {
var provider = new FileExtensionContentTypeProvider(); var provider = new FileExtensionContentTypeProvider();
string contentType; Assert.True(provider.TryGetContentType(@"/first/example.txt", out var contentType));
Assert.True(provider.TryGetContentType(@"/first/example.txt", out contentType));
Assert.Equal("text/plain", contentType); Assert.Equal("text/plain", contentType);
Assert.True(provider.TryGetContentType(@"\second\example.txt", out contentType)); Assert.True(provider.TryGetContentType(@"\second\example.txt", out contentType));
Assert.Equal("text/plain", contentType); Assert.Equal("text/plain", contentType);
@ -56,8 +53,7 @@ namespace Microsoft.AspNetCore.StaticFiles
public void DotsInDirectoryAreIgnored() public void DotsInDirectoryAreIgnored()
{ {
var provider = new FileExtensionContentTypeProvider(); var provider = new FileExtensionContentTypeProvider();
string contentType; Assert.True(provider.TryGetContentType(@"/first.css/example.txt", out var contentType));
Assert.True(provider.TryGetContentType(@"/first.css/example.txt", out contentType));
Assert.Equal("text/plain", contentType); Assert.Equal("text/plain", contentType);
Assert.True(provider.TryGetContentType(@"\second.css\example.txt", out contentType)); Assert.True(provider.TryGetContentType(@"\second.css\example.txt", out contentType));
Assert.Equal("text/plain", contentType); Assert.Equal("text/plain", contentType);

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// 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;
@ -9,6 +9,7 @@ using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
@ -75,6 +76,8 @@ namespace Microsoft.AspNetCore.StaticFiles
[InlineData("", @".", "/SubFolder/")] [InlineData("", @".", "/SubFolder/")]
[InlineData("", @"./", "/SubFolder/")] [InlineData("", @"./", "/SubFolder/")]
[InlineData("", @"./SubFolder", "/")] [InlineData("", @"./SubFolder", "/")]
[InlineData("", @"./SubFolder", "/你好/")]
[InlineData("", @"./SubFolder", "/你好/世界/")]
public async Task FoundDirectoryWithDefaultFile_PathModified_All(string baseUrl, string baseDir, string requestUrl) public async Task FoundDirectoryWithDefaultFile_PathModified_All(string baseUrl, string baseDir, string requestUrl)
{ {
await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl); await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl);
@ -85,6 +88,8 @@ namespace Microsoft.AspNetCore.StaticFiles
[OSSkipCondition(OperatingSystems.MacOSX)] [OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData("", @".\", "/SubFolder/")] [InlineData("", @".\", "/SubFolder/")]
[InlineData("", @".\subFolder", "/")] [InlineData("", @".\subFolder", "/")]
[InlineData("", @".\SubFolder", "/你好/")]
[InlineData("", @".\SubFolder", "/你好/世界/")]
public async Task FoundDirectoryWithDefaultFile_PathModified_Windows(string baseUrl, string baseDir, string requestUrl) public async Task FoundDirectoryWithDefaultFile_PathModified_Windows(string baseUrl, string baseDir, string requestUrl)
{ {
await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl); await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl);
@ -114,6 +119,8 @@ namespace Microsoft.AspNetCore.StaticFiles
[InlineData("", @".", "/SubFolder", "")] [InlineData("", @".", "/SubFolder", "")]
[InlineData("", @"./", "/SubFolder", "")] [InlineData("", @"./", "/SubFolder", "")]
[InlineData("", @"./", "/SubFolder", "?a=b")] [InlineData("", @"./", "/SubFolder", "?a=b")]
[InlineData("", @"./SubFolder", "/你好", "?a=b")]
[InlineData("", @"./SubFolder", "/你好/世界", "?a=b")]
public async Task NearMatch_RedirectAddSlash_All(string baseUrl, string baseDir, string requestUrl, string queryString) public async Task NearMatch_RedirectAddSlash_All(string baseUrl, string baseDir, string requestUrl, string queryString)
{ {
await NearMatch_RedirectAddSlash(baseUrl, baseDir, requestUrl, queryString); await NearMatch_RedirectAddSlash(baseUrl, baseDir, requestUrl, queryString);
@ -124,6 +131,8 @@ namespace Microsoft.AspNetCore.StaticFiles
[OSSkipCondition(OperatingSystems.MacOSX)] [OSSkipCondition(OperatingSystems.MacOSX)]
[InlineData("", @".\", "/SubFolder", "")] [InlineData("", @".\", "/SubFolder", "")]
[InlineData("", @".\", "/SubFolder", "?a=b")] [InlineData("", @".\", "/SubFolder", "?a=b")]
[InlineData("", @".\SubFolder", "/你好", "?a=b")]
[InlineData("", @".\SubFolder", "/你好/世界", "?a=b")]
public async Task NearMatch_RedirectAddSlash_Windows(string baseUrl, string baseDir, string requestUrl, string queryString) public async Task NearMatch_RedirectAddSlash_Windows(string baseUrl, string baseDir, string requestUrl, string queryString)
{ {
await NearMatch_RedirectAddSlash(baseUrl, baseDir, requestUrl, queryString); await NearMatch_RedirectAddSlash(baseUrl, baseDir, requestUrl, queryString);
@ -141,7 +150,10 @@ namespace Microsoft.AspNetCore.StaticFiles
var response = await server.CreateRequest(requestUrl + queryString).GetAsync(); var response = await server.CreateRequest(requestUrl + queryString).GetAsync();
Assert.Equal(HttpStatusCode.Moved, response.StatusCode); Assert.Equal(HttpStatusCode.Moved, response.StatusCode);
Assert.Equal(requestUrl + "/" + queryString, response.Headers.GetValues("Location").FirstOrDefault()); // the url in the header of `Location: /xxx/xxx` should be encoded
var expectedURL = UriHelper.BuildRelative(baseUrl, requestUrl + "/", new QueryString(queryString), new FragmentString());
var actualURL = response.Headers.GetValues("Location").FirstOrDefault();
Assert.Equal(expectedURL, actualURL);
Assert.Empty((await response.Content.ReadAsByteArrayAsync())); Assert.Empty((await response.Content.ReadAsByteArrayAsync()));
} }
} }
@ -169,12 +181,12 @@ namespace Microsoft.AspNetCore.StaticFiles
private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl) private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl)
{ {
using (var fileProvder = 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 = fileProvder FileProvider = fileProvider
})); }));
var response = await server.CreateRequest(requestUrl).GetAsync(); var response = await server.CreateRequest(requestUrl).GetAsync();

View File

@ -70,8 +70,7 @@ namespace Microsoft.AspNetCore.StaticFiles
public IFileInfo GetFileInfo(string subpath) public IFileInfo GetFileInfo(string subpath)
{ {
IFileInfo result; if (_files.TryGetValue(subpath, out var result))
if (_files.TryGetValue(subpath, out result))
{ {
return result; return result;
} }

View File

@ -101,9 +101,9 @@ namespace Microsoft.AspNetCore.StaticFiles
var response = await server.CreateRequest("TestDocument.txt").GetAsync(); var response = await server.CreateRequest("TestDocument.txt").GetAsync();
var last = fileInfo.LastModified; var last = fileInfo.LastModified;
var trimed = new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, last.Offset).ToUniversalTime(); 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, trimed); Assert.Equal(response.Content.Headers.LastModified.Value, trimmed);
} }
} }

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
Hello World
</body>
</html>

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
Hello World
</body>
</html>

View File

@ -1,6 +1,6 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<VersionPrefix>2.1.1</VersionPrefix> <VersionPrefix>2.2.0</VersionPrefix>
<VersionSuffix>rtm</VersionSuffix> <VersionSuffix>rtm</VersionSuffix>
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' == 'rtm' ">$(VersionPrefix)</PackageVersion> <PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' == 'rtm' ">$(VersionPrefix)</PackageVersion>
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion> <PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion>