diff --git a/IISIntegration.sln b/IISIntegration.sln
index 4086f09be5..e14a378b23 100644
--- a/IISIntegration.sln
+++ b/IISIntegration.sln
@@ -29,7 +29,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration.Tests", "test\Microsoft.AspNetCore.Server.IISIntegration.Tests\Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj", "{4106DB10-E09F-480E-9CE6-B39235512EE6}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestSites", "test\TestSites\TestSites.csproj", "{F54715C3-88D8-49E3-A291-C13570FE81FC}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OutOfProcessWebSite", "test\WebSites\OutOfProcessWebSite\OutOfProcessWebSite.csproj", "{F54715C3-88D8-49E3-A291-C13570FE81FC}"
ProjectSection(ProjectDependencies) = postProject
{D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
@@ -54,7 +54,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeIISSample", "samples\
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISTestSite", "test\IISTestSite\IISTestSite.csproj", "{679FA2A2-898B-4320-884E-C2D294A97CE1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcessWebSite", "test\WebSites\InProcessWebSite\InProcessWebSite.csproj", "{679FA2A2-898B-4320-884E-C2D294A97CE1}"
ProjectSection(ProjectDependencies) = postProject
{D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
@@ -72,7 +72,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCoreModuleTests", "test\AspNetCoreModuleTests\AspNetCoreModuleTests.vcxproj", "{0692D963-DB10-4387-B3EA-460FBB9BD9A3}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ANCMStressTestApp", "test\ANCMStressTestApp\ANCMStressTestApp.csproj", "{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StressTestWebSite", "test\WebSites\StressTestWebSite\StressTestWebSite.csproj", "{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestTasks", "test\TestTasks\TestTasks.csproj", "{064D860B-4D7C-4B1D-918F-E020F1B99E2A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OverriddenServerWebSite", "test\WebSites\OverriddenServerWebSite\OverriddenServerWebSite.csproj", "{FC2A97F8-A749-4C04-97D1-97500066A820}"
+ ProjectSection(ProjectDependencies) = postProject
+ {D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
+ {439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -120,18 +130,18 @@ Global
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|x64.Build.0 = Release|Any CPU
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|x86.ActiveCfg = Release|Any CPU
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|x86.Build.0 = Release|Any CPU
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|Any CPU.ActiveCfg = Debug|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|Any CPU.Build.0 = Debug|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x64.ActiveCfg = Debug|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x64.Build.0 = Debug|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x86.ActiveCfg = Debug|x86
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x86.Build.0 = Debug|x86
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|Any CPU.ActiveCfg = Release|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|Any CPU.Build.0 = Release|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x64.ActiveCfg = Release|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x64.Build.0 = Release|x64
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x86.ActiveCfg = Release|x86
- {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x86.Build.0 = Release|x86
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x64.Build.0 = Debug|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x86.Build.0 = Debug|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x64.ActiveCfg = Release|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x64.Build.0 = Release|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x86.ActiveCfg = Release|Any CPU
+ {F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x86.Build.0 = Release|Any CPU
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -156,18 +166,18 @@ Global
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x64.Build.0 = Release|x64
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x86.ActiveCfg = Release|x86
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x86.Build.0 = Release|x86
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|Any CPU.ActiveCfg = Debug|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|Any CPU.Build.0 = Debug|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.ActiveCfg = Debug|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.Build.0 = Debug|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.ActiveCfg = Debug|x86
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.Build.0 = Debug|x86
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|Any CPU.ActiveCfg = Release|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|Any CPU.Build.0 = Release|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.ActiveCfg = Release|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.Build.0 = Release|x64
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.ActiveCfg = Release|x86
- {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.Build.0 = Release|x86
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.Build.0 = Debug|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.Build.0 = Debug|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.ActiveCfg = Release|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.Build.0 = Release|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.ActiveCfg = Release|Any CPU
+ {679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.Build.0 = Release|Any CPU
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Any CPU.ActiveCfg = Debug|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x64.ActiveCfg = Debug|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x64.Build.0 = Debug|x64
@@ -230,18 +240,40 @@ Global
{0692D963-DB10-4387-B3EA-460FBB9BD9A3}.Release|x64.Build.0 = Release|x64
{0692D963-DB10-4387-B3EA-460FBB9BD9A3}.Release|x86.ActiveCfg = Release|Win32
{0692D963-DB10-4387-B3EA-460FBB9BD9A3}.Release|x86.Build.0 = Release|Win32
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x64.ActiveCfg = Debug|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x64.Build.0 = Debug|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x86.ActiveCfg = Debug|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x86.Build.0 = Debug|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|Any CPU.Build.0 = Release|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x64.ActiveCfg = Release|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x64.Build.0 = Release|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x86.ActiveCfg = Release|Any CPU
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x86.Build.0 = Release|Any CPU
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x64.ActiveCfg = Debug|x64
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x64.Build.0 = Debug|x64
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x86.ActiveCfg = Debug|x86
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x86.Build.0 = Debug|x86
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|Any CPU.ActiveCfg = Release|x86
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x64.ActiveCfg = Release|x64
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x64.Build.0 = Release|x64
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x86.ActiveCfg = Release|x86
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x86.Build.0 = Release|x86
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x64.Build.0 = Debug|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x86.Build.0 = Debug|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x64.ActiveCfg = Release|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x64.Build.0 = Release|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x86.ActiveCfg = Release|Any CPU
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x86.Build.0 = Release|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x64.Build.0 = Debug|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x86.Build.0 = Debug|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x64.ActiveCfg = Release|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x64.Build.0 = Release|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x86.ActiveCfg = Release|Any CPU
+ {FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -250,17 +282,20 @@ Global
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
{8B3446E8-E6A8-4591-AA63-A95837C6E97C} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{4106DB10-E09F-480E-9CE6-B39235512EE6} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
- {F54715C3-88D8-49E3-A291-C13570FE81FC} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
+ {F54715C3-88D8-49E3-A291-C13570FE81FC} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
- {679FA2A2-898B-4320-884E-C2D294A97CE1} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
+ {679FA2A2-898B-4320-884E-C2D294A97CE1} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{55494E58-E061-4C4C-A0A8-837008E72F85} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{D57EA297-6DC2-4BC0-8C91-334863327863} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{46A8612B-418B-4D70-B3A7-A21DD0627473} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{0692D963-DB10-4387-B3EA-460FBB9BD9A3} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
- {13FD8F12-FFBE-4D01-B4AC-444F2994B04F} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
+ {13FD8F12-FFBE-4D01-B4AC-444F2994B04F} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
+ {064D860B-4D7C-4B1D-918F-E020F1B99E2A} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
+ {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
+ {FC2A97F8-A749-4C04-97D1-97500066A820} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
diff --git a/build/dependencies.props b/build/dependencies.props
index 057ebd9114..5cd40704ec 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -4,43 +4,46 @@
2.1.0-preview3-17001
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 0.5.0-preview2-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
- 2.1.0-preview3-32037
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 0.5.0-preview2-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 15.6.82
+ 15.6.82
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
+ 2.1.0-preview3-32094
1.1.0
- 2.1.0-preview3-32037
+ 2.1.0-preview3-32094
2.0.0
- 2.1.0-preview2-26314-02
- 2.1.0-preview3-32037
+ 2.1.0-preview2-26326-03
+ 2.1.0-preview3-32094
15.6.1
7.0.0
- 4.5.0-preview2-26313-01
- 4.5.0-preview2-26313-01
+ 4.5.0-preview2-26326-04
+ 4.5.0-preview2-26326-04
6.1.7601.17515
- 4.5.0-preview2-26313-01
- 4.5.0-preview2-26313-01
- 4.5.0-preview2-26313-01
- 4.5.0-preview2-26313-01
- 4.5.0-preview2-26313-01
+ 4.5.0-preview2-26326-04
+ 4.5.0-preview2-26326-04
+ 4.5.0-preview2-26326-04
+ 4.5.0-preview2-26326-04
+ 4.5.0-preview2-26326-04
+ 9.0.1
2.3.1
2.4.0-beta.1.build3945
diff --git a/test/TestSites/Properties/launchSettings.json b/build/launchSettings.json
similarity index 97%
rename from test/TestSites/Properties/launchSettings.json
rename to build/launchSettings.json
index 7d09a120ab..6d5ce43f73 100644
--- a/test/TestSites/Properties/launchSettings.json
+++ b/build/launchSettings.json
@@ -12,6 +12,7 @@
"commandName": "Executable",
"executablePath": "$(IISExpressPath)",
"commandLineArgs": "$(IISExpressArguments)",
+ "nativeDebugging": true,
"environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(TargetDir)$(AncmPath)",
diff --git a/build/testsite.props b/build/testsite.props
index 549556790f..0a3f00ac79 100644
--- a/build/testsite.props
+++ b/build/testsite.props
@@ -8,15 +8,7 @@
x64
$(Platform)
-
-
-
-
-
-
-
-
-
+
$(MSBuildProgramFiles32)\IIS Express\iisexpress.exe
$(SystemRoot)\SysWOW64\inetsrv\w3wp.exe
@@ -29,12 +21,61 @@
x64
+
+
+
+
+
+
+
/config:"$(IISExpressAppHostConfig)"
-h "$(IISAppHostConfig)"
$(NativePlatform)\aspnetcore.dll
+ $(NativePlatform)\aspnetcorerh.dll
$(userprofile)\.dotnet\$(NativePlatform)\dotnet.exe
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+
+
+ $(MSBuildThisFileDirectory)..\test\TestTasks\bin\$(Configuration)\$(TargetFramework)\TestTasks
+
+ $(InjectDepsAssembly)
+ "win7-$(NativePlatform)" "$(AncmRHPath)"
+
+
+
+ $(InjectDepsAssembly).exe
+ $(InjectDepsAssembly)
+
+
+
+ $(InjectDepsAssembly).dll
+ dotnet
+ $(InjectDepsAssembly) $(InjectDepsArguments)
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/NativeIISSample/NativeIISSample.csproj b/samples/NativeIISSample/NativeIISSample.csproj
index d35016b658..d9bf22ba16 100644
--- a/samples/NativeIISSample/NativeIISSample.csproj
+++ b/samples/NativeIISSample/NativeIISSample.csproj
@@ -17,5 +17,4 @@
inprocess
-
diff --git a/src/CommonLib/hostfxr_utility.cpp b/src/CommonLib/hostfxr_utility.cpp
index b7fe5a1eea..6d3d6d74a0 100644
--- a/src/CommonLib/hostfxr_utility.cpp
+++ b/src/CommonLib/hostfxr_utility.cpp
@@ -164,19 +164,25 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
{
HRESULT hr = S_OK;
STRU struSystemPathVariable;
- STRU struHostFxrPath;
- STRU struExeLocation;
- STRU struHostFxrSearchExpression;
- STRU struHighestDotnetVersion;
+ STRU struAbsolutePathToHostFxr;
+ STRU struAbsolutePathToDotnet;
STRU struEventMsg;
- std::vector vVersionFolders;
- DWORD dwPosition;
+ STACK_STRU(struExpandedProcessPath, MAX_PATH);
+ STACK_STRU(struExpandedArguments, MAX_PATH);
- // Convert the process path an absolute path.
+ // Copy and Expand the processPath and Arguments.
+ if (FAILED(hr = struExpandedProcessPath.CopyAndExpandEnvironmentStrings(pcwzProcessPath))
+ || FAILED(hr = struExpandedArguments.CopyAndExpandEnvironmentStrings(pcwzArguments)))
+ {
+ goto Finished;
+ }
+
+ // Convert the process path an absolute path to our current application directory.
+ // If the path is already an absolute path, it will be unchanged.
hr = UTILITY::ConvertPathToFullPath(
- pcwzProcessPath,
+ struExpandedProcessPath.QueryStr(),
pcwzApplicationPhysicalPath,
- &struExeLocation
+ &struAbsolutePathToDotnet
);
if (FAILED(hr))
@@ -184,152 +190,76 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
goto Finished;
}
- if (UTILITY::CheckIfFileExists(struExeLocation.QueryStr()))
+ // Check if the absolute path is to dotnet or not.
+ if (struAbsolutePathToDotnet.EndsWith(L"dotnet.exe") || struAbsolutePathToDotnet.EndsWith(L"dotnet"))
{
- // Check if hostfxr is in this folder, if it is, we are a standalone application,
- // else we assume we received an absolute path to dotnet.exe
- if (!struExeLocation.EndsWith(L"dotnet.exe") &&
- !struExeLocation.EndsWith(L"dotnet"))
+ //
+ // The processPath ends with dotnet.exe or dotnet
+ // like: C:\Program Files\dotnet\dotnet.exe, C:\Program Files\dotnet\dotnet, dotnet.exe, or dotnet.
+ // Get the absolute path to dotnet. If the path is already an absolute path, it will return that path
+ //
+ if (FAILED(hr = HOSTFXR_UTILITY::GetAbsolutePathToDotnet(&struAbsolutePathToDotnet))) // Make sure to append the dotnet.exe path correctly here (pass in regular path)?
+ {
+ goto Finished;
+ }
+
+ if (FAILED(hr = GetAbsolutePathToHostFxr(&struAbsolutePathToDotnet, hEventLog, &struAbsolutePathToHostFxr)))
+ {
+ goto Finished;
+ }
+
+ if (FAILED(hr = ParseHostfxrArguments(
+ struExpandedArguments.QueryStr(),
+ struAbsolutePathToDotnet.QueryStr(),
+ pcwzApplicationPhysicalPath,
+ hEventLog,
+ pdwArgCount,
+ pbstrArgv)))
+ {
+ goto Finished;
+ }
+
+ if (FAILED(hr = struHostFxrDllLocation->Copy(struAbsolutePathToHostFxr)))
{
- hr = GetStandaloneHostfxrParameters(
- struExeLocation.QueryStr(),
- pcwzApplicationPhysicalPath,
- pcwzArguments,
- hEventLog,
- struHostFxrDllLocation,
- pdwArgCount,
- pbstrArgv);
goto Finished;
}
}
else
{
- if (FAILED(hr = HOSTFXR_UTILITY::FindDotnetExePath(&struExeLocation)))
+ //
+ // The processPath is a path to the application executable
+ // like: C:\test\MyApp.Exe or MyApp.Exe
+ // Check if the file exists, and if it does, get the parameters for a standalone application
+ //
+ if (UTILITY::CheckIfFileExists(struAbsolutePathToDotnet.QueryStr()))
{
- goto Finished;
+ hr = GetStandaloneHostfxrParameters(
+ struAbsolutePathToDotnet.QueryStr(),
+ pcwzApplicationPhysicalPath,
+ struExpandedArguments.QueryStr(),
+ hEventLog,
+ struHostFxrDllLocation,
+ pdwArgCount,
+ pbstrArgv);
}
- }
-
- if (FAILED(hr = struExeLocation.SyncWithBuffer()) ||
- FAILED(hr = struHostFxrPath.Copy(struExeLocation)))
- {
- goto Finished;
- }
-
- dwPosition = struHostFxrPath.LastIndexOf(L'\\', 0);
- if (dwPosition == -1)
- {
- hr = E_FAIL;
- goto Finished;
- }
-
- struHostFxrPath.QueryStr()[dwPosition] = L'\0';
-
- if (FAILED(hr = struHostFxrPath.SyncWithBuffer()) ||
- FAILED(hr = struHostFxrPath.Append(L"\\")))
- {
- goto Finished;
- }
-
- hr = struHostFxrPath.Append(L"host\\fxr");
- if (FAILED(hr))
- {
- goto Finished;
- }
-
- if (!UTILITY::DirectoryExists(&struHostFxrPath))
- {
- hr = ERROR_BAD_ENVIRONMENT;
- if (SUCCEEDED(struEventMsg.SafeSnwprintf(
- ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG,
- struHostFxrPath.QueryStr(),
- hr)))
+ else
{
- UTILITY::LogEvent(hEventLog,
- EVENTLOG_ERROR_TYPE,
- ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND,
- struEventMsg.QueryStr());
+ //
+ // If the processPath file does not exist and it doesn't include dotnet.exe or dotnet
+ // then it is an invalid argument.
+ //
+ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);;
+ if (SUCCEEDED(struEventMsg.SafeSnwprintf(
+ ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG,
+ struExpandedProcessPath.QueryStr(),
+ hr)))
+ {
+ UTILITY::LogEvent(hEventLog,
+ EVENTLOG_ERROR_TYPE,
+ ASPNETCORE_EVENT_GENERAL_ERROR_MSG,
+ struEventMsg.QueryStr());
+ }
}
- goto Finished;
- }
-
- // Find all folders under host\\fxr\\ for version numbers.
- hr = struHostFxrSearchExpression.Copy(struHostFxrPath);
- if (FAILED(hr))
- {
- goto Finished;
- }
-
- hr = struHostFxrSearchExpression.Append(L"\\*");
- if (FAILED(hr))
- {
- goto Finished;
- }
-
- // As we use the logic from core-setup, we are opting to use std here.
- // TODO remove all uses of std?
- UTILITY::FindDotNetFolders(struHostFxrSearchExpression.QueryStr(), &vVersionFolders);
-
- if (vVersionFolders.size() == 0)
- {
- hr = HRESULT_FROM_WIN32(ERROR_BAD_ENVIRONMENT);
- if (SUCCEEDED(struEventMsg.SafeSnwprintf(
- ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG,
- struHostFxrPath.QueryStr(),
- hr)))
- {
- UTILITY::LogEvent(hEventLog,
- EVENTLOG_ERROR_TYPE,
- ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND,
- struEventMsg.QueryStr());
- }
- goto Finished;
- }
-
- hr = UTILITY::FindHighestDotNetVersion(vVersionFolders, &struHighestDotnetVersion);
- if (FAILED(hr))
- {
- goto Finished;
- }
-
- if (FAILED(hr = struHostFxrPath.Append(L"\\"))
- || FAILED(hr = struHostFxrPath.Append(struHighestDotnetVersion.QueryStr()))
- || FAILED(hr = struHostFxrPath.Append(L"\\hostfxr.dll")))
- {
- goto Finished;
- }
-
- if (!UTILITY::CheckIfFileExists(struHostFxrPath.QueryStr()))
- {
- // ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG
- hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
- if (SUCCEEDED(struEventMsg.SafeSnwprintf(
- ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG,
- struHostFxrPath.QueryStr(),
- hr)))
- {
- UTILITY::LogEvent(hEventLog,
- EVENTLOG_ERROR_TYPE,
- ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND,
- struEventMsg.QueryStr());
- }
- goto Finished;
- }
-
- if (FAILED(hr = ParseHostfxrArguments(
- pcwzArguments,
- struExeLocation.QueryStr(),
- pcwzApplicationPhysicalPath,
- hEventLog,
- pdwArgCount,
- pbstrArgv)))
- {
- goto Finished;
- }
-
- if (FAILED(hr = struHostFxrDllLocation->Copy(struHostFxrPath)))
- {
- goto Finished;
}
Finished:
@@ -383,7 +313,7 @@ HOSTFXR_UTILITY::ParseHostfxrArguments(
goto Failure;
}
- argv = new PWSTR[argc + 1];
+ argv = new BSTR[argc + 1];
if (argv == NULL)
{
hr = E_OUTOFMEMORY;
@@ -457,41 +387,220 @@ Finished:
return hr;
}
-//
-// Invoke where.exe to find the location of dotnet.exe
-// Copies contents of dotnet.exe to a temp file
-// Respects path ordering.
HRESULT
-HOSTFXR_UTILITY::FindDotnetExePath(
- _Out_ STRU* struDotnetPath
+HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
+ _Inout_ STRU* pStruAbsolutePathToDotnet
)
{
HRESULT hr = S_OK;
+
+ //
+ // If we are given an absolute path to dotnet.exe, we are done
+ //
+ if (UTILITY::CheckIfFileExists(pStruAbsolutePathToDotnet->QueryStr()))
+ {
+ goto Finished;
+ }
+
+ //
+ // If the path was C:\Program Files\dotnet\dotnet
+ // We need to try appending .exe and check if the file exists too.
+ //
+ if (FAILED(hr = pStruAbsolutePathToDotnet->Append(L".exe")))
+ {
+ goto Finished;
+ }
+
+ if (UTILITY::CheckIfFileExists(pStruAbsolutePathToDotnet->QueryStr()))
+ {
+ goto Finished;
+ }
+
+ // At this point, we are calling where.exe to find dotnet.
+ // If we encounter any failures, try getting dotnet.exe from the
+ // backup location.
+ if (!InvokeWhereToFindDotnet(pStruAbsolutePathToDotnet))
+ {
+ hr = GetAbsolutePathToDotnetFromProgramFiles(pStruAbsolutePathToDotnet);
+ }
+
+Finished:
+
+ return hr;
+}
+
+HRESULT
+HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
+ STRU* pStruAbsolutePathToDotnet,
+ HANDLE hEventLog,
+ STRU* pStruAbsolutePathToHostfxr
+)
+{
+ HRESULT hr = S_OK;
+ STRU struHostFxrPath;
+ STRU struHostFxrSearchExpression;
+ STRU struHighestDotnetVersion;
+ STRU struEventMsg;
+ std::vector vVersionFolders;
+ DWORD dwPosition = 0;
+
+ if (FAILED(hr = struHostFxrPath.Copy(pStruAbsolutePathToDotnet)))
+ {
+ goto Finished;
+ }
+
+ dwPosition = struHostFxrPath.LastIndexOf(L'\\', 0);
+ if (dwPosition == -1)
+ {
+ hr = E_FAIL;
+ goto Finished;
+ }
+
+ struHostFxrPath.QueryStr()[dwPosition] = L'\0';
+
+ if (FAILED(hr = struHostFxrPath.SyncWithBuffer()) ||
+ FAILED(hr = struHostFxrPath.Append(L"\\")))
+ {
+ goto Finished;
+ }
+
+ hr = struHostFxrPath.Append(L"host\\fxr");
+ if (FAILED(hr))
+ {
+ goto Finished;
+ }
+
+ if (!UTILITY::DirectoryExists(&struHostFxrPath))
+ {
+ hr = ERROR_BAD_ENVIRONMENT;
+ if (SUCCEEDED(struEventMsg.SafeSnwprintf(
+ ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG,
+ struHostFxrPath.QueryStr(),
+ hr)))
+ {
+ UTILITY::LogEvent(hEventLog,
+ EVENTLOG_ERROR_TYPE,
+ ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND,
+ struEventMsg.QueryStr());
+ }
+ goto Finished;
+ }
+
+ // Find all folders under host\\fxr\\ for version numbers.
+ hr = struHostFxrSearchExpression.Copy(struHostFxrPath);
+ if (FAILED(hr))
+ {
+ goto Finished;
+ }
+
+ hr = struHostFxrSearchExpression.Append(L"\\*");
+ if (FAILED(hr))
+ {
+ goto Finished;
+ }
+
+ // As we use the logic from core-setup, we are opting to use std here.
+ UTILITY::FindDotNetFolders(struHostFxrSearchExpression.QueryStr(), &vVersionFolders);
+
+ if (vVersionFolders.size() == 0)
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_BAD_ENVIRONMENT);
+ if (SUCCEEDED(struEventMsg.SafeSnwprintf(
+ ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG,
+ struHostFxrPath.QueryStr(),
+ hr)))
+ {
+ UTILITY::LogEvent(hEventLog,
+ EVENTLOG_ERROR_TYPE,
+ ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND,
+ struEventMsg.QueryStr());
+ }
+ goto Finished;
+ }
+
+ hr = UTILITY::FindHighestDotNetVersion(vVersionFolders, &struHighestDotnetVersion);
+ if (FAILED(hr))
+ {
+ goto Finished;
+ }
+
+ if (FAILED(hr = struHostFxrPath.Append(L"\\"))
+ || FAILED(hr = struHostFxrPath.Append(struHighestDotnetVersion.QueryStr()))
+ || FAILED(hr = struHostFxrPath.Append(L"\\hostfxr.dll")))
+ {
+ goto Finished;
+ }
+
+ if (!UTILITY::CheckIfFileExists(struHostFxrPath.QueryStr()))
+ {
+ // ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG
+ hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
+ if (SUCCEEDED(struEventMsg.SafeSnwprintf(
+ ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG,
+ struHostFxrPath.QueryStr(),
+ hr)))
+ {
+ UTILITY::LogEvent(hEventLog,
+ EVENTLOG_ERROR_TYPE,
+ ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND,
+ struEventMsg.QueryStr());
+ }
+ goto Finished;
+ }
+
+ if (FAILED(hr = pStruAbsolutePathToHostfxr->Copy(struHostFxrPath)))
+ {
+ goto Finished;
+ }
+
+Finished:
+ return hr;
+}
+
+//
+// Tries to call where.exe to find the location of dotnet.exe.
+// Will check that the bitness of dotnet matches the current
+// worker process bitness.
+// Returns true if a valid dotnet was found, else false.
+//
+BOOL
+HOSTFXR_UTILITY::InvokeWhereToFindDotnet(
+ _Inout_ STRU* pStruAbsolutePathToDotnet
+)
+{
+ HRESULT hr = S_OK;
+ // Arguments to call where.exe
STARTUPINFOW startupInfo = { 0 };
PROCESS_INFORMATION processInformation = { 0 };
SECURITY_ATTRIBUTES securityAttributes;
- STRU struDotnetSubstring;
- STRU struDotnetLocationsString;
- LPWSTR pwzDotnetName = NULL;
- DWORD dwExitCode;
- DWORD dwNumBytesRead;
- DWORD dwFilePointer;
- DWORD dwBinaryType;
- DWORD dwPathSize = MAX_PATH;
- INT index = 0;
- INT prevIndex = 0;
- BOOL fResult = FALSE;
- BOOL fIsWow64Process;
- BOOL fIsCurrentProcess64Bit;
- BOOL fFound = FALSE;
+
CHAR pzFileContents[READ_BUFFER_SIZE];
HANDLE hStdOutReadPipe = INVALID_HANDLE_VALUE;
HANDLE hStdOutWritePipe = INVALID_HANDLE_VALUE;
+ LPWSTR pwzDotnetName = NULL;
+ DWORD dwFilePointer;
+ BOOL fIsWow64Process;
+ BOOL fIsCurrentProcess64Bit;
+ DWORD dwExitCode;
+ STRU struDotnetSubstring;
+ STRU struDotnetLocationsString;
+ DWORD dwNumBytesRead;
+ DWORD dwBinaryType;
+ INT index = 0;
+ INT prevIndex = 0;
+ BOOL fProcessCreationResult = FALSE;
+ BOOL fResult = FALSE;
+ // Set the security attributes for the read/write pipe
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;
securityAttributes.bInheritHandle = TRUE;
+ // Reset the path to dotnet as we will be using whether the string is
+ // empty or not as state
+ pStruAbsolutePathToDotnet->Reset();
+
+ // Create a read/write pipe that will be used for reading the result of where.exe
if (!CreatePipe(&hStdOutReadPipe, &hStdOutWritePipe, &securityAttributes, 0))
{
hr = HRESULT_FROM_WIN32(GetLastError());
@@ -503,7 +612,7 @@ HOSTFXR_UTILITY::FindDotnetExePath(
goto Finished;
}
- // Set stdout and error to redirect to the temp file.
+ // Set the stdout and err pipe to the write pipes.
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
startupInfo.hStdOutput = hStdOutWritePipe;
@@ -511,14 +620,14 @@ HOSTFXR_UTILITY::FindDotnetExePath(
// CreateProcess requires a mutable string to be passed to commandline
// See https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083/
-
pwzDotnetName = SysAllocString(L"\"where.exe\" dotnet.exe");
if (pwzDotnetName == NULL)
{
- hr = E_OUTOFMEMORY;
goto Finished;
}
- fResult = CreateProcessW(NULL,
+
+ // Create a process to invoke where.exe
+ fProcessCreationResult = CreateProcessW(NULL,
pwzDotnetName,
NULL,
NULL,
@@ -530,14 +639,15 @@ HOSTFXR_UTILITY::FindDotnetExePath(
&processInformation
);
- if (!fResult)
+ if (!fProcessCreationResult)
{
- hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
- if (WaitForSingleObject(processInformation.hProcess, 2000) != WAIT_OBJECT_0) // 2 seconds
+ // Wait for where.exe to return, waiting 2 seconds.
+ if (WaitForSingleObject(processInformation.hProcess, 2000) != WAIT_OBJECT_0)
{
+ // Timeout occured, terminate the where.exe process and return.
TerminateProcess(processInformation.hProcess, 2);
hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
goto Finished;
@@ -550,131 +660,95 @@ HOSTFXR_UTILITY::FindDotnetExePath(
//
if (!GetExitCodeProcess(processInformation.hProcess, &dwExitCode))
{
- goto Fallback;
+ goto Finished;
}
//
// In this block, if anything fails, we will goto our fallback of
// looking in C:/Program Files/
//
- if (dwExitCode == 0)
+ if (dwExitCode != 0)
{
- // Where succeeded.
- // Reset file pointer to the beginning of the file.
- dwFilePointer = SetFilePointer(hStdOutReadPipe, 0, NULL, FILE_BEGIN);
- if (dwFilePointer == INVALID_SET_FILE_POINTER)
- {
- goto Fallback;
- }
-
- //
- // As the call to where.exe succeeded (dotnet.exe was found), ReadFile should not hang.
- // TODO consider putting ReadFile in a separate thread with a timeout to guarantee it doesn't block.
- //
- if (!ReadFile(hStdOutReadPipe, pzFileContents, READ_BUFFER_SIZE, &dwNumBytesRead, NULL))
- {
- goto Fallback;
- }
- if (dwNumBytesRead >= READ_BUFFER_SIZE)
- {
- // This shouldn't ever be this large. We could continue to call ReadFile in a loop,
- // however I'd rather error out here and report an issue.
- goto Fallback;
- }
-
- if (FAILED(hr = struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead)))
- {
- goto Finished;
- }
-
- // Check the bitness of the currently running process
- // matches the dotnet.exe found.
- if (!IsWow64Process(GetCurrentProcess(), &fIsWow64Process))
- {
- // Calling IsWow64Process failed
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto Finished;
- }
- if (fIsWow64Process)
- {
- // 32 bit mode
- fIsCurrentProcess64Bit = FALSE;
- }
- else
- {
- SYSTEM_INFO systemInfo;
- GetNativeSystemInfo(&systemInfo);
- fIsCurrentProcess64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
- }
-
- while (!fFound)
- {
- index = struDotnetLocationsString.IndexOf(L"\r\n", prevIndex);
- if (index == -1)
- {
- break;
- }
- if (FAILED(hr = struDotnetSubstring.Copy(&struDotnetLocationsString.QueryStr()[prevIndex], index - prevIndex)))
- {
- goto Finished;
- }
- // \r\n is two wchars, so add 2 here.
- prevIndex = index + 2;
-
- if (GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType) &&
- fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY)) {
- // Found a valid dotnet.
- if (FAILED(hr = struDotnetPath->Copy(struDotnetSubstring)))
- {
- goto Finished;
- }
- fFound = TRUE;
- }
- }
+ goto Finished;
}
-Fallback:
-
- // Look in ProgramFiles
- while (!fFound)
+ // Where succeeded.
+ // Reset file pointer to the beginning of the file.
+ dwFilePointer = SetFilePointer(hStdOutReadPipe, 0, NULL, FILE_BEGIN);
+ if (dwFilePointer == INVALID_SET_FILE_POINTER)
{
- if (FAILED(hr = struDotnetSubstring.Resize(dwPathSize)))
- {
- goto Finished;
- }
-
- // Program files will changes based on the
- dwNumBytesRead = GetEnvironmentVariable(L"ProgramFiles", struDotnetSubstring.QueryStr(), dwPathSize);
- if (dwNumBytesRead == 0)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto Finished;
- }
- else if (dwNumBytesRead == dwPathSize)
- {
- dwPathSize *= 2 + 30; // for dotnet substring
- }
- else
- {
- if (FAILED(hr = struDotnetSubstring.SyncWithBuffer()) ||
- FAILED(hr = struDotnetSubstring.Append(L"\\dotnet\\dotnet.exe")))
- {
- goto Finished;
- }
- if (!UTILITY::CheckIfFileExists(struDotnetSubstring.QueryStr()))
- {
- hr = HRESULT_FROM_WIN32( GetLastError() );
- goto Finished;
- }
- if (FAILED(hr = struDotnetPath->Copy(struDotnetSubstring)))
- {
- goto Finished;
- }
- fFound = TRUE;
- }
+ goto Finished;
}
+ //
+ // As the call to where.exe succeeded (dotnet.exe was found), ReadFile should not hang.
+ // TODO consider putting ReadFile in a separate thread with a timeout to guarantee it doesn't block.
+ //
+ if (!ReadFile(hStdOutReadPipe, pzFileContents, READ_BUFFER_SIZE, &dwNumBytesRead, NULL))
+ {
+ goto Finished;
+ }
+ if (dwNumBytesRead >= READ_BUFFER_SIZE)
+ {
+ // This shouldn't ever be this large. We could continue to call ReadFile in a loop,
+ // however if someone had this many dotnet.exes on their machine.
+ goto Finished;
+ }
+
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ if (FAILED(hr = struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead)))
+ {
+ goto Finished;
+ }
+
+ // Check the bitness of the currently running process
+ // matches the dotnet.exe found.
+ if (!IsWow64Process(GetCurrentProcess(), &fIsWow64Process))
+ {
+ // Calling IsWow64Process failed
+ goto Finished;
+ }
+ if (fIsWow64Process)
+ {
+ // 32 bit mode
+ fIsCurrentProcess64Bit = FALSE;
+ }
+ else
+ {
+ // Check the SystemInfo to see if we are currently 32 or 64 bit.
+ SYSTEM_INFO systemInfo;
+ GetNativeSystemInfo(&systemInfo);
+ fIsCurrentProcess64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
+ }
+
+ while (TRUE)
+ {
+ index = struDotnetLocationsString.IndexOf(L"\r\n", prevIndex);
+ if (index == -1)
+ {
+ break;
+ }
+ if (FAILED(hr = struDotnetSubstring.Copy(&struDotnetLocationsString.QueryStr()[prevIndex], index - prevIndex)))
+ {
+ goto Finished;
+ }
+ // \r\n is two wchars, so add 2 here.
+ prevIndex = index + 2;
+
+ if (GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType) &&
+ fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY))
+ {
+ // The bitness of dotnet matched with the current worker process bitness.
+ if (FAILED(hr = pStruAbsolutePathToDotnet->Copy(struDotnetSubstring)))
+ {
+ goto Finished;
+ }
+ fResult = TRUE;
+ break;
+ }
+ }
+
Finished:
if (hStdOutReadPipe != INVALID_HANDLE_VALUE)
@@ -698,5 +772,60 @@ Finished:
SysFreeString(pwzDotnetName);
}
+ return fResult;
+}
+
+
+HRESULT
+HOSTFXR_UTILITY::GetAbsolutePathToDotnetFromProgramFiles(
+ _Inout_ STRU* pStruAbsolutePathToDotnet
+)
+{
+ HRESULT hr = S_OK;
+ BOOL fFound = FALSE;
+ DWORD dwNumBytesRead = 0;
+ DWORD dwPathSize = MAX_PATH;
+ STRU struDotnetSubstring;
+
+ while (!fFound)
+ {
+ if (FAILED(hr = struDotnetSubstring.Resize(dwPathSize)))
+ {
+ goto Finished;
+ }
+
+ dwNumBytesRead = GetEnvironmentVariable(L"ProgramFiles", struDotnetSubstring.QueryStr(), dwPathSize);
+ if (dwNumBytesRead == 0)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto Finished;
+ }
+ else if (dwNumBytesRead >= dwPathSize)
+ {
+ //
+ // The path to ProgramFiles should never be this long, but resize and try again.
+ dwPathSize *= 2 + 30; // for dotnet substring
+ }
+ else
+ {
+ if (FAILED(hr = struDotnetSubstring.SyncWithBuffer()) ||
+ FAILED(hr = struDotnetSubstring.Append(L"\\dotnet\\dotnet.exe")))
+ {
+ goto Finished;
+ }
+ if (!UTILITY::CheckIfFileExists(struDotnetSubstring.QueryStr()))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto Finished;
+ }
+ if (FAILED(hr = pStruAbsolutePathToDotnet->Copy(struDotnetSubstring)))
+ {
+ goto Finished;
+ }
+ fFound = TRUE;
+ }
+ }
+
+Finished:
return hr;
}
diff --git a/src/CommonLib/hostfxr_utility.h b/src/CommonLib/hostfxr_utility.h
index 2effba31f1..e7703c5bfa 100644
--- a/src/CommonLib/hostfxr_utility.h
+++ b/src/CommonLib/hostfxr_utility.h
@@ -21,7 +21,7 @@ public:
PCWSTR pcwzProcessPath,
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
- _Inout_ STRU* struHostFxrDllLocation,
+ _Inout_ STRU* pStruHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
);
@@ -33,7 +33,7 @@ public:
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
HANDLE hEventLog,
- _Inout_ STRU* struHostFxrDllLocation,
+ _Inout_ STRU* pStruHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
);
@@ -46,13 +46,33 @@ public:
PCWSTR pcwzApplicationPhysicalPath,
HANDLE hEventLog,
_Out_ DWORD* pdwArgCount,
- _Out_ BSTR** ppwzArgv
+ _Out_ BSTR** ppwzArgv
);
static
HRESULT
- FindDotnetExePath(
- STRU* struDotnetLocation
+ GetAbsolutePathToDotnet(
+ STRU* pStruAbsolutePathToDotnet
+ );
+
+ static
+ HRESULT
+ GetAbsolutePathToHostFxr(
+ _In_ STRU* pStruAbsolutePathToDotnet,
+ _In_ HANDLE hEventLog,
+ _Out_ STRU* pStruAbsolutePathToHostfxr
+ );
+
+ static
+ BOOL
+ InvokeWhereToFindDotnet(
+ _Inout_ STRU* pStruAbsolutePathToDotnet
+ );
+
+ static
+ HRESULT
+ GetAbsolutePathToDotnetFromProgramFiles(
+ _Inout_ STRU* pStruAbsolutePathToDotnet
);
};
diff --git a/src/CommonLib/resources.h b/src/CommonLib/resources.h
index adba68b794..63a9cf301e 100644
--- a/src/CommonLib/resources.h
+++ b/src/CommonLib/resources.h
@@ -41,3 +41,4 @@
#define ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG L"Could not find hostfxr.dll in '%s'. ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_MSG L"Could not find application executable in '%s'. ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, ErrorCode = '0x%x. Please check the stderr logs for more information."
+#define ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG L"Invalid or unknown processPath provided in web.config: processPath = %s, ErrorCode = '0x%x'."
diff --git a/src/CommonLib/utility.h b/src/CommonLib/utility.h
index 49549c0f33..891f0f0092 100644
--- a/src/CommonLib/utility.h
+++ b/src/CommonLib/utility.h
@@ -118,7 +118,7 @@ public:
_In_ WORD dwEventInfoType,
_In_ DWORD dwEventId,
_In_ LPCWSTR pstrMsg
- );
+ );
private:
diff --git a/src/IISLib/util.cxx b/src/IISLib/util.cxx
index bde325025e..214ee65abf 100644
--- a/src/IISLib/util.cxx
+++ b/src/IISLib/util.cxx
@@ -61,13 +61,17 @@ Return Values:
return hr;
}
}
- else
+ else if (wcslen(pszName) > MAX_PATH)
{
if (FAILED(hr = pstrPath->Copy(L"\\\\?\\")))
{
return hr;
}
}
+ else
+ {
+ pstrPath->Reset();
+ }
return pstrPath->Append(pszName);
}
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs
index 00c9d5beb1..4f8c2ce10e 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs
@@ -7,24 +7,28 @@ using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.IISIntegration
{
- internal class NativeMethods
+ internal static class NativeMethods
{
-#if DOTNET5_4
- private const string api_ms_win_core_handle_LIB = "api-ms-win-core-handle-l1-1-0.dll";
-#else
+ private const int HR_NOT_FOUND = unchecked((int)0x80070490);
+ private const int HR_OK = 0;
+
private const string KERNEL32 = "kernel32.dll";
-#endif
-#if DOTNET5_4
- [DllImport(api_ms_win_core_handle_LIB, ExactSpelling = true, SetLastError = true)]
-#else
- [DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
-#endif
- internal static extern bool CloseHandle(IntPtr handle);
-
- public const int S_OK = 0;
private const string AspNetCoreModuleDll = "aspnetcorerh.dll";
+ [DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
+
+ public static extern bool CloseHandle(IntPtr handle);
+
+
+ [DllImport("kernel32.dll")]
+ private static extern IntPtr GetModuleHandle(string lpModuleName);
+
+ public static bool IsAspNetCoreModuleLoaded()
+ {
+ return GetModuleHandle(AspNetCoreModuleDll) != IntPtr.Zero;
+ }
+
public enum REQUEST_NOTIFICATION_STATUS
{
RQ_NOTIFICATION_CONTINUE,
@@ -37,85 +41,232 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
public delegate REQUEST_NOTIFICATION_STATUS PFN_ASYNC_COMPLETION(IntPtr pvManagedHttpContext, int hr, int bytes);
public delegate REQUEST_NOTIFICATION_STATUS PFN_WEBSOCKET_ASYNC_COMPLETION(IntPtr pInProcessHandler, IntPtr completionInfo, IntPtr pvCompletionContext);
- // TODO make this all internal
[DllImport(AspNetCoreModuleDll)]
- public static extern int http_post_completion(IntPtr pInProcessHandler, int cbBytes);
+ private static extern int http_post_completion(IntPtr pInProcessHandler, int cbBytes);
[DllImport(AspNetCoreModuleDll)]
- public static extern int http_set_completion_status(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS rquestNotificationStatus);
+ private static extern int http_set_completion_status(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS rquestNotificationStatus);
[DllImport(AspNetCoreModuleDll)]
- public static extern void http_indicate_completion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus);
+ private static extern void http_indicate_completion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus);
[DllImport(AspNetCoreModuleDll)]
- public static extern void register_callbacks(PFN_REQUEST_HANDLER request_callback, PFN_SHUTDOWN_HANDLER shutdown_callback, PFN_ASYNC_COMPLETION managed_context_handler, IntPtr pvRequestContext, IntPtr pvShutdownContext);
+ private static extern void register_callbacks(PFN_REQUEST_HANDLER request_callback, PFN_SHUTDOWN_HANDLER shutdown_callback, PFN_ASYNC_COMPLETION managed_context_handler, IntPtr pvRequestContext, IntPtr pvShutdownContext);
[DllImport(AspNetCoreModuleDll)]
- internal unsafe static extern int http_write_response_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected);
+ private static extern unsafe int http_write_response_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_flush_response_bytes(IntPtr pInProcessHandler, out bool fCompletionExpected);
+ private static extern int http_flush_response_bytes(IntPtr pInProcessHandler, out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)]
- internal unsafe static extern HttpApiTypes.HTTP_REQUEST_V2* http_get_raw_request(IntPtr pInProcessHandler);
+ private static extern unsafe HttpApiTypes.HTTP_REQUEST_V2* http_get_raw_request(IntPtr pInProcessHandler);
[DllImport(AspNetCoreModuleDll)]
- internal unsafe static extern void http_stop_calls_into_managed();
+ private static extern void http_stop_calls_into_managed();
[DllImport(AspNetCoreModuleDll)]
- internal unsafe static extern void http_stop_incoming_requests();
+ private static extern void http_stop_incoming_requests();
[DllImport(AspNetCoreModuleDll)]
- internal unsafe static extern HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pInProcessHandler);
+ private static extern unsafe HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pInProcessHandler);
[DllImport(AspNetCoreModuleDll, CharSet = CharSet.Ansi)]
- public unsafe static extern int http_set_response_status_code(IntPtr pInProcessHandler, ushort statusCode, string pszReason);
+ private static extern int http_set_response_status_code(IntPtr pInProcessHandler, ushort statusCode, string pszReason);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_read_request_bytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, out int dwBytesReceived, out bool fCompletionExpected);
+ private static extern unsafe int http_read_request_bytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, out int dwBytesReceived, out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern bool http_get_completion_info(IntPtr pCompletionInfo, out int cbBytes, out int hr);
+ private static extern void http_get_completion_info(IntPtr pCompletionInfo, out int cbBytes, out int hr);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern bool http_set_managed_context(IntPtr pInProcessHandler, IntPtr pvManagedContext);
+ private static extern int http_set_managed_context(IntPtr pInProcessHandler, IntPtr pvManagedContext);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_get_application_properties(ref IISConfigurationData iiConfigData);
+ private static extern int http_get_application_properties(ref IISConfigurationData iiConfigData);
[DllImport(AspNetCoreModuleDll)]
- public static extern int http_get_server_variable(IntPtr pInProcessHandler, [MarshalAs(UnmanagedType.AnsiBStr)] string variableName, [MarshalAs(UnmanagedType.BStr)] out string value);
+ private static extern int http_get_server_variable(
+ IntPtr pInProcessHandler,
+ [MarshalAs(UnmanagedType.AnsiBStr)] string variableName,
+ [MarshalAs(UnmanagedType.BStr)] out string value);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern bool http_shutdown();
+ private static extern unsafe int http_websockets_read_bytes(
+ IntPtr pInProcessHandler,
+ byte* pvBuffer,
+ int cbBuffer,
+ PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
+ IntPtr pvCompletionContext,
+ out int dwBytesReceived,
+ out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_websockets_read_bytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out int dwBytesReceived, out bool fCompletionExpected);
+ private static extern unsafe int http_websockets_write_bytes(
+ IntPtr pInProcessHandler,
+ HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks,
+ int nChunks,
+ PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
+ IntPtr pvCompletionContext,
+ out bool fCompletionExpected);
[DllImport(AspNetCoreModuleDll)]
- internal unsafe static extern int http_websockets_write_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out bool fCompletionExpected);
+ private static extern int http_enable_websockets(IntPtr pInProcessHandler);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_enable_websockets(IntPtr pInProcessHandler);
+ private static extern int http_cancel_io(IntPtr pInProcessHandler);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_cancel_io(IntPtr pInProcessHandler);
+ private static extern unsafe int http_response_set_unknown_header(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool fReplace);
[DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_response_set_unknown_header(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool fReplace);
+ private static extern unsafe int http_response_set_known_header(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace);
[DllImport(AspNetCoreModuleDll)]
- internal unsafe static extern int http_response_set_known_header(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace);
+ private static extern int http_get_authentication_information(IntPtr pInProcessHandler, [MarshalAs(UnmanagedType.BStr)] out string authType, out IntPtr token);
- [DllImport(AspNetCoreModuleDll)]
- public unsafe static extern int http_get_authentication_information(IntPtr pInProcessHandler, [MarshalAs(UnmanagedType.BStr)] out string authType, out IntPtr token);
-
- [DllImport("kernel32.dll")]
- public static extern IntPtr GetModuleHandle(string lpModuleName);
-
- public static bool is_ancm_loaded()
+ public static void HttpPostCompletion(IntPtr pInProcessHandler, int cbBytes)
{
- return GetModuleHandle(AspNetCoreModuleDll) != IntPtr.Zero;
+ Validate(http_post_completion(pInProcessHandler, cbBytes));
+ }
+
+ public static void HttpSetCompletionStatus(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS rquestNotificationStatus)
+ {
+ Validate(http_set_completion_status(pInProcessHandler, rquestNotificationStatus));
+ }
+
+ public static void HttpIndicateCompletion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus)
+ {
+ http_indicate_completion(pInProcessHandler, notificationStatus);
+ }
+ public static void HttpRegisterCallbacks(PFN_REQUEST_HANDLER request_callback, PFN_SHUTDOWN_HANDLER shutdown_callback, PFN_ASYNC_COMPLETION managed_context_handler, IntPtr pvRequestContext, IntPtr pvShutdownContext)
+ {
+ register_callbacks(request_callback, shutdown_callback, managed_context_handler, pvRequestContext, pvShutdownContext);
+ }
+
+ public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected)
+ {
+ return http_write_response_bytes(pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
+ }
+
+ public static int HttpFlushResponseBytes(IntPtr pInProcessHandler, out bool fCompletionExpected)
+ {
+ return http_flush_response_bytes(pInProcessHandler, out fCompletionExpected);
+ }
+ public static unsafe HttpApiTypes.HTTP_REQUEST_V2* HttpGetRawRequest(IntPtr pInProcessHandler)
+ {
+ return http_get_raw_request(pInProcessHandler);
+ }
+
+ public static void HttpStopCallsIntoManaged()
+ {
+ http_stop_calls_into_managed();
+ }
+
+ public static void HttpStopIncomingRequests()
+ {
+ http_stop_incoming_requests();
+ }
+
+ public static unsafe HttpApiTypes.HTTP_RESPONSE_V2* HttpGetRawResponse(IntPtr pInProcessHandler)
+ {
+ return http_get_raw_response(pInProcessHandler);
+ }
+
+ public static void HttpSetResponseStatusCode(IntPtr pInProcessHandler, ushort statusCode, string pszReason)
+ {
+ Validate(http_set_response_status_code(pInProcessHandler, statusCode, pszReason));
+ }
+
+ public static unsafe int HttpReadRequestBytes(IntPtr pInProcessHandler, byte* pvBuffer, int cbBuffer, out int dwBytesReceived, out bool fCompletionExpected)
+ {
+ return http_read_request_bytes(pInProcessHandler, pvBuffer, cbBuffer, out dwBytesReceived, out fCompletionExpected);
+ }
+
+ public static void HttpGetCompletionInfo(IntPtr pCompletionInfo, out int cbBytes, out int hr)
+ {
+ http_get_completion_info(pCompletionInfo, out cbBytes, out hr);
+ }
+
+ public static void HttpSetManagedContext(IntPtr pInProcessHandler, IntPtr pvManagedContext)
+ {
+ Validate(http_set_managed_context(pInProcessHandler, pvManagedContext));
+ }
+
+ public static IISConfigurationData HttpGetApplicationProperties()
+ {
+ var iisConfigurationData = new IISConfigurationData();
+ Validate(http_get_application_properties(ref iisConfigurationData));
+ return iisConfigurationData;
+ }
+
+ public static bool HttpTryGetServerVariable(IntPtr pInProcessHandler, string variableName, out string value)
+ {
+ return http_get_server_variable(pInProcessHandler, variableName, out value) == 0;
+ }
+
+ public static unsafe int HttpWebsocketsReadBytes(
+ IntPtr pInProcessHandler,
+ byte* pvBuffer,
+ int cbBuffer,
+ PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
+ IntPtr pvCompletionContext, out int dwBytesReceived,
+ out bool fCompletionExpected)
+ {
+ return http_websockets_read_bytes(pInProcessHandler, pvBuffer, cbBuffer, pfnCompletionCallback, pvCompletionContext, out dwBytesReceived, out fCompletionExpected);
+ }
+
+ public static unsafe int HttpWebsocketsWriteBytes(
+ IntPtr pInProcessHandler,
+ HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks,
+ int nChunks,
+ PFN_WEBSOCKET_ASYNC_COMPLETION pfnCompletionCallback,
+ IntPtr pvCompletionContext,
+ out bool fCompletionExpected)
+ {
+ return http_websockets_write_bytes(pInProcessHandler, pDataChunks, nChunks, pfnCompletionCallback, pvCompletionContext, out fCompletionExpected);
+ }
+
+ public static void HttpEnableWebsockets(IntPtr pInProcessHandler)
+ {
+ Validate(http_enable_websockets(pInProcessHandler));
+ }
+
+ public static bool HttpTryCancelIO(IntPtr pInProcessHandler)
+ {
+ var hr = http_cancel_io(pInProcessHandler);
+ // Async operation finished
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363792(v=vs.85).aspx
+ if (hr == HR_NOT_FOUND)
+ {
+ return false;
+ }
+ Validate(hr);
+ return true;
+ }
+
+ public static unsafe void HttpResponseSetUnknownHeader(IntPtr pInProcessHandler, byte* pszHeaderName, byte* pszHeaderValue, ushort usHeaderValueLength, bool fReplace)
+ {
+ Validate(http_response_set_unknown_header(pInProcessHandler, pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace));
+ }
+
+ public static unsafe void HttpResponseSetKnownHeader(IntPtr pInProcessHandler, int headerId, byte* pHeaderValue, ushort length, bool fReplace)
+ {
+ Validate(http_response_set_known_header(pInProcessHandler, headerId, pHeaderValue, length, fReplace));
+ }
+
+ public static void HttpGetAuthenticationInformation(IntPtr pInProcessHandler, out string authType, out IntPtr token)
+ {
+ Validate(http_get_authentication_information(pInProcessHandler, out authType, out token));
+ }
+
+ private static void Validate(int hr)
+ {
+ if (hr != HR_OK)
+ {
+ throw Marshal.GetExceptionForHR(hr);
+ }
}
}
}
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs
index 28cc3672d5..a24586b137 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISAwaitable.cs
@@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
var context = (IISHttpContext)GCHandle.FromIntPtr(pvCompletionContext).Target;
- NativeMethods.http_get_completion_info(pCompletionInfo, out int cbBytes, out int hr);
+ NativeMethods.HttpGetCompletionInfo(pCompletionInfo, out int cbBytes, out int hr);
context.CompleteReadWebSockets(hr, cbBytes);
@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
var context = (IISHttpContext)GCHandle.FromIntPtr(pvCompletionContext).Target;
- NativeMethods.http_get_completion_info(pCompletionInfo, out int cbBytes, out int hr);
+ NativeMethods.HttpGetCompletionInfo(pCompletionInfo, out int cbBytes, out int hr);
context.CompleteWriteWebSockets(hr, cbBytes);
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs
index 4a1ecd5f27..f43c88a319 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.FeatureCollection.cs
@@ -243,8 +243,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
return null;
}
- int hr = NativeMethods.http_get_server_variable(_pInProcessHandler, variableName, out var value);
- return hr == 0 ? value : null;
+ return NativeMethods.HttpTryGetServerVariable(_pInProcessHandler, variableName, out var value) ? value : null;
}
}
@@ -296,7 +295,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
ReasonPhrase = ReasonPhrases.GetReasonPhrase(StatusCodes.Status101SwitchingProtocols);
_readWebSocketsOperation = new IISAwaitable();
_writeWebSocketsOperation = new IISAwaitable();
- NativeMethods.http_enable_websockets(_pInProcessHandler);
+ NativeMethods.HttpEnableWebsockets(_pInProcessHandler);
// Upgrade async will cause the stream processing to go into duplex mode
await UpgradeAsync();
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs
index 699081e659..7b5f18efce 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.ReadWrite.cs
@@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
}
else
{
- var hr = NativeMethods.http_read_request_bytes(
+ var hr = NativeMethods.HttpReadRequestBytes(
_pInProcessHandler,
(byte*)_inputHandle.Pointer,
length,
@@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
chunk.fromMemory.pBuffer = (IntPtr)pBuffer;
chunk.fromMemory.BufferLength = (uint)buffer.Length;
- hr = NativeMethods.http_write_response_bytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
+ hr = NativeMethods.HttpWriteResponseBytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
}
}
else if (nChunks < HttpDataChunkStackLimit)
@@ -274,7 +274,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
currentChunk++;
}
- hr = NativeMethods.http_write_response_bytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
+ hr = NativeMethods.HttpWriteResponseBytes(_pInProcessHandler, pDataChunks, nChunks, out fCompletionExpected);
// Free the handles
foreach (var handle in handles)
@@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
// Calls flush
var hr = 0;
- hr = NativeMethods.http_flush_response_bytes(_pInProcessHandler, out var fCompletionExpected);
+ hr = NativeMethods.HttpFlushResponseBytes(_pInProcessHandler, out var fCompletionExpected);
if (!fCompletionExpected)
{
_operation.Complete(hr, 0);
@@ -468,7 +468,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
_reading = false;
// Calls IHttpContext->CancelIo(), which will cause the OnAsyncCompletion handler to fire.
- NativeMethods.http_cancel_io(_pInProcessHandler);
+ NativeMethods.HttpTryCancelIO(_pInProcessHandler);
}
}
}
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs
index fa84c3ce11..6ddbdef865 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.Websockets.cs
@@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
bool fCompletionExpected;
// For websocket calls, we can directly provide a callback function to be called once the websocket operation completes.
- hr = NativeMethods.http_websockets_read_bytes(
+ hr = NativeMethods.HttpWebsocketsReadBytes(
_pInProcessHandler,
(byte*)_inputHandle.Pointer,
length,
@@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
chunk.fromMemory.pBuffer = (IntPtr)pBuffer;
chunk.fromMemory.BufferLength = (uint)buffer.Length;
- hr = NativeMethods.http_websockets_write_bytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
+ hr = NativeMethods.HttpWebsocketsWriteBytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
}
}
else
@@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
currentChunk++;
}
- hr = NativeMethods.http_websockets_write_bytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
+ hr = NativeMethods.HttpWebsocketsWriteBytes(_pInProcessHandler, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
foreach (var handle in handles)
{
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs
index 32afb07033..8ca003ed7f 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpContext.cs
@@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
private const string WebSocketVersionString = "WEBSOCKET_VERSION";
internal unsafe IISHttpContext(MemoryPool memoryPool, IntPtr pInProcessHandler, IISOptions options, IISHttpServer server)
- : base((HttpApiTypes.HTTP_REQUEST*)NativeMethods.http_get_raw_request(pInProcessHandler))
+ : base((HttpApiTypes.HTTP_REQUEST*)NativeMethods.HttpGetRawRequest(pInProcessHandler))
{
_thisHandle = GCHandle.Alloc(this);
@@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_pInProcessHandler = pInProcessHandler;
_server = server;
- NativeMethods.http_set_managed_context(pInProcessHandler, (IntPtr)_thisHandle);
+ NativeMethods.HttpSetManagedContext(pInProcessHandler, (IntPtr)_thisHandle);
unsafe
{
Method = GetVerb();
@@ -145,8 +145,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
// server variables a few extra times if a bunch of requests hit the server at the same time.
if (_websocketAvailability == WebsocketAvailabilityStatus.Uninitialized)
{
- NativeMethods.http_get_server_variable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported);
- var webSocketsAvailable = !string.IsNullOrEmpty(webSocketsSupported);
+ var webSocketsAvailable = NativeMethods.HttpTryGetServerVariable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported)
+ && !string.IsNullOrEmpty(webSocketsSupported);
+
_websocketAvailability = webSocketsAvailable ?
WebsocketAvailabilityStatus.Available :
WebsocketAvailabilityStatus.NotAvailable;
@@ -335,7 +336,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
var reasonPhrase = string.IsNullOrEmpty(ReasonPhrase) ? ReasonPhrases.GetReasonPhrase(StatusCode) : ReasonPhrase;
// This copies data into the underlying buffer
- NativeMethods.http_set_response_status_code(_pInProcessHandler, (ushort)StatusCode, reasonPhrase);
+ NativeMethods.HttpSetResponseStatusCode(_pInProcessHandler, (ushort)StatusCode, reasonPhrase);
HttpResponseHeaders.IsReadOnly = true;
foreach (var headerPair in HttpResponseHeaders)
@@ -352,7 +353,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
fixed (byte* pHeaderValue = headerValueBytes)
{
- NativeMethods.http_response_set_unknown_header(_pInProcessHandler, pHeaderName, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false);
+ NativeMethods.HttpResponseSetUnknownHeader(_pInProcessHandler, pHeaderName, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false);
}
}
}
@@ -364,7 +365,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
var headerValueBytes = Encoding.UTF8.GetBytes(headerValues[i]);
fixed (byte* pHeaderValue = headerValueBytes)
{
- NativeMethods.http_response_set_known_header(_pInProcessHandler, knownHeaderIndex, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false);
+ NativeMethods.HttpResponseSetKnownHeader(_pInProcessHandler, knownHeaderIndex, pHeaderValue, (ushort)headerValueBytes.Length, fReplace: false);
}
}
}
@@ -475,22 +476,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
Debug.Assert(!_operation.HasContinuation, "Pending async operation!");
- var hr = NativeMethods.http_set_completion_status(_pInProcessHandler, requestNotificationStatus);
- if (hr != NativeMethods.S_OK)
- {
- throw Marshal.GetExceptionForHR(hr);
- }
-
- hr = NativeMethods.http_post_completion(_pInProcessHandler, 0);
- if (hr != NativeMethods.S_OK)
- {
- throw Marshal.GetExceptionForHR(hr);
- }
+ NativeMethods.HttpSetCompletionStatus(_pInProcessHandler, requestNotificationStatus);
+ NativeMethods.HttpPostCompletion(_pInProcessHandler, 0);
}
public void IndicateCompletion(NativeMethods.REQUEST_NOTIFICATION_STATUS notificationStatus)
{
- NativeMethods.http_indicate_completion(_pInProcessHandler, notificationStatus);
+ NativeMethods.HttpIndicateCompletion(_pInProcessHandler, notificationStatus);
}
internal void OnAsyncCompletion(int hr, int cbBytes)
@@ -540,9 +532,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
private WindowsPrincipal GetWindowsPrincipal()
{
- var hr = NativeMethods.http_get_authentication_information(_pInProcessHandler, out var authenticationType, out var token);
+ NativeMethods.HttpGetAuthenticationInformation(_pInProcessHandler, out var authenticationType, out var token);
- if (hr == 0 && token != IntPtr.Zero && authenticationType != null)
+ if (token != IntPtr.Zero && authenticationType != null)
{
if ((authenticationType.Equals(NtlmString, StringComparison.OrdinalIgnoreCase)
|| authenticationType.Equals(NegotiateString, StringComparison.OrdinalIgnoreCase)
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs
index 110b38e729..046d8b9c4f 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISHttpServer.cs
@@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_iisContextFactory = new IISContextFactory(_memoryPool, application, _options, this);
// Start the server by registering the callback
- NativeMethods.register_callbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
+ NativeMethods.HttpRegisterCallbacks(_requestHandler, _shutdownHandler, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
return Task.CompletedTask;
}
@@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
cancellationToken.Register(() =>
{
- NativeMethods.http_stop_calls_into_managed();
+ NativeMethods.HttpStopCallsIntoManaged();
_shutdownSignal.TrySetResult(null);
});
}
@@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
}
// First call back into native saying "DON'T SEND ME ANY MORE REQUESTS"
- NativeMethods.http_stop_incoming_requests();
+ NativeMethods.HttpStopIncomingRequests();
try
{
@@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
else
{
// We have drained all requests. Block any callbacks into managed at this point.
- NativeMethods.http_stop_calls_into_managed();
+ NativeMethods.HttpStopCallsIntoManaged();
_shutdownSignal.TrySetResult(null);
}
}
@@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
_stopping = 1;
// Block any more calls into managed from native as we are unloading.
- NativeMethods.http_stop_calls_into_managed();
+ NativeMethods.HttpStopCallsIntoManaged();
_shutdownSignal.TrySetResult(null);
if (_httpServerHandle.IsAllocated)
@@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
if (Interlocked.Decrement(ref context.Server._outstandingRequests) == 0 && context.Server.Stopping)
{
// All requests have been drained.
- NativeMethods.http_stop_calls_into_managed();
+ NativeMethods.HttpStopCallsIntoManaged();
context.Server._shutdownSignal.TrySetResult(null);
}
@@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
~IISHttpServer()
{
// If this finalize is invoked, try our best to block all calls into managed.
- NativeMethods.http_stop_calls_into_managed();
+ NativeMethods.HttpStopCallsIntoManaged();
}
}
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISServerSetupFilter.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISServerSetupFilter.cs
index 94fa2ac136..787c979c96 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISServerSetupFilter.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Server/IISServerSetupFilter.cs
@@ -4,6 +4,8 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Server.IISIntegration
{
@@ -20,6 +22,12 @@ namespace Microsoft.AspNetCore.Server.IISIntegration
{
return app =>
{
+ var server = app.ApplicationServices.GetService();
+ if (server?.GetType() != typeof(IISHttpServer))
+ {
+ throw new InvalidOperationException("Application is running inside IIS process but is not configured to use IIS server.");
+ }
+
app.UsePathBase(_virtualPath);
next(app);
};
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs b/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs
index a96305d4d8..c236c7eac4 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs
@@ -41,34 +41,10 @@ namespace Microsoft.AspNetCore.Hosting
}
// Check if in process
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && NativeMethods.is_ancm_loaded())
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && NativeMethods.IsAspNetCoreModuleLoaded())
{
- hostBuilder.UseSetting(nameof(UseIISIntegration), "true");
- hostBuilder.CaptureStartupErrors(true);
- // TODO consider adding a configuration load where all variables needed are loaded from ANCM in one call.
- var iisConfigData = new IISConfigurationData();
- var hResult = NativeMethods.http_get_application_properties(ref iisConfigData);
-
- var exception = Marshal.GetExceptionForHR(hResult);
- if (exception != null)
- {
- throw exception;
- }
-
- hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath);
- return hostBuilder.ConfigureServices(services =>
- {
- services.AddSingleton();
- services.AddSingleton(new IISServerSetupFilter(iisConfigData.pwzVirtualApplicationPath));
- services.AddAuthenticationCore();
- services.Configure(
- options =>
- {
- options.ForwardWindowsAuthentication = iisConfigData.fWindowsAuthEnabled || iisConfigData.fBasicAuthEnabled;
- }
- );
- });
+ return SetupInProcessServer(hostBuilder);
}
var port = hostBuilder.GetSetting(ServerPort) ?? Environment.GetEnvironmentVariable($"ASPNETCORE_{ServerPort}");
@@ -131,5 +107,23 @@ namespace Microsoft.AspNetCore.Hosting
return hostBuilder;
}
+
+ private static IWebHostBuilder SetupInProcessServer(IWebHostBuilder hostBuilder)
+ {
+ hostBuilder.UseSetting(nameof(UseIISIntegration), "true");
+ hostBuilder.CaptureStartupErrors(true);
+
+ var iisConfigData = NativeMethods.HttpGetApplicationProperties();
+ hostBuilder.UseContentRoot(iisConfigData.pwzFullApplicationPath);
+ return hostBuilder.ConfigureServices(
+ services => {
+ services.AddSingleton();
+ services.AddSingleton(new IISServerSetupFilter(iisConfigData.pwzVirtualApplicationPath));
+ services.AddAuthenticationCore();
+ services.Configure(
+ options => { options.ForwardWindowsAuthentication = iisConfigData.fWindowsAuthEnabled || iisConfigData.fBasicAuthEnabled; }
+ );
+ });
+ }
}
}
diff --git a/src/RequestHandler/outofprocess/serverprocess.cxx b/src/RequestHandler/outofprocess/serverprocess.cxx
index 03f957c17d..7aaea35a1f 100644
--- a/src/RequestHandler/outofprocess/serverprocess.cxx
+++ b/src/RequestHandler/outofprocess/serverprocess.cxx
@@ -30,7 +30,6 @@ SERVER_PROCESS::Initialize(
)
{
HRESULT hr = S_OK;
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { 0 };
m_pProcessManager = pProcessManager;
m_dwStartupTimeLimitInMS = dwStartupTimeLimitInMS;
@@ -47,11 +46,24 @@ SERVER_PROCESS::Initialize(
FAILED(hr = m_struPhysicalPath.Copy(*pszAppPhysicalPath))||
FAILED(hr = m_struAppFullPath.Copy(*pszAppPath))||
FAILED(hr = m_struAppVirtualPath.Copy(*pszAppVirtualPath))||
- FAILED(hr = m_Arguments.Copy(*pszArguments)))
+ FAILED(hr = m_Arguments.Copy(*pszArguments)) ||
+ FAILED(hr = SetupJobObject()))
{
goto Finished;
}
+ m_pEnvironmentVarTable = pEnvironmentVariables;
+
+Finished:
+ return hr;
+}
+
+HRESULT
+SERVER_PROCESS::SetupJobObject(VOID)
+{
+ HRESULT hr = S_OK;
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { 0 };
+
if (m_hJobObject == NULL)
{
m_hJobObject = CreateJobObject(NULL, // LPSECURITY_ATTRIBUTES
@@ -75,14 +87,10 @@ SERVER_PROCESS::Initialize(
sizeof jobInfo))
{
hr = HRESULT_FROM_WIN32(GetLastError());
- goto Finished;
}
}
-
- m_pEnvironmentVarTable = pEnvironmentVariables;
}
-Finished:
return hr;
}
@@ -130,23 +138,25 @@ SERVER_PROCESS::GetRandomPort
HRESULT
SERVER_PROCESS::SetupListenPort(
- ENVIRONMENT_VAR_HASH *pEnvironmentVarTable
+ ENVIRONMENT_VAR_HASH *pEnvironmentVarTable,
+ BOOL* pfCriticalError
)
{
HRESULT hr = S_OK;
ENVIRONMENT_VAR_ENTRY *pEntry = NULL;
STACK_STRU(strEventMsg, 256);
+ *pfCriticalError = FALSE;
pEnvironmentVarTable->FindKey(ASPNETCORE_PORT_ENV_STR, &pEntry);
if (pEntry != NULL)
{
- pEntry->Dereference();
if (pEntry->QueryValue() != NULL || pEntry->QueryValue()[0] != L'\0')
{
m_dwPort = (DWORD)_wtoi(pEntry->QueryValue());
if (m_dwPort >MAX_PORT || m_dwPort < MIN_PORT)
{
hr = E_INVALIDARG;
+ *pfCriticalError = TRUE;
goto Finished;
// need add log for this one
}
@@ -160,6 +170,8 @@ SERVER_PROCESS::SetupListenPort(
//
pEnvironmentVarTable->DeleteKey(ASPNETCORE_PORT_ENV_STR);
}
+ pEntry->Dereference();
+ pEntry = NULL;
}
WCHAR buffer[15];
@@ -207,7 +219,7 @@ Finished:
hr)))
{
UTILITY::LogEvent(g_hEventLog,
- EVENTLOG_INFORMATION_TYPE,
+ EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_PROCESS_START_SUCCESS,
strEventMsg.QueryStr());
}
@@ -736,7 +748,7 @@ SERVER_PROCESS::StartProcess(
MULTISZ mszNewEnvironment;
ENVIRONMENT_VAR_HASH *pHashTable = NULL;
PWSTR pStrStage = NULL;
-
+ BOOL fCriticalError = FALSE;
GetStartupInfoW(&startupInfo);
//
@@ -782,7 +794,7 @@ SERVER_PROCESS::StartProcess(
//
// setup the the port that the backend process will listen on
//
- if (FAILED(hr = SetupListenPort(pHashTable)))
+ if (FAILED(hr = SetupListenPort(pHashTable, &fCriticalError)))
{
pStrStage = L"SetupListenPort";
goto Failure;
@@ -840,6 +852,12 @@ SERVER_PROCESS::StartProcess(
m_hProcessHandle = processInformation.hProcess;
m_dwProcessId = processInformation.dwProcessId;
+ if (FAILED(hr = SetupJobObject()))
+ {
+ pStrStage = L"SetupJobObject";
+ goto Failure;
+ }
+
if (m_hJobObject != NULL)
{
if (!AssignProcessToJobObject(m_hJobObject, m_hProcessHandle))
@@ -887,6 +905,12 @@ SERVER_PROCESS::StartProcess(
goto Finished;
Failure:
+ if (fCriticalError)
+ {
+ // Critical error, no retry need to avoid wasting resource and polluting log
+ dwRetryCount = 0;
+ }
+
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_PROCESS_START_ERROR_MSG,
m_struAppFullPath.QueryStr(),
@@ -917,7 +941,6 @@ SERVER_PROCESS::StartProcess(
}
CleanUp();
-
}
Finished:
diff --git a/src/RequestHandler/outofprocess/serverprocess.h b/src/RequestHandler/outofprocess/serverprocess.h
index 3b6ff4b370..cef9446c15 100644
--- a/src/RequestHandler/outofprocess/serverprocess.h
+++ b/src/RequestHandler/outofprocess/serverprocess.h
@@ -127,6 +127,11 @@ private:
VOID
CleanUp();
+ HRESULT
+ SetupJobObject(
+ VOID
+ );
+
BOOL
IsDebuggerIsAttached(
VOID
@@ -162,7 +167,8 @@ private:
HRESULT
SetupListenPort(
- ENVIRONMENT_VAR_HASH *pEnvironmentVarTable
+ ENVIRONMENT_VAR_HASH *pEnvironmentVarTable,
+ BOOL *pfCriticalError
);
HRESULT
diff --git a/test/ANCMStressTestApp/Properties/launchSettings.json b/test/ANCMStressTestApp/Properties/launchSettings.json
deleted file mode 100644
index 8e9b6cfcf7..0000000000
--- a/test/ANCMStressTestApp/Properties/launchSettings.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:16606/",
- "sslPort": 0
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "ANCMStressTestSample": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "http://localhost:16607/"
- }
- }
-}
\ No newline at end of file
diff --git a/test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj b/test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj
index 1dc88d2ac3..910b52ee74 100644
--- a/test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj
+++ b/test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj
@@ -167,6 +167,7 @@
Create
+
diff --git a/test/AspNetCoreModuleTests/hostfxr_utility_tests.cpp b/test/AspNetCoreModuleTests/hostfxr_utility_tests.cpp
index dfa0e3c4b9..7e1d6f8d89 100644
--- a/test/AspNetCoreModuleTests/hostfxr_utility_tests.cpp
+++ b/test/AspNetCoreModuleTests/hostfxr_utility_tests.cpp
@@ -71,7 +71,7 @@ namespace AspNetCoreModuleTests
Assert::AreEqual(DWORD(3), retVal);
Assert::AreEqual(exeStr, bstrArray[0]);
Assert::AreEqual(L"exec", bstrArray[1]);
- Assert::AreEqual(L"\\\\?\\C:\\test\\test.dll", bstrArray[2]);
+ Assert::AreEqual(L"C:\\test\\test.dll", bstrArray[2]);
}
TEST_METHOD(ParseHostfxrArguments_ProvideNoArgs_InvalidArgs)
@@ -90,5 +90,63 @@ namespace AspNetCoreModuleTests
Assert::AreEqual(E_INVALIDARG, hr);
}
+
+ TEST_METHOD(GetAbsolutePathToDotnetFromProgramFiles_BackupWorks)
+ {
+ STRU struAbsolutePathToDotnet;
+ HRESULT hr = S_OK;
+ BOOL fDotnetInProgramFiles;
+ BOOL is64Bit;
+ BOOL fIsWow64 = FALSE;
+ SYSTEM_INFO systemInfo;
+ IsWow64Process(GetCurrentProcess(), &fIsWow64);
+ if (fIsWow64)
+ {
+ is64Bit = FALSE;
+ }
+ else
+ {
+ GetNativeSystemInfo(&systemInfo);
+ is64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
+ }
+
+ if (is64Bit)
+ {
+ fDotnetInProgramFiles = UTILITY::CheckIfFileExists(L"C:/Program Files/dotnet/dotnet.exe");
+ }
+ else
+ {
+ fDotnetInProgramFiles = UTILITY::CheckIfFileExists(L"C:/Program Files (x86)/dotnet/dotnet.exe");
+ }
+
+ hr = HOSTFXR_UTILITY::GetAbsolutePathToDotnetFromProgramFiles(&struAbsolutePathToDotnet);
+ if (fDotnetInProgramFiles)
+ {
+ Assert::AreEqual(hr, S_OK);
+ }
+ else
+ {
+ Assert::AreNotEqual(hr, S_OK);
+ Assert::IsTrue(struAbsolutePathToDotnet.IsEmpty());
+ }
+ }
+
+ TEST_METHOD(GetHostFxrArguments_InvalidParams)
+ {
+ DWORD retVal = 0;
+ BSTR* bstrArray;
+ STRU struHostFxrDllLocation;
+
+ HRESULT hr = HOSTFXR_UTILITY::GetHostFxrParameters(
+ INVALID_HANDLE_VALUE,
+ L"bogus", // processPath
+ L"", // application physical path, ignored.
+ L"ignored", //arguments
+ NULL, // event log
+ &retVal, // arg count
+ &bstrArray); // args array.
+
+ Assert::AreEqual(E_INVALIDARG, hr);
+ }
};
}
diff --git a/test/AspNetCoreModuleTests/utility_tests.cpp b/test/AspNetCoreModuleTests/utility_tests.cpp
new file mode 100644
index 0000000000..a24711cf1a
--- /dev/null
+++ b/test/AspNetCoreModuleTests/utility_tests.cpp
@@ -0,0 +1,52 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+#include "stdafx.h"
+#include "CppUnitTest.h"
+
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+
+namespace AspNetCoreModuleTests
+{
+ TEST_CLASS(UTILITY_TESTS)
+ {
+ public:
+
+ TEST_METHOD(PassUnexpandedString_ExpandsResult)
+ {
+ HRESULT hr = S_OK;
+ PCWSTR unexpandedString = L"ANCM_TEST_ENV_VAR";
+ PCWSTR unexpandedStringValue = L"foobar";
+ STRU struExpandedString;
+ SetEnvironmentVariable(L"ANCM_TEST_ENV_VAR", unexpandedStringValue);
+
+ hr = struExpandedString.CopyAndExpandEnvironmentStrings(L"%ANCM_TEST_ENV_VAR%");
+ Assert::AreEqual(hr, S_OK);
+ Assert::AreEqual(L"foobar", struExpandedString.QueryStr());
+ }
+
+ TEST_METHOD(PassUnexpandedString_Resize_ExpandsResult)
+ {
+ HRESULT hr = S_OK;
+ PCWSTR unexpandedString = L"ANCM_TEST_ENV_VAR_LONG";
+ STRU struStringValue;
+ STACK_STRU(struExpandedString, MAX_PATH);
+
+ struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
+ struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
+ struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
+ struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
+ struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
+ struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
+
+ SetEnvironmentVariable(unexpandedString, struStringValue.QueryStr());
+
+ hr = struExpandedString.CopyAndExpandEnvironmentStrings(L"%ANCM_TEST_ENV_VAR_LONG%");
+ Assert::AreEqual(hr, S_OK);
+ Assert::AreEqual(struStringValue.QueryCCH(), struExpandedString.QueryCCH());
+ // The values are exactly the same, however Assert::AreEqual is returning false.
+ //Assert::AreEqual(struStringValue.QueryStr(), struExpandedString.QueryStr());
+ Assert::AreEqual(0, wcscmp(struStringValue.QueryStr(), struExpandedString.QueryStr()));
+ }
+ };
+}
diff --git a/test/IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj b/test/IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj
index c09eeee095..d79a5ec5d9 100644
--- a/test/IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj
+++ b/test/IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj
@@ -10,7 +10,9 @@
-
+
+ False
+
diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs b/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs
index f86b3bcffd..d6fd676346 100644
--- a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs
+++ b/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs
@@ -28,8 +28,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
[ConditionalFact]
public async Task ReturnsNullForUndefinedServerVariable()
{
- var port = _fixture.Client.BaseAddress.Port;
Assert.Equal("THIS_VAR_IS_UNDEFINED: (null)", await _fixture.Client.GetStringAsync("/ServerVariable?q=THIS_VAR_IS_UNDEFINED"));
}
+
+ [ConditionalFact]
+ public async Task BasePathIsNotPrefixedBySlashSlashQuestionMark()
+ {
+ Assert.DoesNotContain(@"\\?\", await _fixture.Client.GetStringAsync("/BasePath"));
+ }
}
}
diff --git a/test/IISIntegration.FunctionalTests/Inprocess/StartupTests.cs b/test/IISIntegration.FunctionalTests/Inprocess/StartupTests.cs
new file mode 100644
index 0000000000..e351649d86
--- /dev/null
+++ b/test/IISIntegration.FunctionalTests/Inprocess/StartupTests.cs
@@ -0,0 +1,233 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using Microsoft.AspNetCore.Server.IntegrationTesting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Testing;
+using Xunit;
+using Xunit.Abstractions;
+using Xunit.Sdk;
+
+
+namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
+{
+ public class StartupTests : LoggedTest
+ {
+ public StartupTests(ITestOutputHelper output) : base(output)
+ {
+
+ }
+
+ [Fact]
+ public async Task ExpandEnvironmentVariableInWebConfig()
+ {
+ var architecture = RuntimeArchitecture.x64;
+ var dotnetLocation = $"%USERPROFILE%\\.dotnet\\{architecture.ToString()}\\dotnet.exe";
+ using (StartLog(out var loggerFactory))
+ {
+ var logger = loggerFactory.CreateLogger("HelloWorldTest");
+
+ var deploymentParameters = GetBaseDeploymentParameters();
+
+ // Point to dotnet installed in user profile.
+ deploymentParameters.EnvironmentVariables["DotnetPath"] = Environment.ExpandEnvironmentVariables(dotnetLocation); // Path to dotnet.
+
+ using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
+ {
+ var deploymentResult = await deployer.DeployAsync();
+
+ Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "processPath", "%DotnetPath%");
+
+ // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+ var response = await RetryHelper.RetryRequest(() =>
+ {
+ return deploymentResult.HttpClient.GetAsync("HelloWorld");
+ }, logger, deploymentResult.HostShutdownToken, retryCount: 30);
+
+ var responseText = await response.Content.ReadAsStringAsync();
+ try
+ {
+ Assert.Equal("Hello World", responseText);
+ }
+ catch (XunitException)
+ {
+ logger.LogWarning(response.ToString());
+ logger.LogWarning(responseText);
+ throw;
+ }
+ }
+ }
+ }
+
+ [Fact]
+ public async Task InvalidProcessPath_ExpectServerError()
+ {
+ var dotnetLocation = "bogus";
+ using (StartLog(out var loggerFactory))
+ {
+ var logger = loggerFactory.CreateLogger("HelloWorldTest");
+ var deploymentParameters = GetBaseDeploymentParameters();
+
+ // Point to dotnet installed in user profile.
+ deploymentParameters.EnvironmentVariables["DotnetPath"] = Environment.ExpandEnvironmentVariables(dotnetLocation); // Path to dotnet.
+
+ using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
+ {
+ var deploymentResult = await deployer.DeployAsync();
+
+ Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "processPath", "%DotnetPath%");
+
+ // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+ var response = await RetryHelper.RetryRequest(() =>
+ {
+ return deploymentResult.HttpClient.GetAsync("HelloWorld");
+ }, logger, deploymentResult.HostShutdownToken, retryCount: 30);
+
+ Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
+ }
+ }
+ }
+
+#if NETCOREAPP2_0 || NETCOREAPP2_1
+
+ [Fact] // Consistently fails on CI for net461
+ public async Task StandaloneApplication_ExpectCorrectPublish()
+ {
+ using (StartLog(out var loggerFactory))
+ {
+ var logger = loggerFactory.CreateLogger("HelloWorldTest");
+
+ var deploymentParameters = GetBaseDeploymentParameters();
+
+ using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
+ {
+ var deploymentResult = await deployer.DeployAsync();
+
+ // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+ var response = await RetryHelper.RetryRequest(() =>
+ {
+ return deploymentResult.HttpClient.GetAsync("HelloWorld");
+ }, logger, deploymentResult.HostShutdownToken, retryCount: 30);
+
+ var responseText = await response.Content.ReadAsStringAsync();
+ try
+ {
+ Assert.Equal("Hello World", responseText);
+ }
+ catch (XunitException)
+ {
+ logger.LogWarning(response.ToString());
+ logger.LogWarning(responseText);
+ throw;
+ }
+ }
+ }
+ }
+
+ [Fact] // Consistently fails on CI for net461
+ public async Task StandaloneApplication_AbsolutePathToExe_ExpectCorrectPublish()
+ {
+ using (StartLog(out var loggerFactory))
+ {
+ var logger = loggerFactory.CreateLogger("HelloWorldTest");
+
+ var deploymentParameters = GetBaseDeploymentParameters();
+ deploymentParameters.ApplicationType = ApplicationType.Standalone;
+
+ using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
+ {
+ var deploymentResult = await deployer.DeployAsync();
+
+ Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "processPath", $"{deploymentResult.ContentRoot}\\InProcessWebSite.exe");
+
+ // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+ var response = await RetryHelper.RetryRequest(() =>
+ {
+ return deploymentResult.HttpClient.GetAsync("HelloWorld");
+ }, logger, deploymentResult.HostShutdownToken, retryCount: 30);
+
+ var responseText = await response.Content.ReadAsStringAsync();
+ try
+ {
+ Assert.Equal("Hello World", responseText);
+ }
+ catch (XunitException)
+ {
+ logger.LogWarning(response.ToString());
+ logger.LogWarning(responseText);
+ throw;
+ }
+ }
+ }
+ }
+
+#elif NET461
+#else
+#error Target frameworks need to be updated
+#endif
+
+ [Fact]
+ public async Task DetectsOveriddenServer()
+ {
+ var testSink = new TestSink();
+ using (StartLog(out var loggerFactory))
+ {
+ var testLoggerFactory = new TestLoggerFactory(testSink, true);
+ loggerFactory.AddProvider(new TestLoggerProvider(testLoggerFactory));
+
+ using (var deployer = ApplicationDeployerFactory.Create(GetBaseDeploymentParameters("OverriddenServerWebSite"), loggerFactory))
+ {
+ var deploymentResult = await deployer.DeployAsync();
+ var response = await deploymentResult.HttpClient.GetAsync("/");
+ Assert.False(response.IsSuccessStatusCode);
+ }
+ }
+ Assert.Contains(testSink.Writes, context => context.State.ToString().Contains("Application is running inside IIS process but is not configured to use IIS server"));
+ }
+
+ private DeploymentParameters GetBaseDeploymentParameters(string site = null)
+ {
+ return new DeploymentParameters(Helpers.GetTestWebSitePath(site ?? "InProcessWebSite"), ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
+ {
+ ServerConfigTemplateContent = File.ReadAllText("AppHostConfig/Http.config"),
+ SiteName = "HttpTestSite", // This is configured in the Http.config
+ TargetFramework = "netcoreapp2.1",
+ ApplicationType = ApplicationType.Portable,
+ Configuration = GetCurrentConfiguration()
+ };
+ }
+
+ private static string GetCurrentConfiguration()
+ {
+#if DEBUG
+ return "Debug";
+#else
+ return "Release";
+#endif
+ }
+
+ private class TestLoggerProvider : ILoggerProvider
+ {
+ private readonly TestLoggerFactory _loggerFactory;
+
+ public TestLoggerProvider(TestLoggerFactory loggerFactory)
+ {
+ _loggerFactory = loggerFactory;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public ILogger CreateLogger(string categoryName)
+ {
+ return _loggerFactory.CreateLogger(categoryName);
+ }
+ }
+ }
+}
diff --git a/test/IISIntegration.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs b/test/IISIntegration.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs
index e69437a7b8..c79c8a462c 100644
--- a/test/IISIntegration.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs
+++ b/test/IISIntegration.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs
@@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Assert.Equal(body, responseText);
}
- [ConditionalFact(Skip = "See https://github.com/aspnet/IISIntegration/issues/687")]
+ [ConditionalFact]
public async Task ReadAndWriteEchoTwice()
{
var requestBody = new string('a', 10000);
diff --git a/test/IISIntegration.FunctionalTests/Utilities/Helpers.cs b/test/IISIntegration.FunctionalTests/Utilities/Helpers.cs
index c09b1bf3a7..5cda360005 100644
--- a/test/IISIntegration.FunctionalTests/Utilities/Helpers.cs
+++ b/test/IISIntegration.FunctionalTests/Utilities/Helpers.cs
@@ -1,33 +1,41 @@
// 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 Microsoft.AspNetCore.Server.IntegrationTesting;
using System;
using System.IO;
+using System.Linq;
+using System.Xml.Linq;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
public class Helpers
{
- public static string GetInProcessTestSitesPath()
- {
+ public static string GetTestWebSitePath(string name)
+ {
return Path.GetFullPath(
Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
- "..", // tfm
- "..", // debug
- "..", // obj
- "..", // projectfolder
- "IISTestSite"));
+ "..", // tfm
+ "..", // debug
+ "..", // obj
+ "..", // projectfolder
+ "WebSites",
+ name));
}
- public static string GetOutOfProcessTestSitesPath()
+ public static string GetInProcessTestSitesPath() => GetTestWebSitePath("InProcessWebSite");
+
+ public static string GetOutOfProcessTestSitesPath() => GetTestWebSitePath("OutOfProcessWebSite");
+
+ public static void ModifyAspNetCoreSectionInWebConfig(DeploymentResult deploymentResult, string key, string value)
{
- return Path.GetFullPath(
- Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
- "..", // tfm
- "..", // debug
- "..", // obj
- "..", // projectfolder
- "TestSites"));
+ // modify the web.config after publish
+ var root = deploymentResult.ContentRoot;
+ var webConfigFile = $"{root}/web.config";
+ var config = XDocument.Load(webConfigFile);
+ var element = config.Descendants("aspNetCore").FirstOrDefault();
+ element.SetAttributeValue(key, value);
+ config.Save(webConfigFile);
}
}
}
diff --git a/test/TestTasks/InjectRequestHandler.cs b/test/TestTasks/InjectRequestHandler.cs
new file mode 100644
index 0000000000..639428ebd1
--- /dev/null
+++ b/test/TestTasks/InjectRequestHandler.cs
@@ -0,0 +1,62 @@
+// 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.Diagnostics;
+using System.IO;
+using System.Linq;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace TestTasks
+{
+ public class InjectRequestHandler
+ {
+ private static void Main(string[] args)
+ {
+ var depsFile = args[2];
+ var rid = args[0];
+ var libraryLocation = args[1];
+
+ JToken deps;
+ using (var file = File.OpenText(depsFile))
+ using (JsonTextReader reader = new JsonTextReader(file))
+ {
+ deps = JObject.ReadFrom(reader);
+ }
+
+ var libraryName = "ANCMRH/1.0";
+ var libraries = (JObject)deps["libraries"];
+ var targetName = (JValue)deps["runtimeTarget"]["name"];
+
+ var target = (JObject)deps["targets"][targetName.Value];
+ var targetLibrary = target.Properties().FirstOrDefault(p => p.Name == libraryName);
+ targetLibrary?.Remove();
+ targetLibrary =
+ new JProperty(libraryName, new JObject(
+ new JProperty("runtimeTargets", new JObject(
+ new JProperty(libraryLocation.Replace('\\', '/'), new JObject(
+ new JProperty("rid", rid),
+ new JProperty("assetType", "native")
+ ))))));
+ target.AddFirst(targetLibrary);
+
+ var library = libraries.Properties().FirstOrDefault(p => p.Name == libraryName);
+ library?.Remove();
+ library =
+ new JProperty(libraryName, new JObject(
+ new JProperty("type", "package"),
+ new JProperty("serviceable", true),
+ new JProperty("sha512", ""),
+ new JProperty("path", libraryName),
+ new JProperty("hashPath", "")));
+ libraries.AddFirst(library);
+
+ using (var file = File.CreateText(depsFile))
+ using (var writer = new JsonTextWriter(file) { Formatting = Formatting.Indented })
+ {
+ deps.WriteTo(writer);
+ }
+ }
+ }
+}
diff --git a/test/TestTasks/TestTasks.csproj b/test/TestTasks/TestTasks.csproj
new file mode 100644
index 0000000000..aa4c144936
--- /dev/null
+++ b/test/TestTasks/TestTasks.csproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ $(StandardTestTfms)
+
+
+
+
+
+
+
diff --git a/test/IISTestSite/IISTestSite.csproj b/test/WebSites/InProcessWebSite/InProcessWebSite.csproj
similarity index 83%
rename from test/IISTestSite/IISTestSite.csproj
rename to test/WebSites/InProcessWebSite/InProcessWebSite.csproj
index f628ba9cf9..c615d460ee 100644
--- a/test/IISTestSite/IISTestSite.csproj
+++ b/test/WebSites/InProcessWebSite/InProcessWebSite.csproj
@@ -1,13 +1,12 @@
-
-
+
$(StandardTestTfms)
-
+
diff --git a/test/IISTestSite/Program.cs b/test/WebSites/InProcessWebSite/Program.cs
similarity index 92%
rename from test/IISTestSite/Program.cs
rename to test/WebSites/InProcessWebSite/Program.cs
index 5e22d2f2c6..0550f0f1fd 100644
--- a/test/IISTestSite/Program.cs
+++ b/test/WebSites/InProcessWebSite/Program.cs
@@ -17,7 +17,7 @@ namespace IISTestSite
factory.AddFilter("Console", level => level >= LogLevel.Information);
})
.UseIISIntegration()
- .UseStartup("IISTestSite")
+ .UseStartup(typeof(Program).Assembly.FullName)
.Build();
host.Run();
diff --git a/test/IISTestSite/Properties/launchSettings.json b/test/WebSites/InProcessWebSite/Properties/launchSettings.json
similarity index 97%
rename from test/IISTestSite/Properties/launchSettings.json
rename to test/WebSites/InProcessWebSite/Properties/launchSettings.json
index 7d09a120ab..6d5ce43f73 100644
--- a/test/IISTestSite/Properties/launchSettings.json
+++ b/test/WebSites/InProcessWebSite/Properties/launchSettings.json
@@ -12,6 +12,7 @@
"commandName": "Executable",
"executablePath": "$(IISExpressPath)",
"commandLineArgs": "$(IISExpressArguments)",
+ "nativeDebugging": true,
"environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(TargetDir)$(AncmPath)",
diff --git a/test/IISTestSite/Startup.cs b/test/WebSites/InProcessWebSite/Startup.cs
similarity index 99%
rename from test/IISTestSite/Startup.cs
rename to test/WebSites/InProcessWebSite/Startup.cs
index 00b83e769d..781601aea5 100644
--- a/test/IISTestSite/Startup.cs
+++ b/test/WebSites/InProcessWebSite/Startup.cs
@@ -667,5 +667,10 @@ namespace IISTestSite
}
});
}
+
+ private void BasePath(IApplicationBuilder app)
+ {
+ app.Run(async ctx => { await ctx.Response.WriteAsync(AppDomain.CurrentDomain.BaseDirectory); });
+ }
}
}
diff --git a/test/IISTestSite/web.config b/test/WebSites/InProcessWebSite/web.config
similarity index 100%
rename from test/IISTestSite/web.config
rename to test/WebSites/InProcessWebSite/web.config
diff --git a/test/TestSites/TestSites.csproj b/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj
similarity index 83%
rename from test/TestSites/TestSites.csproj
rename to test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj
index 19ed3dc502..0b96c98c36 100644
--- a/test/TestSites/TestSites.csproj
+++ b/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj
@@ -1,13 +1,13 @@
-
+
$(StandardTestTfms)
-
+
diff --git a/test/TestSites/Program.cs b/test/WebSites/OutOfProcessWebSite/Program.cs
similarity index 92%
rename from test/TestSites/Program.cs
rename to test/WebSites/OutOfProcessWebSite/Program.cs
index af6e90bd15..18104fa30a 100644
--- a/test/TestSites/Program.cs
+++ b/test/WebSites/OutOfProcessWebSite/Program.cs
@@ -17,7 +17,7 @@ namespace TestSites
factory.AddFilter("Console", level => level >= LogLevel.Information);
})
.UseIISIntegration()
- .UseStartup("TestSites")
+ .UseStartup(typeof(Program).Assembly.FullName)
.UseKestrel()
.Build();
diff --git a/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json b/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json
new file mode 100644
index 0000000000..6d5ce43f73
--- /dev/null
+++ b/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json
@@ -0,0 +1,37 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": true,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:5762/",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "ANCM IIS Express": {
+ "commandName": "Executable",
+ "executablePath": "$(IISExpressPath)",
+ "commandLineArgs": "$(IISExpressArguments)",
+ "nativeDebugging": true,
+ "environmentVariables": {
+ "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
+ "ANCM_PATH": "$(TargetDir)$(AncmPath)",
+ "LAUNCHER_ARGS": "$(TargetPath)",
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "LAUNCHER_PATH": "$(DotNetPath)"
+ }
+ },
+ "ANCM IIS": {
+ "commandName": "Executable",
+ "executablePath": "$(IISPath)",
+ "commandLineArgs": "$(IISArguments)",
+ "environmentVariables": {
+ "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
+ "ANCM_PATH": "$(TargetDir)$(AncmPath)",
+ "LAUNCHER_ARGS": "$(TargetPath)",
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "LAUNCHER_PATH": "$(DotNetPath)"
+ }
+ }
+ }
+}
diff --git a/test/TestSites/StartupHelloWorld.cs b/test/WebSites/OutOfProcessWebSite/StartupHelloWorld.cs
similarity index 100%
rename from test/TestSites/StartupHelloWorld.cs
rename to test/WebSites/OutOfProcessWebSite/StartupHelloWorld.cs
diff --git a/test/TestSites/StartupHttpsHelloWorld.cs b/test/WebSites/OutOfProcessWebSite/StartupHttpsHelloWorld.cs
similarity index 100%
rename from test/TestSites/StartupHttpsHelloWorld.cs
rename to test/WebSites/OutOfProcessWebSite/StartupHttpsHelloWorld.cs
diff --git a/test/TestSites/StartupNtlmAuthentication.cs b/test/WebSites/OutOfProcessWebSite/StartupNtlmAuthentication.cs
similarity index 100%
rename from test/TestSites/StartupNtlmAuthentication.cs
rename to test/WebSites/OutOfProcessWebSite/StartupNtlmAuthentication.cs
diff --git a/test/TestSites/StartupUpgradeFeatureDetection.cs b/test/WebSites/OutOfProcessWebSite/StartupUpgradeFeatureDetection.cs
similarity index 100%
rename from test/TestSites/StartupUpgradeFeatureDetection.cs
rename to test/WebSites/OutOfProcessWebSite/StartupUpgradeFeatureDetection.cs
diff --git a/test/TestSites/web.config b/test/WebSites/OutOfProcessWebSite/web.config
similarity index 100%
rename from test/TestSites/web.config
rename to test/WebSites/OutOfProcessWebSite/web.config
diff --git a/test/WebSites/OverriddenServerWebSite/OverriddenServerWebSite.csproj b/test/WebSites/OverriddenServerWebSite/OverriddenServerWebSite.csproj
new file mode 100644
index 0000000000..4332ea3fd1
--- /dev/null
+++ b/test/WebSites/OverriddenServerWebSite/OverriddenServerWebSite.csproj
@@ -0,0 +1,17 @@
+
+
+
+
+
+ $(StandardTestTfms)
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/WebSites/OverriddenServerWebSite/Program.cs b/test/WebSites/OverriddenServerWebSite/Program.cs
new file mode 100644
index 0000000000..bb65e03004
--- /dev/null
+++ b/test/WebSites/OverriddenServerWebSite/Program.cs
@@ -0,0 +1,48 @@
+// 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.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Features;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace IISTestSite
+{
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ var host = new WebHostBuilder()
+ .UseIISIntegration()
+ .ConfigureServices(services => services.AddSingleton())
+ .Configure(builder => builder.Run(async context => { await context.Response.WriteAsync("I shouldn't work"); }))
+ .Build();
+
+ host.Run();
+ }
+ }
+
+ public class DummyServer: IServer
+ {
+ public void Dispose()
+ {
+ }
+
+ public Task StartAsync(IHttpApplication application, CancellationToken cancellationToken)
+ {
+ return Task.Delay(TimeSpan.MaxValue);
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ return Task.Delay(TimeSpan.MaxValue);
+ }
+
+ public IFeatureCollection Features { get; }
+ }
+}
diff --git a/test/WebSites/OverriddenServerWebSite/Properties/launchSettings.json b/test/WebSites/OverriddenServerWebSite/Properties/launchSettings.json
new file mode 100644
index 0000000000..6d5ce43f73
--- /dev/null
+++ b/test/WebSites/OverriddenServerWebSite/Properties/launchSettings.json
@@ -0,0 +1,37 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": true,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:5762/",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "ANCM IIS Express": {
+ "commandName": "Executable",
+ "executablePath": "$(IISExpressPath)",
+ "commandLineArgs": "$(IISExpressArguments)",
+ "nativeDebugging": true,
+ "environmentVariables": {
+ "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
+ "ANCM_PATH": "$(TargetDir)$(AncmPath)",
+ "LAUNCHER_ARGS": "$(TargetPath)",
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "LAUNCHER_PATH": "$(DotNetPath)"
+ }
+ },
+ "ANCM IIS": {
+ "commandName": "Executable",
+ "executablePath": "$(IISPath)",
+ "commandLineArgs": "$(IISArguments)",
+ "environmentVariables": {
+ "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
+ "ANCM_PATH": "$(TargetDir)$(AncmPath)",
+ "LAUNCHER_ARGS": "$(TargetPath)",
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "LAUNCHER_PATH": "$(DotNetPath)"
+ }
+ }
+ }
+}
diff --git a/test/WebSites/OverriddenServerWebSite/web.config b/test/WebSites/OverriddenServerWebSite/web.config
new file mode 100644
index 0000000000..f125d57107
--- /dev/null
+++ b/test/WebSites/OverriddenServerWebSite/web.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/test/ANCMStressTestApp/Program.cs b/test/WebSites/StressTestWebSite/Program.cs
similarity index 69%
rename from test/ANCMStressTestApp/Program.cs
rename to test/WebSites/StressTestWebSite/Program.cs
index b0edb5b7f2..e8e5392c2c 100644
--- a/test/ANCMStressTestApp/Program.cs
+++ b/test/WebSites/StressTestWebSite/Program.cs
@@ -1,16 +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.Linq;
-using System.Threading;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Features;
-using Microsoft.AspNetCore.Server.IISIntegration;
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace ANCMStressTestApp
diff --git a/test/WebSites/StressTestWebSite/Properties/launchSettings.json b/test/WebSites/StressTestWebSite/Properties/launchSettings.json
new file mode 100644
index 0000000000..6d5ce43f73
--- /dev/null
+++ b/test/WebSites/StressTestWebSite/Properties/launchSettings.json
@@ -0,0 +1,37 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": true,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:5762/",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "ANCM IIS Express": {
+ "commandName": "Executable",
+ "executablePath": "$(IISExpressPath)",
+ "commandLineArgs": "$(IISExpressArguments)",
+ "nativeDebugging": true,
+ "environmentVariables": {
+ "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
+ "ANCM_PATH": "$(TargetDir)$(AncmPath)",
+ "LAUNCHER_ARGS": "$(TargetPath)",
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "LAUNCHER_PATH": "$(DotNetPath)"
+ }
+ },
+ "ANCM IIS": {
+ "commandName": "Executable",
+ "executablePath": "$(IISPath)",
+ "commandLineArgs": "$(IISArguments)",
+ "environmentVariables": {
+ "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
+ "ANCM_PATH": "$(TargetDir)$(AncmPath)",
+ "LAUNCHER_ARGS": "$(TargetPath)",
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "LAUNCHER_PATH": "$(DotNetPath)"
+ }
+ }
+ }
+}
diff --git a/test/ANCMStressTestApp/Startup.cs b/test/WebSites/StressTestWebSite/Startup.cs
similarity index 100%
rename from test/ANCMStressTestApp/Startup.cs
rename to test/WebSites/StressTestWebSite/Startup.cs
diff --git a/test/ANCMStressTestApp/ANCMStressTestApp.csproj b/test/WebSites/StressTestWebSite/StressTestWebSite.csproj
similarity index 68%
rename from test/ANCMStressTestApp/ANCMStressTestApp.csproj
rename to test/WebSites/StressTestWebSite/StressTestWebSite.csproj
index 54755b4824..3566143fcd 100644
--- a/test/ANCMStressTestApp/ANCMStressTestApp.csproj
+++ b/test/WebSites/StressTestWebSite/StressTestWebSite.csproj
@@ -1,12 +1,13 @@
+
+
- netcoreapp2.1
- win-x86;win-x64
+ $(StandardTestTfms)
-
+
diff --git a/test/ANCMStressTestApp/WebSockets/Constants.cs b/test/WebSites/StressTestWebSite/WebSockets/Constants.cs
similarity index 100%
rename from test/ANCMStressTestApp/WebSockets/Constants.cs
rename to test/WebSites/StressTestWebSite/WebSockets/Constants.cs
diff --git a/test/ANCMStressTestApp/WebSockets/HandshakeHelpers.cs b/test/WebSites/StressTestWebSite/WebSockets/HandshakeHelpers.cs
similarity index 100%
rename from test/ANCMStressTestApp/WebSockets/HandshakeHelpers.cs
rename to test/WebSites/StressTestWebSite/WebSockets/HandshakeHelpers.cs