diff --git a/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs b/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs index 6ce99f7832..146f9a50f5 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.IO; using System.Runtime.InteropServices; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; @@ -32,7 +33,9 @@ namespace Microsoft.AspNetCore.Hosting hostBuilder.CaptureStartupErrors(true); var iisConfigData = NativeMethods.HttpGetApplicationProperties(); - hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath); + // Trim trailing slash to be consistent with other servers + var contentRoot = iisConfigData.pwzFullApplicationPath.TrimEnd(Path.DirectorySeparatorChar); + hostBuilder.UseContentRoot(contentRoot); return hostBuilder.ConfigureServices( services => { services.AddSingleton(new IISNativeApplication(iisConfigData.pNativeApplication)); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs index 0fea5fa391..6d99edf0fd 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs @@ -175,7 +175,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, - RedirectStandardOutput = true + RedirectStandardOutput = true, + // VS sets current directory to C:\Program Files\IIS Express + WorkingDirectory = Path.GetDirectoryName(iisExpressPath) }; AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs index 241991f62d..d9067c038e 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs @@ -44,6 +44,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS offset += count; } while (count != 0 && offset != buffer.Length); + readAsStreamAsync.Position = 0; _logger.Log(logLevel, Encoding.ASCII.GetString(buffer, 0, offset)); } } diff --git a/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs b/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs new file mode 100644 index 0000000000..061b828a6c --- /dev/null +++ b/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs @@ -0,0 +1,33 @@ +// 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. + +using System; +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class HostingEnvironmentTests: FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public HostingEnvironmentTests(IISTestSiteFixture fixture): base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + [RequiresIIS(IISCapability.ShutdownToken)] + public async Task HostingEnvironmentIsCorrect() + { + Assert.Equal( + $"ContentRootPath {_fixture.DeploymentResult.ContentRoot}" + Environment.NewLine + + $"WebRootPath {_fixture.DeploymentResult.ContentRoot}\\wwwroot" + Environment.NewLine + + $"CurrentDirectory {Path.GetDirectoryName(_fixture.DeploymentResult.HostProcess.MainModule.FileName)}", + await _fixture.Client.GetStringAsync("/HostingEnvironment")); + } + } +} diff --git a/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs b/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs index 8ae0c7dc89..e868207bb8 100644 --- a/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs +++ b/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs @@ -1,6 +1,7 @@ // 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. +using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; @@ -58,6 +59,12 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests responseText = await response.Content.ReadAsStringAsync(); Assert.True("backcompat;Windows".Equals(responseText) || "latest;null".Equals(responseText), "Auth"); + + Assert.Equal( + $"ContentRootPath {deploymentResult.ContentRoot}" + Environment.NewLine + + $"WebRootPath {deploymentResult.ContentRoot}\\wwwroot" + Environment.NewLine + + $"CurrentDirectory {deploymentResult.ContentRoot}", + await deploymentResult.HttpClient.GetStringAsync("/HostingEnvironment")); } } } diff --git a/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs index 787276a8fa..fc5a3b6df1 100644 --- a/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs +++ b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests _deployer = IISApplicationDeployerFactory.Create(deploymentParameters, loggerFactory); - DeploymentResult = _deployer.DeployAsync().Result; + DeploymentResult = (IISDeploymentResult)_deployer.DeployAsync().Result; Client = DeploymentResult.HttpClient; BaseUri = DeploymentResult.ApplicationBaseUri; ShutdownToken = DeploymentResult.HostShutdownToken; @@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests public string BaseUri { get; } public HttpClient Client { get; } public CancellationToken ShutdownToken { get; } - public DeploymentResult DeploymentResult { get; } + public IISDeploymentResult DeploymentResult { get; } public TestConnection CreateTestConnection() { diff --git a/test/WebSites/InProcessWebSite/InProcessWebSite.csproj b/test/WebSites/InProcessWebSite/InProcessWebSite.csproj index e5158c8cad..b6d09409c1 100644 --- a/test/WebSites/InProcessWebSite/InProcessWebSite.csproj +++ b/test/WebSites/InProcessWebSite/InProcessWebSite.csproj @@ -1,4 +1,4 @@ - + @@ -13,6 +13,10 @@ + + + + diff --git a/test/WebSites/InProcessWebSite/Startup.cs b/test/WebSites/InProcessWebSite/Startup.cs index f42e220751..7142f627d3 100644 --- a/test/WebSites/InProcessWebSite/Startup.cs +++ b/test/WebSites/InProcessWebSite/Startup.cs @@ -43,6 +43,15 @@ namespace IISTestSite }); } + private async Task HostingEnvironment(HttpContext context) + { + var hostingEnv = context.RequestServices.GetService(); + + await context.Response.WriteAsync("ContentRootPath "+hostingEnv.ContentRootPath + Environment.NewLine); + await context.Response.WriteAsync("WebRootPath "+hostingEnv.WebRootPath + Environment.NewLine); + await context.Response.WriteAsync("CurrentDirectory "+Environment.CurrentDirectory); + } + private void AuthenticationRestricted(IApplicationBuilder app) { app.Run(async ctx => diff --git a/test/WebSites/InProcessWebSite/wwwroot/static.txt b/test/WebSites/InProcessWebSite/wwwroot/static.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj b/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj index 399a22e279..36ca6e2b54 100644 --- a/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj +++ b/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj @@ -14,6 +14,10 @@ + + + + diff --git a/test/WebSites/OutOfProcessWebSite/Program.cs b/test/WebSites/OutOfProcessWebSite/Program.cs index 52be26b80c..a5943f5f00 100644 --- a/test/WebSites/OutOfProcessWebSite/Program.cs +++ b/test/WebSites/OutOfProcessWebSite/Program.cs @@ -1,6 +1,7 @@ // 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. +using System.IO; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Logging; @@ -16,6 +17,7 @@ namespace TestSites factory.AddConsole(); factory.AddFilter("Console", level => level >= LogLevel.Information); }) + .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup() .UseKestrel() diff --git a/test/WebSites/OutOfProcessWebSite/Startup.cs b/test/WebSites/OutOfProcessWebSite/Startup.cs index 185aecb7f4..be44480891 100644 --- a/test/WebSites/OutOfProcessWebSite/Startup.cs +++ b/test/WebSites/OutOfProcessWebSite/Startup.cs @@ -9,6 +9,7 @@ using System.Security.Principal; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.IISIntegration.FunctionalTests; @@ -104,5 +105,14 @@ namespace TestSites return context.Response.WriteAsync(context.Request.Headers["ANCMRHPath"]); } + + private async Task HostingEnvironment(HttpContext context) + { + var hostingEnv = context.RequestServices.GetService(); + + await context.Response.WriteAsync("ContentRootPath "+hostingEnv.ContentRootPath + Environment.NewLine); + await context.Response.WriteAsync("WebRootPath "+hostingEnv.WebRootPath + Environment.NewLine); + await context.Response.WriteAsync("CurrentDirectory "+Environment.CurrentDirectory); + } } } diff --git a/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt b/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt new file mode 100644 index 0000000000..e69de29bb2