Fix deployment parameters override (#1241)

This commit is contained in:
Pavel Krymets 2018-08-15 12:15:21 -07:00 committed by GitHub
parent 3e00887c2f
commit 60ca38ab56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 87 additions and 1136 deletions

View File

@ -176,9 +176,6 @@
</system.applicationHost>
<system.webServer>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" hostingModel="[HostingModel]" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
<serverRuntime />
<asp scriptErrorSentToBrowser="true">
@ -255,8 +252,6 @@
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
<add name="AspNetCoreModule" image="[ANCMPath]" />
<add name="AspNetCoreModuleV2" image="[ANCMV2Path]" />
</globalModules>
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
@ -931,11 +926,8 @@
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
<add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler,runtimeVersionv2.0" />
<add name="AspNetCoreModule" />
<add name="AspNetCoreModuleV2"/>
</modules>
<handlers accessPolicy="Read, Script">
<add name="aspNetCore" path="*" verb="*" modules="[AspNetCoreModule]" resourceType="Unspecified" />
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
<add name="AXD-ISAPI-4.0_64bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
@ -1031,4 +1023,4 @@
</handlers>
</system.webServer>
</location>
</configuration>
</configuration>

View File

@ -276,32 +276,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
private void ConfigureAppHostConfig(XElement config, string contentRoot, int port)
{
var siteElement = config
.RequiredElement("system.applicationHost")
.RequiredElement("sites")
.RequiredElement("site");
siteElement
.RequiredElement("application")
.RequiredElement("virtualDirectory")
.SetAttributeValue("physicalPath", contentRoot);
siteElement
.RequiredElement("bindings")
.RequiredElement("binding")
.SetAttributeValue("bindingInformation", $"*:{port}:");
var ancmVersion = DeploymentParameters.AncmVersion.ToString();
config
.RequiredElement("system.webServer")
.RequiredElement("globalModules")
.GetOrAdd("add", "name", ancmVersion)
.SetAttributeValue("image", GetAncmLocation(DeploymentParameters.AncmVersion));
ConfigureModuleAndBinding(config, contentRoot, port);
// In IISExpress system.webServer/modules in under location element
config
.RequiredElement("system.webServer")
.RequiredElement("modules")
.GetOrAdd("add", "name", ancmVersion);
.GetOrAdd("add", "name", DeploymentParameters.AncmVersion.ToString());
var pool = config
.RequiredElement("system.applicationHost")

View File

@ -124,5 +124,30 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
.SetAttributeValue("value", handlerSetting.Value);
}
}
protected void ConfigureModuleAndBinding(XElement config, string contentRoot, int port)
{
var siteElement = config
.RequiredElement("system.applicationHost")
.RequiredElement("sites")
.RequiredElement("site");
siteElement
.RequiredElement("application")
.RequiredElement("virtualDirectory")
.SetAttributeValue("physicalPath", contentRoot);
siteElement
.RequiredElement("bindings")
.RequiredElement("binding")
.SetAttributeValue("bindingInformation", $":{port}:localhost");
var ancmVersion = DeploymentParameters.AncmVersion.ToString();
config
.RequiredElement("system.webServer")
.RequiredElement("globalModules")
.GetOrAdd("add", "name", ancmVersion)
.SetAttributeValue("image", GetAncmLocation(DeploymentParameters.AncmVersion));
}
}
}

View File

@ -91,6 +91,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath;
}
RunWebConfigActions(contentRoot);
var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint);
// Launch the host process.
@ -260,40 +262,35 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
private void PrepareConfig(string contentRoot, int port)
{
var serverConfig = DeploymentParameters.ServerConfigTemplateContent;;
// Config is required. If not present then fall back to one we carry with us.
if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent))
if (string.IsNullOrEmpty(serverConfig))
{
using (var stream = GetType().Assembly.GetManifestResourceStream("Microsoft.AspNetCore.Server.IntegrationTesting.IIS.Http.config"))
using (var reader = new StreamReader(stream))
{
DeploymentParameters.ServerConfigTemplateContent = reader.ReadToEnd();
serverConfig = reader.ReadToEnd();
}
}
var serverConfig = DeploymentParameters.ServerConfigTemplateContent;
XDocument config = XDocument.Parse(serverConfig);
// Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config
// We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo.
serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", AncmVersion.AspNetCoreModule, serverConfig);
serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", AncmVersion.AspNetCoreModuleV2, serverConfig);
serverConfig = ReplacePlaceholder(serverConfig, "[PORT]", port.ToString(CultureInfo.InvariantCulture));
serverConfig = ReplacePlaceholder(serverConfig, "[ApplicationPhysicalPath]", contentRoot);
config.Root
.RequiredElement("location")
.RequiredElement("system.webServer")
.RequiredElement("modules")
.GetOrAdd("add", "name", DeploymentParameters.AncmVersion.ToString());
if (DeploymentParameters.PublishApplicationBeforeDeployment)
{
serverConfig = RemoveRedundantElements(serverConfig);
}
else
ConfigureModuleAndBinding(config.Root, contentRoot, port);
if (!DeploymentParameters.PublishApplicationBeforeDeployment)
{
// The elements normally in the web.config are in the applicationhost.config for unpublished apps.
serverConfig = ReplacePlaceholder(serverConfig, "[HostingModel]", DeploymentParameters.HostingModel.ToString());
serverConfig = ReplacePlaceholder(serverConfig, "[AspNetCoreModule]", DeploymentParameters.AncmVersion.ToString());
AddAspNetCoreElement(config.Root);
}
RunWebConfigActions(contentRoot);
var config = XDocument.Parse(serverConfig);
RunServerConfigActions(config.Root, contentRoot);
serverConfig = config.ToString();
@ -303,14 +300,31 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig);
}
private string ReplacePlaceholder(string content, string field, string value)
private void AddAspNetCoreElement(XElement config)
{
if (content.Contains(field))
{
content = content.Replace(field, value);
Logger.LogDebug("Writing {field} '{value}' to config", field, value);
}
return content;
var aspNetCore = config
.RequiredElement("system.webServer")
.GetOrAdd("aspNetCore");
aspNetCore.SetAttributeValue("hostingModel", DeploymentParameters.HostingModel.ToString());
aspNetCore.SetAttributeValue("arguments", "%LAUNCHER_ARGS%");
aspNetCore.SetAttributeValue("processPath", "%LAUNCHER_PATH%");
var handlers = config
.RequiredElement("location")
.RequiredElement("system.webServer")
.RequiredElement("handlers");
var aspNetCoreHandler = handlers
.GetOrAdd("add", "name", "aspNetCore");
aspNetCoreHandler.SetAttributeValue("path", "*");
aspNetCoreHandler.SetAttributeValue("verb", "*");
aspNetCoreHandler.SetAttributeValue("modules", DeploymentParameters.AncmVersion.ToString());
aspNetCoreHandler.SetAttributeValue("resourceType", "Unspecified");
// Make aspNetCore handler first
aspNetCoreHandler.Remove();
handlers.AddFirst(aspNetCoreHandler);
}
protected override IEnumerable<Action<XElement, string>> GetWebConfigActions()
@ -347,18 +361,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
}
}
private string ModifyANCMPathInConfig(string replaceFlag, AncmVersion version, string serverConfig)
{
if (serverConfig.Contains(replaceFlag))
{
var ancmFile = GetAncmLocation(version);
Logger.LogDebug($"Writing '{replaceFlag}' '{ancmFile}' to config");
return serverConfig.Replace(replaceFlag, ancmFile);
}
return serverConfig;
}
private string GetIISExpressPath()
{
var programFiles = "Program Files";
@ -477,21 +479,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
throw new InvalidOperationException($"iisexpress Process {hostProcess.Id} crashed before shutdown was triggered.");
}
}
// These elements are duplicated in the web.config if you publish. Remove them from the host.config.
private string RemoveRedundantElements(string serverConfig)
{
var hostConfig = XDocument.Parse(serverConfig);
var coreElement = hostConfig.Descendants("aspNetCore").FirstOrDefault();
coreElement?.Remove();
var handlersElement = hostConfig.Descendants("handlers").First();
var handlerElement = handlersElement.Descendants("add")
.Where(x => x.Attribute("name").Value == "aspNetCore").FirstOrDefault();
handlerElement?.Remove();
return hostConfig.ToString();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -37,11 +37,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
// Must publish to set env vars in web.config
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
// Workaround "PublishedSitesFixture.GetBaseDeploymentParameters() overrides too many properties of baseParameters"
// https://github.com/aspnet/IISIntegration/issues/1237
deploymentParameters.AncmVersion = variant.AncmVersion;
var port = GetUnusedRandomPort();
deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_PORT"] = port.ToString();

View File

@ -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.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.AspNetCore.Testing.xunit;
using Xunit;
@ -30,9 +33,16 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
[MemberData(nameof(TestVariants))]
public async Task HelloWorld(TestVariant variant)
{
// The default in hosting sets windows auth to true.
// Set it to the IISExpress.config file
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
deploymentParameters.ServerConfigActionList.Add(
(element, _) => {
element
.RequiredElement("system.webServer")
.RequiredElement("security")
.RequiredElement("authentication")
.Element("windowsAuthentication")
?.SetAttributeValue("enabled", "false");
});
var deploymentResult = await DeployAsync(deploymentParameters);
@ -63,6 +73,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
$"WebRootPath {deploymentResult.ContentRoot}\\wwwroot" + Environment.NewLine +
$"CurrentDirectory {deploymentResult.ContentRoot}",
await deploymentResult.HttpClient.GetStringAsync("/HostingEnvironment"));
var expectedDll = variant.AncmVersion == AncmVersion.AspNetCoreModule ? "aspnetcore.dll" : "aspnetcorev2.dll";
Assert.Contains(deploymentResult.HostProcess.Modules.OfType<ProcessModule>(), m=> m.FileName.Contains(expectedDll));
}
}
}

View File

@ -49,7 +49,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
publisher,
new DeploymentParameters(publisher.ApplicationPath, DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
{
HostingModel = hostingModel
HostingModel = hostingModel,
TargetFramework = "netcoreapp2.2",
AncmVersion = AncmVersion.AspNetCoreModuleV2
},
publish);
}
@ -60,10 +62,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
ApplicationPublisher = publisher,
ApplicationPath = publisher.ApplicationPath,
TargetFramework = Tfm.NetCoreApp22,
ApplicationType = ApplicationType.Portable,
AncmVersion = AncmVersion.AspNetCoreModuleV2,
PublishApplicationBeforeDeployment = publish,
PublishApplicationBeforeDeployment = publish
};
}
}

View File

@ -28,11 +28,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
parameters.EnvironmentVariables[DebugEnvironmentVariable] = "console";
}
if (parameters.ServerType == ServerType.IISExpress)
{
parameters.ServerConfigTemplateContent = parameters.ServerConfigTemplateContent ?? File.ReadAllText("IISExpress.config");
}
if (parameters.ApplicationPublisher == null)
{
throw new InvalidOperationException("All tests should use ApplicationPublisher");