Merge release/2.2 into master

This commit is contained in:
Justin Kotalik 2018-07-18 15:05:35 -07:00
commit bc995251f8
53 changed files with 726 additions and 368 deletions

View File

@ -113,6 +113,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.FunctionalTests", "test
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IntegrationTesting.IIS", "src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj", "{34135ED7-313D-4E68-860C-D6B51AA28523}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IntegrationTesting.IIS", "src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj", "{34135ED7-313D-4E68-860C-D6B51AA28523}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.Tests", "test\IIS.Tests\IIS.Tests.csproj", "{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Tests", "test\Common.Tests\Common.Tests.csproj", "{D17B7B35-5361-4A50-B499-E03E5C3CC095}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -381,6 +385,30 @@ Global
{34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x64.Build.0 = Release|Any CPU {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x64.Build.0 = Release|Any CPU
{34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x86.ActiveCfg = Release|Any CPU {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x86.ActiveCfg = Release|Any CPU
{34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x86.Build.0 = Release|Any CPU {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x86.Build.0 = Release|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Debug|x64.ActiveCfg = Debug|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Debug|x64.Build.0 = Debug|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Debug|x86.ActiveCfg = Debug|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Debug|x86.Build.0 = Debug|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Release|Any CPU.Build.0 = Release|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Release|x64.ActiveCfg = Release|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Release|x64.Build.0 = Release|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Release|x86.ActiveCfg = Release|Any CPU
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E}.Release|x86.Build.0 = Release|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Debug|x64.ActiveCfg = Debug|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Debug|x64.Build.0 = Debug|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Debug|x86.ActiveCfg = Debug|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Debug|x86.Build.0 = Debug|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Release|Any CPU.Build.0 = Release|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Release|x64.ActiveCfg = Release|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Release|x64.Build.0 = Release|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Release|x86.ActiveCfg = Release|Any CPU
{D17B7B35-5361-4A50-B499-E03E5C3CC095}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -411,6 +439,8 @@ Global
{1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E} {1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
{D182103F-8405-4647-B158-C36F598657EF} = {EF30B533-D715-421A-92B7-92FEF460AC9C} {D182103F-8405-4647-B158-C36F598657EF} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{34135ED7-313D-4E68-860C-D6B51AA28523} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD} {34135ED7-313D-4E68-860C-D6B51AA28523} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{C0310D84-BC2F-4B2E-870E-D35044DB3E3E} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{D17B7B35-5361-4A50-B499-E03E5C3CC095} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5} SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}

View File

@ -120,6 +120,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.FunctionalTests", "test
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IntegrationTesting.IIS", "src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj", "{CE4FB142-91FB-4B34-BC96-A31120EF4009}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IntegrationTesting.IIS", "src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj", "{CE4FB142-91FB-4B34-BC96-A31120EF4009}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.Tests", "test\IIS.Tests\IIS.Tests.csproj", "{A091777D-66B3-42E1-B95C-85322DE40706}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Tests", "test\Common.Tests\Common.Tests.csproj", "{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -408,6 +412,30 @@ Global
{CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x64.Build.0 = Release|Any CPU {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x64.Build.0 = Release|Any CPU
{CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x86.ActiveCfg = Release|Any CPU {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x86.ActiveCfg = Release|Any CPU
{CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x86.Build.0 = Release|Any CPU {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x86.Build.0 = Release|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Debug|x64.ActiveCfg = Debug|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Debug|x64.Build.0 = Debug|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Debug|x86.ActiveCfg = Debug|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Debug|x86.Build.0 = Debug|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Release|Any CPU.Build.0 = Release|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Release|x64.ActiveCfg = Release|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Release|x64.Build.0 = Release|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Release|x86.ActiveCfg = Release|Any CPU
{A091777D-66B3-42E1-B95C-85322DE40706}.Release|x86.Build.0 = Release|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Debug|x64.ActiveCfg = Debug|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Debug|x64.Build.0 = Debug|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Debug|x86.ActiveCfg = Debug|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Debug|x86.Build.0 = Debug|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Release|Any CPU.Build.0 = Release|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Release|x64.ActiveCfg = Release|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Release|x64.Build.0 = Release|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Release|x86.ActiveCfg = Release|Any CPU
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -441,6 +469,8 @@ Global
{1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E} {1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
{1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712} = {EF30B533-D715-421A-92B7-92FEF460AC9C} {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{CE4FB142-91FB-4B34-BC96-A31120EF4009} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD} {CE4FB142-91FB-4B34-BC96-A31120EF4009} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{A091777D-66B3-42E1-B95C-85322DE40706} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{A641A208-2974-4E48-BCFF-54E3AAFA4FB9} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5} SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}

View File

@ -25,6 +25,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" />
<ProjectReference Include="..\..\test\IISExpress.FunctionalTests\IISExpress.FunctionalTests.csproj" /> <ProjectReference Include="..\..\test\IISExpress.FunctionalTests\IISExpress.FunctionalTests.csproj" />
<ProjectReference Include="..\..\test\IIS.Tests\IIS.Tests.csproj" />
<ProjectReference Include="..\..\test\WebSites\**\*.csproj"> <ProjectReference Include="..\..\test\WebSites\**\*.csproj">
<ReferenceOutputAssembly>False</ReferenceOutputAssembly> <ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference> </ProjectReference>

View File

@ -5,36 +5,36 @@
<PropertyGroup Label="Package Versions"> <PropertyGroup Label="Package Versions">
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion> <BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
<InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-10009</InternalAspNetCoreSdkPackageVersion> <InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-10009</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreAllPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreAllPackageVersion> <MicrosoftAspNetCoreAllPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreAllPackageVersion>
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreAuthenticationCorePackageVersion> <MicrosoftAspNetCoreAuthenticationCorePackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion> <MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreHostingAbstractionsPackageVersion> <MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreHostingPackageVersion> <MicrosoftAspNetCoreHostingPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreHttpExtensionsPackageVersion> <MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftAspNetCoreHttpOverridesPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreHttpOverridesPackageVersion> <MicrosoftAspNetCoreHttpOverridesPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreHttpOverridesPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreHttpPackageVersion> <MicrosoftAspNetCoreHttpPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreHttpSysSourcesPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreHttpSysSourcesPackageVersion> <MicrosoftAspNetCoreHttpSysSourcesPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreHttpSysSourcesPackageVersion>
<MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.7.0-alpha1-10081</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion> <MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.7.0-alpha1-10102</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreServerKestrelPackageVersion> <MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreTestHostPackageVersion> <MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreTestingPackageVersion> <MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>3.0.0-alpha1-10081</MicrosoftAspNetCoreWebUtilitiesPackageVersion> <MicrosoftAspNetCoreWebUtilitiesPackageVersion>3.0.0-alpha1-10102</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
<MicrosoftBuildFrameworkPackageVersion>15.6.82</MicrosoftBuildFrameworkPackageVersion> <MicrosoftBuildFrameworkPackageVersion>15.6.82</MicrosoftBuildFrameworkPackageVersion>
<MicrosoftBuildUtilitiesCorePackageVersion>15.6.82</MicrosoftBuildUtilitiesCorePackageVersion> <MicrosoftBuildUtilitiesCorePackageVersion>15.6.82</MicrosoftBuildUtilitiesCorePackageVersion>
<MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion> <MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion> <MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion> <MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsConfigurationJsonPackageVersion> <MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsConfigurationJsonPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsLoggingAbstractionsPackageVersion> <MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsLoggingConsolePackageVersion> <MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsLoggingDebugPackageVersion> <MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsLoggingPackageVersion> <MicrosoftExtensionsLoggingPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsLoggingTestingPackageVersion> <MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-alpha1-10081</MicrosoftExtensionsOptionsPackageVersion> <MicrosoftExtensionsOptionsPackageVersion>3.0.0-alpha1-10102</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion> <MicrosoftNETCoreApp20PackageVersion>2.0.9</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.2</MicrosoftNETCoreApp21PackageVersion> <MicrosoftNETCoreApp21PackageVersion>2.1.2</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview1-26618-02</MicrosoftNETCoreApp22PackageVersion> <MicrosoftNETCoreApp22PackageVersion>2.2.0-preview1-26618-02</MicrosoftNETCoreApp22PackageVersion>
<MicrosoftNetHttpHeadersPackageVersion>3.0.0-alpha1-10081</MicrosoftNetHttpHeadersPackageVersion> <MicrosoftNetHttpHeadersPackageVersion>3.0.0-alpha1-10102</MicrosoftNetHttpHeadersPackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion> <MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
<MicrosoftWebAdministrationPackageVersion>11.1.0</MicrosoftWebAdministrationPackageVersion> <MicrosoftWebAdministrationPackageVersion>11.1.0</MicrosoftWebAdministrationPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion> <NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>

View File

@ -12,12 +12,21 @@
#include "SRWExclusiveLock.h" #include "SRWExclusiveLock.h"
#include "GlobalVersionUtility.h" #include "GlobalVersionUtility.h"
#include "exceptions.h" #include "exceptions.h"
#include "HandleWrapper.h"
#include "PollingAppOfflineApplication.h" #include "PollingAppOfflineApplication.h"
#include "EventLog.h"
extern HINSTANCE g_hModule;
const PCWSTR APPLICATION_INFO::s_pwzAspnetcoreInProcessRequestHandlerName = L"aspnetcorev2_inprocess.dll"; const PCWSTR APPLICATION_INFO::s_pwzAspnetcoreInProcessRequestHandlerName = L"aspnetcorev2_inprocess.dll";
const PCWSTR APPLICATION_INFO::s_pwzAspnetcoreOutOfProcessRequestHandlerName = L"aspnetcorev2_outofprocess.dll"; const PCWSTR APPLICATION_INFO::s_pwzAspnetcoreOutOfProcessRequestHandlerName = L"aspnetcorev2_outofprocess.dll";
SRWLOCK APPLICATION_INFO::s_requestHandlerLoadLock {};
bool APPLICATION_INFO::s_fAspnetcoreRHAssemblyLoaded = false;
bool APPLICATION_INFO::s_fAspnetcoreRHLoadedError = false;
HMODULE APPLICATION_INFO::s_hAspnetCoreRH = nullptr;
PFN_ASPNETCORE_CREATE_APPLICATION APPLICATION_INFO::s_pfnAspNetCoreCreateApplication = nullptr;
APPLICATION_INFO::~APPLICATION_INFO() APPLICATION_INFO::~APPLICATION_INFO()
{ {
if (m_pApplication != NULL) if (m_pApplication != NULL)
@ -39,23 +48,14 @@ APPLICATION_INFO::~APPLICATION_INFO()
HRESULT HRESULT
APPLICATION_INFO::Initialize( APPLICATION_INFO::Initialize(
_In_ IHttpServer *pServer, _In_ IHttpApplication &pApplication
_In_ IHttpApplication *pApplication
) )
{ {
HRESULT hr = S_OK; m_pConfiguration = new ASPNETCORE_SHIM_CONFIG();
RETURN_IF_FAILED(m_pConfiguration->Populate(&m_pServer, &pApplication));
RETURN_IF_FAILED(m_struInfoKey.Copy(pApplication.GetApplicationId()));
DBG_ASSERT(pServer); return S_OK;
DBG_ASSERT(pApplication);
// todo: make sure Initialize should be called only once
m_pServer = pServer;
FINISHED_IF_NULL_ALLOC(m_pConfiguration = new ASPNETCORE_SHIM_CONFIG());
FINISHED_IF_FAILED(m_pConfiguration->Populate(m_pServer, pApplication));
FINISHED_IF_FAILED(m_struInfoKey.Copy(pApplication->GetApplicationId()));
Finished:
return hr;
} }
@ -125,7 +125,7 @@ APPLICATION_INFO::EnsureApplicationCreated(
}; };
LOG_INFO("Creating handler application"); LOG_INFO("Creating handler application");
FINISHED_IF_FAILED(m_pfnAspNetCoreCreateApplication( FINISHED_IF_FAILED(m_pfnAspNetCoreCreateApplication(
m_pServer, &m_pServer,
pHttpContext->GetApplication(), pHttpContext->GetApplication(),
parameters.data(), parameters.data(),
static_cast<DWORD>(parameters.size()), static_cast<DWORD>(parameters.size()),
@ -157,19 +157,18 @@ APPLICATION_INFO::FindRequestHandlerAssembly(STRU& location)
PCWSTR pstrHandlerDllName; PCWSTR pstrHandlerDllName;
STACK_STRU(struFileName, 256); STACK_STRU(struFileName, 256);
if (g_fAspnetcoreRHLoadedError) if (s_fAspnetcoreRHLoadedError)
{ {
FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE); FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE);
} }
else if (!g_fAspnetcoreRHAssemblyLoaded) else if (!s_fAspnetcoreRHAssemblyLoaded)
{ {
SRWExclusiveLock lock(g_srwLock); SRWExclusiveLock lock(s_requestHandlerLoadLock);
if (s_fAspnetcoreRHLoadedError)
if (g_fAspnetcoreRHLoadedError)
{ {
FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE); FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE);
} }
if (g_fAspnetcoreRHAssemblyLoaded) if (s_fAspnetcoreRHAssemblyLoaded)
{ {
FINISHED(S_OK); FINISHED(S_OK);
} }
@ -184,9 +183,9 @@ APPLICATION_INFO::FindRequestHandlerAssembly(STRU& location)
} }
// Try to see if RH is already loaded // Try to see if RH is already loaded
g_hAspnetCoreRH = GetModuleHandle(pstrHandlerDllName); s_hAspnetCoreRH = GetModuleHandle(pstrHandlerDllName);
if (g_hAspnetCoreRH == NULL) if (s_hAspnetCoreRH == NULL)
{ {
if (m_pConfiguration->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS) if (m_pConfiguration->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{ {
@ -229,22 +228,22 @@ APPLICATION_INFO::FindRequestHandlerAssembly(STRU& location)
WLOG_INFOF(L"Loading request handler: %s", struFileName.QueryStr()); WLOG_INFOF(L"Loading request handler: %s", struFileName.QueryStr());
g_hAspnetCoreRH = LoadLibraryW(struFileName.QueryStr()); s_hAspnetCoreRH = LoadLibraryW(struFileName.QueryStr());
if (g_hAspnetCoreRH == NULL) if (s_hAspnetCoreRH == NULL)
{ {
FINISHED(HRESULT_FROM_WIN32(GetLastError())); FINISHED(HRESULT_FROM_WIN32(GetLastError()));
} }
} }
g_pfnAspNetCoreCreateApplication = (PFN_ASPNETCORE_CREATE_APPLICATION) s_pfnAspNetCoreCreateApplication = (PFN_ASPNETCORE_CREATE_APPLICATION)
GetProcAddress(g_hAspnetCoreRH, "CreateApplication"); GetProcAddress(s_hAspnetCoreRH, "CreateApplication");
if (g_pfnAspNetCoreCreateApplication == NULL) if (s_pfnAspNetCoreCreateApplication == NULL)
{ {
FINISHED(HRESULT_FROM_WIN32(GetLastError())); FINISHED(HRESULT_FROM_WIN32(GetLastError()));
} }
g_fAspnetcoreRHAssemblyLoaded = TRUE; s_fAspnetcoreRHAssemblyLoaded = TRUE;
} }
Finished: Finished:
@ -252,11 +251,11 @@ Finished:
// Question: we remember the load failure so that we will not try again. // Question: we remember the load failure so that we will not try again.
// User needs to check whether the fuction pointer is NULL // User needs to check whether the fuction pointer is NULL
// //
m_pfnAspNetCoreCreateApplication = g_pfnAspNetCoreCreateApplication; m_pfnAspNetCoreCreateApplication = s_pfnAspNetCoreCreateApplication;
if (!g_fAspnetcoreRHLoadedError && FAILED(hr)) if (!s_fAspnetcoreRHLoadedError && FAILED(hr))
{ {
g_fAspnetcoreRHLoadedError = TRUE; s_fAspnetcoreRHLoadedError = TRUE;
} }
return hr; return hr;
} }
@ -457,7 +456,7 @@ APPLICATION_INFO::RecycleApplication()
if (m_pConfiguration->QueryHostingModel() == HOSTING_IN_PROCESS) if (m_pConfiguration->QueryHostingModel() == HOSTING_IN_PROCESS)
{ {
// In process application failed to start for whatever reason, need to recycle the work process // In process application failed to start for whatever reason, need to recycle the work process
m_pServer->RecycleProcess(L"AspNetCore InProcess Recycle Process on Demand"); m_pServer.RecycleProcess(L"AspNetCore InProcess Recycle Process on Demand");
} }
} }
@ -466,7 +465,7 @@ APPLICATION_INFO::RecycleApplication()
if (!g_fRecycleProcessCalled) if (!g_fRecycleProcessCalled)
{ {
g_fRecycleProcessCalled = TRUE; g_fRecycleProcessCalled = TRUE;
g_pHttpServer->RecycleProcess(L"On Demand by AspNetCore Module for recycle application failure"); m_pServer.RecycleProcess(L"On Demand by AspNetCore Module for recycle application failure");
} }
} }
else else

View File

@ -23,14 +23,13 @@ HRESULT
); );
extern BOOL g_fRecycleProcessCalled; extern BOOL g_fRecycleProcessCalled;
extern PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
class APPLICATION_INFO class APPLICATION_INFO
{ {
public: public:
APPLICATION_INFO() : APPLICATION_INFO(_In_ IHttpServer &pServer) :
m_pServer(NULL), m_pServer(pServer),
m_cRefs(1), m_cRefs(1),
m_fValid(FALSE), m_fValid(FALSE),
m_fAppCreationAttempted(FALSE), m_fAppCreationAttempted(FALSE),
@ -48,11 +47,17 @@ public:
virtual virtual
~APPLICATION_INFO(); ~APPLICATION_INFO();
static
void
StaticInitialize()
{
InitializeSRWLock(&s_requestHandlerLoadLock);
}
HRESULT HRESULT
Initialize( Initialize(
_In_ IHttpServer *pServer, _In_ IHttpApplication &pApplication
_In_ IHttpApplication *pApplication
); );
VOID VOID
@ -125,11 +130,17 @@ private:
ASPNETCORE_SHIM_CONFIG *m_pConfiguration; ASPNETCORE_SHIM_CONFIG *m_pConfiguration;
IAPPLICATION *m_pApplication; IAPPLICATION *m_pApplication;
SRWLOCK m_srwLock; SRWLOCK m_srwLock;
IHttpServer *m_pServer; IHttpServer &m_pServer;
PFN_ASPNETCORE_CREATE_APPLICATION m_pfnAspNetCoreCreateApplication; PFN_ASPNETCORE_CREATE_APPLICATION m_pfnAspNetCoreCreateApplication;
static const PCWSTR s_pwzAspnetcoreInProcessRequestHandlerName; static const PCWSTR s_pwzAspnetcoreInProcessRequestHandlerName;
static const PCWSTR s_pwzAspnetcoreOutOfProcessRequestHandlerName; static const PCWSTR s_pwzAspnetcoreOutOfProcessRequestHandlerName;
static SRWLOCK s_requestHandlerLoadLock;
static bool s_fAspnetcoreRHAssemblyLoaded;
static bool s_fAspnetcoreRHLoadedError;
static HMODULE s_hAspnetCoreRH;
static PFN_ASPNETCORE_CREATE_APPLICATION s_pfnAspNetCoreCreateApplication;
}; };
class APPLICATION_INFO_HASH : class APPLICATION_INFO_HASH :

View File

@ -8,6 +8,9 @@
#include "resources.h" #include "resources.h"
#include "SRWExclusiveLock.h" #include "SRWExclusiveLock.h"
#include "exceptions.h" #include "exceptions.h"
#include "EventLog.h"
extern BOOL g_fInShutdown;
// The application manager is a singleton across ANCM. // The application manager is a singleton across ANCM.
APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL; APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
@ -18,7 +21,6 @@ APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
// //
HRESULT HRESULT
APPLICATION_MANAGER::GetOrCreateApplicationInfo( APPLICATION_MANAGER::GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ IHttpContext* pHttpContext, _In_ IHttpContext* pHttpContext,
_Out_ APPLICATION_INFO ** ppApplicationInfo _Out_ APPLICATION_INFO ** ppApplicationInfo
) )
@ -32,56 +34,37 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo(
STACK_STRU ( strEventMsg, 256 ); STACK_STRU ( strEventMsg, 256 );
DBG_ASSERT(pServer);
DBG_ASSERT(pHttpContext); DBG_ASSERT(pHttpContext);
DBG_ASSERT(ppApplicationInfo); DBG_ASSERT(ppApplicationInfo);
*ppApplicationInfo = NULL; *ppApplicationInfo = NULL;
IHttpApplication &pApplication = *pHttpContext->GetApplication();
if (!m_fDebugInitialize)
{
SRWExclusiveLock lock(m_srwLock);
if (!m_fDebugInitialize)
{
DebugInitializeFromConfig(*pServer, *pHttpContext->GetApplication());
m_fDebugInitialize = TRUE;
}
}
// The configuration path is unique for each application and is used for the // The configuration path is unique for each application and is used for the
// key in the applicationInfoHash. // key in the applicationInfoHash.
pszApplicationId = pHttpContext->GetApplication()->GetApplicationId(); pszApplicationId = pApplication.GetApplicationId();
// When accessing the m_pApplicationInfoHash, we need to acquire the application manager // When accessing the m_pApplicationInfoHash, we need to acquire the application manager
// lock to avoid races on setting state. // lock to avoid races on setting state.
SRWSharedLock lock(m_srwLock);
if (!m_fDebugInitialize)
{ {
SRWSharedLock lock(m_srwLock); DebugInitializeFromConfig(m_pHttpServer, pApplication);
if (g_fInShutdown) m_fDebugInitialize = TRUE;
{
FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
}
m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
} }
if (g_fInShutdown)
{
FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
}
m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
if (*ppApplicationInfo == NULL) if (*ppApplicationInfo == NULL)
{ {
pApplicationInfo = new APPLICATION_INFO(); pApplicationInfo = new APPLICATION_INFO(m_pHttpServer);
FINISHED_IF_FAILED(pApplicationInfo->Initialize(pServer, pHttpContext->GetApplication())); FINISHED_IF_FAILED(pApplicationInfo->Initialize(pApplication));
SRWExclusiveLock lock(m_srwLock);
if (g_fInShutdown)
{
// Already in shuting down. No need to create the application
FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
}
m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
if (*ppApplicationInfo != NULL)
{
// someone else created the application
FINISHED(S_OK);
}
hostingModel = pApplicationInfo->QueryConfig()->QueryHostingModel(); hostingModel = pApplicationInfo->QueryConfig()->QueryHostingModel();
@ -309,7 +292,7 @@ Finished:
if (!g_fRecycleProcessCalled) if (!g_fRecycleProcessCalled)
{ {
g_fRecycleProcessCalled = TRUE; g_fRecycleProcessCalled = TRUE;
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand Due Application Recycle Error"); m_pHttpServer.RecycleProcess(L"AspNetCore Recycle Process on Demand Due Application Recycle Error");
} }
} }

View File

@ -27,15 +27,9 @@ public:
static static
APPLICATION_MANAGER* APPLICATION_MANAGER*
GetInstance( GetInstance()
VOID
)
{ {
if ( sm_pApplicationManager == NULL ) assert(sm_pApplicationManager);
{
sm_pApplicationManager = new APPLICATION_MANAGER();
}
return sm_pApplicationManager; return sm_pApplicationManager;
} }
@ -68,7 +62,6 @@ public:
HRESULT HRESULT
GetOrCreateApplicationInfo( GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ IHttpContext* pHttpContext, _In_ IHttpContext* pHttpContext,
_Out_ APPLICATION_INFO ** ppApplicationInfo _Out_ APPLICATION_INFO ** ppApplicationInfo
); );
@ -92,6 +85,16 @@ public:
} }
} }
static HRESULT StaticInitialize(IHttpServer& pHttpServer)
{
assert(!sm_pApplicationManager);
sm_pApplicationManager = new APPLICATION_MANAGER(pHttpServer);
RETURN_IF_FAILED(sm_pApplicationManager->Initialize());
APPLICATION_INFO::StaticInitialize();
return S_OK;
}
HRESULT Initialize() HRESULT Initialize()
{ {
if(m_pApplicationInfoHash == NULL) if(m_pApplicationInfoHash == NULL)
@ -107,12 +110,11 @@ public:
} }
private: private:
// APPLICATION_MANAGER(IHttpServer& pHttpServer) :
// we currently limit the size of m_pstrErrorInfo to 5000, be careful if you want to change its payload m_pApplicationInfoHash(NULL),
//
APPLICATION_MANAGER() : m_pApplicationInfoHash(NULL),
m_hostingModel(HOSTING_UNKNOWN), m_hostingModel(HOSTING_UNKNOWN),
m_fDebugInitialize(FALSE) m_fDebugInitialize(FALSE),
m_pHttpServer(pHttpServer)
{ {
InitializeSRWLock(&m_srwLock); InitializeSRWLock(&m_srwLock);
} }
@ -120,6 +122,7 @@ private:
APPLICATION_INFO_HASH *m_pApplicationInfoHash; APPLICATION_INFO_HASH *m_pApplicationInfoHash;
static APPLICATION_MANAGER *sm_pApplicationManager; static APPLICATION_MANAGER *sm_pApplicationManager;
SRWLOCK m_srwLock; SRWLOCK m_srwLock;
APP_HOSTING_MODEL m_hostingModel; APP_HOSTING_MODEL m_hostingModel;
BOOL m_fDebugInitialize; BOOL m_fDebugInitialize;
IHttpServer &m_pHttpServer;
}; };

View File

@ -13,20 +13,10 @@
DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2.dll"); DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2.dll");
HTTP_MODULE_ID g_pModuleId = NULL;
IHttpServer * g_pHttpServer = NULL;
HANDLE g_hEventLog = NULL; HANDLE g_hEventLog = NULL;
BOOL g_fRecycleProcessCalled = FALSE; BOOL g_fRecycleProcessCalled = FALSE;
PCWSTR g_pszModuleName = NULL;
HINSTANCE g_hModule; HINSTANCE g_hModule;
HMODULE g_hAspnetCoreRH = NULL;
BOOL g_fAspnetcoreRHAssemblyLoaded = FALSE;
BOOL g_fAspnetcoreRHLoadedError = FALSE;
BOOL g_fInShutdown = FALSE; BOOL g_fInShutdown = FALSE;
DWORD g_dwActiveServerProcesses = 0;
SRWLOCK g_srwLock;
PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
VOID VOID
StaticCleanup() StaticCleanup()
@ -100,17 +90,10 @@ HRESULT
BOOL fDisableANCM = FALSE; BOOL fDisableANCM = FALSE;
ASPNET_CORE_PROXY_MODULE_FACTORY * pFactory = NULL; ASPNET_CORE_PROXY_MODULE_FACTORY * pFactory = NULL;
ASPNET_CORE_GLOBAL_MODULE * pGlobalModule = NULL; ASPNET_CORE_GLOBAL_MODULE * pGlobalModule = NULL;
APPLICATION_MANAGER * pApplicationManager = NULL;
UNREFERENCED_PARAMETER(dwServerVersion); UNREFERENCED_PARAMETER(dwServerVersion);
InitializeSRWLock(&g_srwLock); if (pHttpServer->IsCommandLineLaunch())
g_pModuleId = pModuleInfo->GetId();
g_pszModuleName = pModuleInfo->GetName();
g_pHttpServer = pHttpServer;
if (g_pHttpServer->IsCommandLineLaunch())
{ {
g_hEventLog = RegisterEventSource(NULL, ASPNETCORE_IISEXPRESS_EVENT_PROVIDER); g_hEventLog = RegisterEventSource(NULL, ASPNETCORE_IISEXPRESS_EVENT_PROVIDER);
} }
@ -175,13 +158,12 @@ HRESULT
0)); 0));
pFactory = NULL; pFactory = NULL;
pApplicationManager = APPLICATION_MANAGER::GetInstance();
FINISHED_IF_FAILED(pApplicationManager->Initialize()); FINISHED_IF_FAILED(APPLICATION_MANAGER::StaticInitialize(*pHttpServer));
pGlobalModule = NULL; pGlobalModule = NULL;
pGlobalModule = new ASPNET_CORE_GLOBAL_MODULE(pApplicationManager); pGlobalModule = new ASPNET_CORE_GLOBAL_MODULE(APPLICATION_MANAGER::GetInstance());
FINISHED_IF_FAILED(pModuleInfo->SetGlobalNotifications( FINISHED_IF_FAILED(pModuleInfo->SetGlobalNotifications(
pGlobalModule, pGlobalModule,

View File

@ -3,6 +3,8 @@
#include "globalmodule.h" #include "globalmodule.h"
extern BOOL g_fInShutdown;
ASPNET_CORE_GLOBAL_MODULE::ASPNET_CORE_GLOBAL_MODULE( ASPNET_CORE_GLOBAL_MODULE::ASPNET_CORE_GLOBAL_MODULE(
APPLICATION_MANAGER* pApplicationManager) APPLICATION_MANAGER* pApplicationManager)
{ {
@ -20,6 +22,8 @@ ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening(
{ {
UNREFERENCED_PARAMETER(pProvider); UNREFERENCED_PARAMETER(pProvider);
LOG_INFO("ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening");
if (g_fInShutdown) if (g_fInShutdown)
{ {
// Avoid receiving two shutudown notifications. // Avoid receiving two shutudown notifications.
@ -52,6 +56,8 @@ ASPNET_CORE_GLOBAL_MODULE::OnGlobalConfigurationChange(
// Retrieve the path that has changed. // Retrieve the path that has changed.
PCWSTR pwszChangePath = pProvider->GetChangePath(); PCWSTR pwszChangePath = pProvider->GetChangePath();
LOG_INFOF("ASPNET_CORE_GLOBAL_MODULE::OnGlobalConfigurationChange %S", pwszChangePath);
// Test for an error. // Test for an error.
if (NULL != pwszChangePath && if (NULL != pwszChangePath &&
_wcsicmp(pwszChangePath, L"MACHINE") != 0 && _wcsicmp(pwszChangePath, L"MACHINE") != 0 &&

View File

@ -20,6 +20,7 @@ public:
VOID Terminate() VOID Terminate()
{ {
LOG_INFO("ASPNET_CORE_GLOBAL_MODULE::Terminate");
// Remove the class from memory. // Remove the class from memory.
delete this; delete this;
} }

View File

@ -7,6 +7,9 @@
#include "applicationinfo.h" #include "applicationinfo.h"
#include "acache.h" #include "acache.h"
#include "exceptions.h" #include "exceptions.h"
extern BOOL g_fInShutdown;
__override __override
HRESULT HRESULT
ASPNET_CORE_PROXY_MODULE_FACTORY::GetHttpModule( ASPNET_CORE_PROXY_MODULE_FACTORY::GetHttpModule(
@ -83,7 +86,6 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
pApplicationManager = APPLICATION_MANAGER::GetInstance(); pApplicationManager = APPLICATION_MANAGER::GetInstance();
FINISHED_IF_FAILED(pApplicationManager->GetOrCreateApplicationInfo( FINISHED_IF_FAILED(pApplicationManager->GetOrCreateApplicationInfo(
g_pHttpServer,
pHttpContext, pHttpContext,
&m_pApplicationInfo)); &m_pApplicationInfo));

View File

@ -8,8 +8,6 @@
#include "irequesthandler.h" #include "irequesthandler.h"
extern HTTP_MODULE_ID g_pModuleId; extern HTTP_MODULE_ID g_pModuleId;
extern IHttpServer *g_pHttpServer;
extern HMODULE g_hAspnetCoreRH;
class ASPNET_CORE_PROXY_MODULE : public CHttpModule class ASPNET_CORE_PROXY_MODULE : public CHttpModule
{ {

View File

@ -9,8 +9,8 @@
// //
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define NTDDI_VERSION 0x06010000 #define NTDDI_VERSION NTDDI_WIN7
#define WINVER 0x0601 #define WINVER _WIN32_WINNT_WIN7
#define _WIN32_WINNT 0x0601 #define _WIN32_WINNT 0x0601
#include <Windows.h> #include <Windows.h>
@ -20,16 +20,4 @@
#include "stringu.h" #include "stringu.h"
#include "stringa.h" #include "stringa.h"
extern PVOID g_pModuleId;
extern BOOL g_fAspnetcoreRHAssemblyLoaded;
extern BOOL g_fAspnetcoreRHLoadedError;
extern BOOL g_fInShutdown;
extern BOOL g_fEnableReferenceCountTracing;
extern DWORD g_dwActiveServerProcesses;
extern HINSTANCE g_hModule;
extern HMODULE g_hAspnetCoreRH;
extern SRWLOCK g_srwLock;
extern PCWSTR g_pwzAspnetcoreRequestHandlerName;
extern HANDLE g_hEventLog;
#pragma warning( error : 4091) #pragma warning( error : 4091)

View File

@ -6,4 +6,6 @@
#include "Utility.h" #include "Utility.h"
#include "resources.h" #include "resources.h"
extern HANDLE g_hEventLog;
#define EVENTLOG(log, name, ...) UTILITY::LogEventF(log, ASPNETCORE_EVENT_ ## name ## _LEVEL, ASPNETCORE_EVENT_ ## name, ASPNETCORE_EVENT_ ## name ## _MSG, __VA_ARGS__) #define EVENTLOG(log, name, ...) UTILITY::LogEventF(log, ASPNETCORE_EVENT_ ## name ## _LEVEL, ASPNETCORE_EVENT_ ## name, ASPNETCORE_EVENT_ ## name ## _MSG, __VA_ARGS__)

View File

@ -26,7 +26,6 @@ DebugInitialize()
HKEY hKey; HKEY hKey;
InitializeSRWLock(&g_logFileLock); InitializeSRWLock(&g_logFileLock);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module V2\\Parameters", L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module V2\\Parameters",
0, 0,
@ -71,6 +70,11 @@ DebugInitialize()
{ {
// ignore // ignore
} }
if (IsDebuggerPresent())
{
DEBUG_FLAGS_VAR |= DEBUG_FLAGS_INFO;
}
} }
HRESULT HRESULT

View File

@ -277,10 +277,7 @@ IN_PROCESS_APPLICATION::LoadManagedApplication
goto Finished; goto Finished;
} }
if (FAILED(hr = m_pLoggerProvider->Start())) LOG_IF_FAILED(m_pLoggerProvider->Start());
{
goto Finished;
}
} }
if (m_status != APPLICATION_STATUS::STARTING) if (m_status != APPLICATION_STATUS::STARTING)
@ -564,14 +561,19 @@ IN_PROCESS_APPLICATION::RunDotnetApplication(DWORD argc, CONST PCWSTR* argv, hos
__try __try
{ {
LOG_INFO("Starting managed application");
m_ProcessExitCode = pProc(argc, argv); m_ProcessExitCode = pProc(argc, argv);
if (m_ProcessExitCode != 0) if (m_ProcessExitCode != 0)
{ {
hr = HRESULT_FROM_WIN32(GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError());
} }
LOG_INFOF("Managed application exited with code %d", m_ProcessExitCode);
} }
__except(GetExceptionCode() != 0) __except(GetExceptionCode() != 0)
{ {
LOG_INFOF("Managed threw an exception %d", GetExceptionCode());
hr = HRESULT_FROM_WIN32(GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError());
} }

View File

@ -15,7 +15,8 @@ register_callbacks(
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler, _In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
_In_ PFN_ASYNC_COMPLETION_HANDLER async_completion_handler, _In_ PFN_ASYNC_COMPLETION_HANDLER async_completion_handler,
_In_ VOID* pvRequstHandlerContext, _In_ VOID* pvRequstHandlerContext,
_In_ VOID* pvShutdownHandlerContext _In_ VOID* pvShutdownHandlerContext,
_Out_ BOOL* pfResetStandardStreams
) )
{ {
if (pInProcessApplication == NULL) if (pInProcessApplication == NULL)
@ -30,6 +31,7 @@ register_callbacks(
pvRequstHandlerContext, pvRequstHandlerContext,
pvShutdownHandlerContext pvShutdownHandlerContext
); );
*pfResetStandardStreams = !pInProcessApplication->QueryConfig()->QueryStdoutLogEnabled();
return S_OK; return S_OK;
} }

View File

@ -10,8 +10,8 @@
FileOutputManager::FileOutputManager() : FileOutputManager::FileOutputManager() :
m_hLogFileHandle(INVALID_HANDLE_VALUE), m_hLogFileHandle(INVALID_HANDLE_VALUE),
m_fdPreviousStdOut(0), m_fdPreviousStdOut(-1),
m_fdPreviousStdErr(0) m_fdPreviousStdErr(-1)
{ {
} }
@ -40,14 +40,14 @@ FileOutputManager::~FileOutputManager()
if (m_fdPreviousStdOut >= 0) if (m_fdPreviousStdOut >= 0)
{ {
_dup2(m_fdPreviousStdOut, _fileno(stdout)); LOG_LAST_ERROR_IF(SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdOut)));
LOG_INFOF("Restoring original stdout of stdout: %d", m_fdPreviousStdOut); LOG_INFOF("Restoring original stdout: %d", m_fdPreviousStdOut);
} }
if (m_fdPreviousStdErr >= 0) if (m_fdPreviousStdErr >= 0)
{ {
_dup2(m_fdPreviousStdErr, _fileno(stderr)); LOG_LAST_ERROR_IF(SetStdHandle(STD_ERROR_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdErr)));
LOG_INFOF("Restoring original stdout of stdout: %d", m_fdPreviousStdOut); LOG_INFOF("Restoring original stderr: %d", m_fdPreviousStdOut);
} }
} }
@ -60,10 +60,6 @@ FileOutputManager::Initialize(PCWSTR pwzStdOutLogFileName, PCWSTR pwzApplication
return S_OK; return S_OK;
} }
void FileOutputManager::NotifyStartupComplete()
{
}
bool FileOutputManager::GetStdOutContent(STRA* struStdOutput) bool FileOutputManager::GetStdOutContent(STRA* struStdOutput)
{ {
// //

View File

@ -19,7 +19,7 @@ public:
virtual bool GetStdOutContent(STRA* struStdOutput) override; virtual bool GetStdOutContent(STRA* struStdOutput) override;
virtual HRESULT Start() override; virtual HRESULT Start() override;
virtual void NotifyStartupComplete() override; virtual void NotifyStartupComplete() override {};
private: private:
HandleWrapper<InvalidHandleTraits> m_hLogFileHandle; HandleWrapper<InvalidHandleTraits> m_hLogFileHandle;

View File

@ -14,7 +14,9 @@ PipeOutputManager::PipeOutputManager() :
m_hErrReadPipe(INVALID_HANDLE_VALUE), m_hErrReadPipe(INVALID_HANDLE_VALUE),
m_hErrWritePipe(INVALID_HANDLE_VALUE), m_hErrWritePipe(INVALID_HANDLE_VALUE),
m_hErrThread(NULL), m_hErrThread(NULL),
m_fDisposed(FALSE) m_fDisposed(FALSE),
m_fdPreviousStdOut(-1),
m_fdPreviousStdErr(-1)
{ {
InitializeSRWLock(&m_srwLock); InitializeSRWLock(&m_srwLock);
} }
@ -54,7 +56,7 @@ PipeOutputManager::StopOutputRedirection()
if (m_fdPreviousStdOut >= 0) if (m_fdPreviousStdOut >= 0)
{ {
LOG_IF_DUPFAIL(_dup2(m_fdPreviousStdOut, _fileno(stdout))); LOG_LAST_ERROR_IF(SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdOut)));
} }
else else
{ {
@ -63,7 +65,7 @@ PipeOutputManager::StopOutputRedirection()
if (m_fdPreviousStdErr >= 0) if (m_fdPreviousStdErr >= 0)
{ {
LOG_IF_DUPFAIL(_dup2(m_fdPreviousStdErr, _fileno(stderr))); LOG_LAST_ERROR_IF(SetStdHandle(STD_ERROR_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdErr)));
} }
else else
{ {

View File

@ -3,6 +3,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "filewatcher.h" #include "filewatcher.h"
#include "debugutil.h"
FILE_WATCHER::FILE_WATCHER() : FILE_WATCHER::FILE_WATCHER() :
m_hCompletionPort(NULL), m_hCompletionPort(NULL),
@ -123,6 +124,7 @@ Win32 error
DWORD dwErrorStatus; DWORD dwErrorStatus;
ULONG_PTR completionKey; ULONG_PTR completionKey;
LOG_INFO("Starting file watcher thread");
pFileMonitor = (FILE_WATCHER*)pvArg; pFileMonitor = (FILE_WATCHER*)pvArg;
DBG_ASSERT(pFileMonitor != NULL); DBG_ASSERT(pFileMonitor != NULL);
@ -156,6 +158,8 @@ Win32 error
} }
pFileMonitor->m_fThreadExit = TRUE; pFileMonitor->m_fThreadExit = TRUE;
LOG_INFO("Stopping file watcher thread");
ExitThread(0); ExitThread(0);
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
while (true) while (true)
{ {
var result = await _bodyInputPipe.Reader.ReadAsync(); var result = await _bodyInputPipe.Reader.ReadAsync(cancellationToken);
var readableBuffer = result.Buffer; var readableBuffer = result.Buffer;
try try
{ {
@ -158,9 +159,13 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
} }
} }
} }
// We want to swallow IO exception and allow app to finish writing
catch (Exception ex) catch (Exception ex)
{ {
_bodyOutput.Reader.Complete(ex); if (!(ex is IOException))
{
_bodyOutput.Reader.Complete(ex);
}
} }
finally finally
{ {

View File

@ -217,7 +217,16 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
if (flushHeaders) if (flushHeaders)
{ {
await AsyncIO.FlushAsync(); try
{
await AsyncIO.FlushAsync();
}
// Client might be disconnected at this point
// don't leak the exception
catch (IOException)
{
// ignore
}
} }
_writeBodyTask = WriteBody(!flushHeaders); _writeBodyTask = WriteBody(!flushHeaders);

View File

@ -90,8 +90,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
await _writeBodyTask; await _writeBodyTask;
} }
// Cancell all remaining IO, thre might be reads pending if not entire request body was sent // Cancel all remaining IO, there might be reads pending if not entire request body was sent by client
// by client
AsyncIO.Dispose(); AsyncIO.Dispose();
if (_readBodyTask != null) if (_readBodyTask != null)

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.IO;
namespace Microsoft.AspNetCore.Server.IIS.Core namespace Microsoft.AspNetCore.Server.IIS.Core
{ {
@ -31,7 +32,39 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
IntPtr requestContext, IntPtr requestContext,
IntPtr shutdownContext) IntPtr shutdownContext)
{ {
NativeMethods.HttpRegisterCallbacks(_nativeApplication, requestHandler, shutdownHandler, onAsyncCompletion, requestContext, shutdownContext); NativeMethods.HttpRegisterCallbacks(
_nativeApplication,
requestHandler,
shutdownHandler,
onAsyncCompletion,
requestContext,
shutdownContext,
out var resetStandardStreams);
if (resetStandardStreams)
{
ResetStdOutHandles();
}
}
private static void ResetStdOutHandles()
{
// By using the PipeOutputRedirection, after calling RegisterCallbacks,
// stdout and stderr will be redirected to NULL. However, if something wrote
// to stdout before redirecting, (like a Console.WriteLine during startup),
// we need to call Console.Set* to pick up the modified consoles outputs.
Console.SetOut(CreateStreamWriter(Console.OpenStandardOutput()));
Console.SetError(CreateStreamWriter(Console.OpenStandardError()));
}
private static StreamWriter CreateStreamWriter(Stream stdStream)
{
return new StreamWriter(
stdStream,
encoding: Console.OutputEncoding,
bufferSize: 256,
leaveOpen: true)
{ AutoFlush = true };
} }
public void Dispose() public void Dispose()

View File

@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks.Sources; using System.Threading.Tasks.Sources;
@ -101,7 +103,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO
_result = bytes; _result = bytes;
if (hr != NativeMethods.HR_OK) if (hr != NativeMethods.HR_OK)
{ {
_exception = new IOException("IO exception occurred", hr); _exception = new IOException("Native IO operation failed", Marshal.GetExceptionForHR(hr));
} }
} }
else else

View File

@ -121,6 +121,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
_pipe.Writer.Complete();
_completed = true; _completed = true;
throw; throw;
} }

View File

@ -13,6 +13,7 @@ namespace Microsoft.AspNetCore.Server.IIS
internal const int HR_OK = 0; internal const int HR_OK = 0;
internal const int ERROR_NOT_FOUND = unchecked((int)0x80070490); internal const int ERROR_NOT_FOUND = unchecked((int)0x80070490);
internal const int ERROR_OPERATION_ABORTED = unchecked((int)0x800703E3); internal const int ERROR_OPERATION_ABORTED = unchecked((int)0x800703E3);
internal const int COR_E_IO = unchecked((int)0x80131620);
private const string KERNEL32 = "kernel32.dll"; private const string KERNEL32 = "kernel32.dll";
@ -53,7 +54,13 @@ namespace Microsoft.AspNetCore.Server.IIS
private 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)] [DllImport(AspNetCoreModuleDll)]
private static extern int register_callbacks(IntPtr pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_ASYNC_COMPLETION asyncCallback, IntPtr pvRequestContext, IntPtr pvShutdownContext); private static extern int register_callbacks(IntPtr pInProcessApplication,
PFN_REQUEST_HANDLER requestCallback,
PFN_SHUTDOWN_HANDLER shutdownCallback,
PFN_ASYNC_COMPLETION asyncCallback,
IntPtr pvRequestContext,
IntPtr pvShutdownContext,
out bool resetStandardStreams);
[DllImport(AspNetCoreModuleDll)] [DllImport(AspNetCoreModuleDll)]
private static extern unsafe 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);
@ -135,9 +142,15 @@ namespace Microsoft.AspNetCore.Server.IIS
Validate(http_set_completion_status(pInProcessHandler, rquestNotificationStatus)); Validate(http_set_completion_status(pInProcessHandler, rquestNotificationStatus));
} }
public static void HttpRegisterCallbacks(IntPtr pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_ASYNC_COMPLETION asyncCallback, IntPtr pvRequestContext, IntPtr pvShutdownContext) public static void HttpRegisterCallbacks(IntPtr pInProcessApplication,
PFN_REQUEST_HANDLER requestCallback,
PFN_SHUTDOWN_HANDLER shutdownCallback,
PFN_ASYNC_COMPLETION asyncCallback,
IntPtr pvRequestContext,
IntPtr pvShutdownContext,
out bool resetStandardStreams)
{ {
Validate(register_callbacks(pInProcessApplication, requestCallback, shutdownCallback, asyncCallback, pvRequestContext, pvShutdownContext)); Validate(register_callbacks(pInProcessApplication, requestCallback, shutdownCallback, asyncCallback, pvRequestContext, pvShutdownContext, out resetStandardStreams));
} }
public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected) public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected)

View File

@ -1,73 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Server.IntegrationTesting
{
// Copied from hosting
// TODO: make public while removing IISExpressDeployer
public static class DotNetCommands
{
private const string _dotnetFolderName = ".dotnet";
internal static string DotNetHome { get; } = GetDotNetHome();
// Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76
private static string GetDotNetHome()
{
var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME");
var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
var home = Environment.GetEnvironmentVariable("HOME");
var result = Path.Combine(Directory.GetCurrentDirectory(), _dotnetFolderName);
if (!string.IsNullOrEmpty(dotnetHome))
{
result = dotnetHome;
}
else if (!string.IsNullOrEmpty(userProfile))
{
result = Path.Combine(userProfile, _dotnetFolderName);
}
else if (!string.IsNullOrEmpty(home))
{
result = home;
}
return result;
}
internal static string GetDotNetInstallDir(RuntimeArchitecture arch)
{
var dotnetDir = DotNetHome;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
dotnetDir = Path.Combine(dotnetDir, arch.ToString());
}
return dotnetDir;
}
public static string GetDotNetExecutable(RuntimeArchitecture arch)
{
var dotnetDir = GetDotNetInstallDir(arch);
var dotnetFile = "dotnet";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
dotnetFile += ".exe";
}
return Path.Combine(dotnetDir, dotnetFile);
}
internal static bool IsRunningX86OnX64(RuntimeArchitecture arch)
{
return (RuntimeInformation.OSArchitecture == Architecture.X64 || RuntimeInformation.OSArchitecture == Architecture.Arm64)
&& arch == RuntimeArchitecture.x86;
}
}
}

View File

@ -231,7 +231,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem; pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem;
pool.ManagedRuntimeVersion = string.Empty; pool.ManagedRuntimeVersion = string.Empty;
pool.StartMode = StartMode.AlwaysRunning; pool.StartMode = StartMode.AlwaysRunning;
AddEnvironmentVariables(contentRoot, pool); AddEnvironmentVariables(contentRoot, pool);
_logger.LogInformation($"Configured AppPool {AppPoolName}"); _logger.LogInformation($"Configured AppPool {AppPoolName}");

View File

@ -1,58 +0,0 @@
// 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;
namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common
{
internal static class TestUriHelper
{
internal static Uri BuildTestUri(ServerType serverType, string hint)
{
// Assume status messages are enabled for Kestrel and disabled for all other servers.
var statusMessagesEnabled = (serverType == ServerType.Kestrel);
return BuildTestUri(serverType, Uri.UriSchemeHttp, hint, statusMessagesEnabled);
}
internal static Uri BuildTestUri(ServerType serverType, string scheme, string hint, bool statusMessagesEnabled)
{
if (string.IsNullOrEmpty(hint))
{
if (serverType == ServerType.Kestrel && statusMessagesEnabled)
{
// Most functional tests use this codepath and should directly bind to dynamic port "0" and scrape
// the assigned port from the status message, which should be 100% reliable since the port is bound
// once and never released. Binding to dynamic port "0" on "localhost" (both IPv4 and IPv6) is not
// supported, so the port is only bound on "127.0.0.1" (IPv4). If a test explicitly requires IPv6,
// it should provide a hint URL with "localhost" (IPv4 and IPv6) or "[::1]" (IPv6-only).
return new UriBuilder(scheme, "127.0.0.1", 0).Uri;
}
else
{
// If the server type is not Kestrel, or status messages are disabled, there is no status message
// from which to scrape the assigned port, so the less reliable GetNextPort() must be used. The
// port is bound on "localhost" (both IPv4 and IPv6), since this is supported when using a specific
// (non-zero) port.
return new UriBuilder(scheme, "localhost", TestPortHelper.GetNextPort()).Uri;
}
}
else
{
var uriHint = new Uri(hint);
if (uriHint.Port == 0)
{
// Only a few tests use this codepath, so it's fine to use the less reliable GetNextPort() for simplicity.
// The tests using this codepath will be reviewed to see if they can be changed to directly bind to dynamic
// port "0" on "127.0.0.1" and scrape the assigned port from the status message (the default codepath).
return new UriBuilder(uriHint) { Port = TestPortHelper.GetNextPort() }.Uri;
}
else
{
// If the hint contains a specific port, return it unchanged.
return uriHint;
}
}
}
}
}

View File

@ -0,0 +1,47 @@
// 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.Threading.Tasks;
using Microsoft.AspNetCore.Testing.xunit;
using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
[Collection(IISTestSiteCollection.Name)]
public class ClientDisconnectTests: FixtureLoggedTest
{
private readonly IISTestSiteFixture _fixture;
public ClientDisconnectTests(IISTestSiteFixture fixture): base(fixture)
{
_fixture = fixture;
}
[ConditionalFact]
public async Task ServerWorksAfterClientDisconnect()
{
using (var connection = _fixture.CreateTestConnection())
{
var message = "Hello";
await connection.Send(
"POST /ReadAndWriteSynchronously HTTP/1.1",
$"Content-Length: {100000}",
"Host: localhost",
"Connection: close",
"",
"");
await connection.Send(message);
await connection.Receive(
"HTTP/1.1 200 OK",
"");
}
var response = await _fixture.Client.GetAsync("HelloWorld");
var responseText = await response.Content.ReadAsStringAsync();
Assert.Equal("Hello World", responseText);
}
}
}

View File

@ -19,55 +19,58 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
[ConditionalTheory] [ConditionalTheory]
[InlineData("CheckErrLogFile")] [InlineData("CheckErrLogFile")]
[InlineData("CheckLogFile")] [InlineData("CheckLogFile")]
public async Task CheckStdoutLogging(string path) public async Task CheckStdoutLoggingToFile(string path)
{ {
var deploymentParameters = Helpers.GetBaseDeploymentParameters(); var deploymentParameters = Helpers.GetBaseDeploymentParameters();
deploymentParameters.PublishApplicationBeforeDeployment = true; deploymentParameters.PublishApplicationBeforeDeployment = true;
deploymentParameters.PreservePublishedApplicationForDebugging = true; // workaround for keeping
var deploymentResult = await DeployAsync(deploymentParameters); var deploymentResult = await DeployAsync(deploymentParameters);
var pathToLogs = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
try try
{ {
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogEnabled", "true"); Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogEnabled", "true");
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogFile", @".\logs\stdout"); Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogFile", Path.Combine(pathToLogs, "std"));
var response = await deploymentResult.RetryingHttpClient.GetAsync(path); await Helpers.AssertStarts(deploymentResult, path);
var responseText = await response.Content.ReadAsStringAsync();
Assert.Equal("Hello World", responseText);
StopServer(); StopServer();
var folderPath = Path.Combine(deploymentResult.DeploymentResult.ContentRoot, @"logs"); var fileInDirectory = Directory.GetFiles(pathToLogs).Single();
var fileInDirectory = Directory.GetFiles(folderPath).Single(); var contents = File.ReadAllText(fileInDirectory);
Assert.NotNull(fileInDirectory);
string contents = null;
// RetryOperation doesn't support async lambdas, call synchronous ReadAllText.
RetryHelper.RetryOperation(
() => contents = File.ReadAllText(fileInDirectory),
e => Logger.LogError($"Failed to read file: {e.Message}"),
retryCount: 10,
retryDelayMilliseconds: 100);
Assert.NotNull(contents); Assert.NotNull(contents);
Assert.Contains("TEST MESSAGE", contents); Assert.Contains("TEST MESSAGE", contents);
Assert.DoesNotContain(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE"));
// TODO we should check that debug logs are restored during graceful shutdown.
// The IIS Express deployer doesn't support graceful shutdown.
//Assert.Contains(TestSink.Writes, context => context.Message.Contains("Restoring original stdout: "));
} }
finally finally
{ {
RetryHelper.RetryOperation( RetryHelper.RetryOperation(
() => Directory.Delete(deploymentParameters.PublishedApplicationRootPath, true), () => Directory.Delete(pathToLogs, true),
e => Logger.LogWarning($"Failed to delete directory : {e.Message}"), e => Logger.LogWarning($"Failed to delete directory : {e.Message}"),
retryCount: 3, retryCount: 3,
retryDelayMilliseconds: 100); retryDelayMilliseconds: 100);
} }
} }
[ConditionalFact]
public async Task InvalidFilePathForLogs_ServerStillRuns()
{
var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true);
var deploymentResult = await DeployAsync(deploymentParameters);
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogEnabled", "true");
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogFile", Path.Combine("Q:", "std"));
await Helpers.AssertStarts(deploymentResult, "HelloWorld");
}
[ConditionalFact] [ConditionalFact]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)] [RequiresIIS(IISCapability.PoolEnvironmentVariables)]
public async Task StartupMessagesAreLoggedIntoDebugLogFile() public async Task StartupMessagesAreLoggedIntoDebugLogFile()
@ -96,6 +99,48 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
} }
} }
[ConditionalTheory]
[InlineData("CheckErrLogFile")]
[InlineData("CheckLogFile")]
public async Task CheckStdoutLoggingToPipe_DoesNotCrashProcess(string path)
{
var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true);
var deploymentResult = await DeployAsync(deploymentParameters);
await Helpers.AssertStarts(deploymentResult, path);
StopServer();
if (deploymentParameters.ServerType == ServerType.IISExpress)
{
Assert.Contains(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE"));
}
}
[ConditionalTheory]
[InlineData("CheckErrLogFile")]
[InlineData("CheckLogFile")]
public async Task CheckStdoutLoggingToPipeWithFirstWrite(string path)
{
var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true);
var deploymentResult = await DeployAsync(deploymentParameters);
var firstWriteString = path + path;
Helpers.ModifyEnvironmentVariableCollectionInWebConfig(deploymentResult, "ASPNETCORE_INPROCESS_INITIAL_WRITE", firstWriteString);
await Helpers.AssertStarts(deploymentResult, path);
StopServer();
if (deploymentParameters.ServerType == ServerType.IISExpress)
{
// We can't read stdout logs from IIS as they aren't redirected.
Assert.Contains(TestSink.Writes, context => context.Message.Contains(firstWriteString));
Assert.Contains(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE"));
}
}
[ConditionalFact] [ConditionalFact]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)] [RequiresIIS(IISCapability.PoolEnvironmentVariables)]
public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig() public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig()

View File

@ -14,10 +14,8 @@ using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{ {
public class Helpers public static class Helpers
{ {
public static TimeSpan DefaultTimeout = TimeSpan.FromSeconds(3);
public static string GetTestWebSitePath(string name) public static string GetTestWebSitePath(string name)
{ {
return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name); return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name);
@ -41,6 +39,22 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
config.Save(webConfigFile); config.Save(webConfigFile);
} }
public static void ModifyEnvironmentVariableCollectionInWebConfig(IISDeploymentResult deploymentResult, string key, string value)
{
var webConfigFile = GetWebConfigFile(deploymentResult);
var config = XDocument.Load(webConfigFile);
var envVarElement = new XElement("environmentVariable");
envVarElement.SetAttributeValue("name", key);
envVarElement.SetAttributeValue("value", value);
config.Descendants("aspNetCore").Single()
.Descendants("environmentVariables").Single()
.Add(envVarElement);
config.Save(webConfigFile);
}
public static void ModifyHandlerSectionInWebConfig(IISDeploymentResult deploymentResult, string handlerVersionValue) public static void ModifyHandlerSectionInWebConfig(IISDeploymentResult deploymentResult, string handlerVersionValue)
{ {
var webConfigFile = GetWebConfigFile(deploymentResult); var webConfigFile = GetWebConfigFile(deploymentResult);

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,21 @@
// 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.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Testing;
namespace Microsoft.AspNetCore.Server.IntegrationTesting
{
public static class TimeoutExtensions
{
public static TimeSpan DefaultTimeout = TimeSpan.FromSeconds(300);
public static Task TimeoutAfterDefault(this Task task, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = -1)
{
return task.TimeoutAfter(DefaultTimeout, filePath, lineNumber);
}
}
}

View File

@ -13,6 +13,7 @@
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
<ProjectReference Include="..\WebSites\**\*.csproj"> <ProjectReference Include="..\WebSites\**\*.csproj">
<ReferenceOutputAssembly>False</ReferenceOutputAssembly> <ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference> </ProjectReference>

View File

@ -92,7 +92,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
} }
} }
public RequiresIISAttribute() { } public RequiresIISAttribute()
: this (IISCapability.None) { }
public RequiresIISAttribute(IISCapability capabilities) public RequiresIISAttribute(IISCapability capabilities)
{ {

View File

@ -177,8 +177,6 @@
--> -->
<globalModules> <globalModules>
<add name="UriCacheModule" image="%windir%\System32\inetsrv\cachuri.dll" />
<add name="ProtocolSupportModule" image="%windir%\System32\inetsrv\protsup.dll" />
<add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" /> <add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
<add name="AspNetCoreModuleV2" image="aspnetcorev2.dll" /> <add name="AspNetCoreModuleV2" image="aspnetcorev2.dll" />
</globalModules> </globalModules>
@ -193,8 +191,7 @@
<add name="AspNetCoreModuleV2" lockItem="true" /> <add name="AspNetCoreModuleV2" lockItem="true" />
</modules> </modules>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" hostingModel="inprocess" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" hostingModel="inprocess" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer> </system.webServer>

View File

@ -0,0 +1,177 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging.Testing;
using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
[SkipIfHostableWebCoreNotAvailable]
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
public class ClientDisconnectTests : LoggedTest
{
[ConditionalFact]
public async Task WritesSucceedAfterClientDisconnect()
{
var requestStartedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var clientDisconnectedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var requestCompletedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var data = new byte[1024];
using (var testServer = await TestServer.Create(
async ctx =>
{
requestStartedCompletionSource.SetResult(true);
await clientDisconnectedCompletionSource.Task;
for (var i = 0; i < 1000; i++)
{
await ctx.Response.Body.WriteAsync(data);
}
requestCompletedCompletionSource.SetResult(true);
}, LoggerFactory))
{
using (var connection = testServer.CreateConnection())
{
await SendContentLength1Post(connection);
await requestStartedCompletionSource.Task.TimeoutAfterDefault();
}
clientDisconnectedCompletionSource.SetResult(true);
await requestCompletedCompletionSource.Task.TimeoutAfterDefault();
}
}
[ConditionalFact]
public async Task ReadThrowsAfterClientDisconnect()
{
var requestStartedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var requestCompletedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
Exception exception = null;
var data = new byte[1024];
using (var testServer = await TestServer.Create(async ctx =>
{
requestStartedCompletionSource.SetResult(true);
try
{
await ctx.Request.Body.ReadAsync(data);
}
catch (Exception e)
{
exception = e;
}
requestCompletedCompletionSource.SetResult(true);
}, LoggerFactory))
{
using (var connection = testServer.CreateConnection())
{
await SendContentLength1Post(connection);
await requestStartedCompletionSource.Task.TimeoutAfterDefault();
}
await requestCompletedCompletionSource.Task.TimeoutAfterDefault();
}
Assert.IsType<IOException>(exception);
Assert.Equal("Native IO operation failed", exception.Message);
}
[ConditionalFact]
public async Task WriterThrowsCancelledException()
{
var requestStartedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var requestCompletedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
Exception exception = null;
var cancellationTokenSource = new CancellationTokenSource();
var data = new byte[1024];
using (var testServer = await TestServer.Create(async ctx =>
{
requestStartedCompletionSource.SetResult(true);
try
{
while (true)
{
await ctx.Response.Body.WriteAsync(data, cancellationTokenSource.Token);
}
}
catch (Exception e)
{
exception = e;
}
requestCompletedCompletionSource.SetResult(true);
}, LoggerFactory))
{
using (var connection = testServer.CreateConnection())
{
await SendContentLength1Post(connection);
await requestStartedCompletionSource.Task.TimeoutAfterDefault();
cancellationTokenSource.Cancel();
await requestCompletedCompletionSource.Task.TimeoutAfterDefault();
}
Assert.IsType<OperationCanceledException>(exception);
}
}
[ConditionalFact]
public async Task ReaderThrowsCancelledException()
{
var requestStartedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var requestCompletedCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
Exception exception = null;
var cancellationTokenSource = new CancellationTokenSource();
var data = new byte[1024];
using (var testServer = await TestServer.Create(async ctx =>
{
requestStartedCompletionSource.SetResult(true);
try
{
await ctx.Request.Body.ReadAsync(data, cancellationTokenSource.Token);
}
catch (Exception e)
{
exception = e;
}
requestCompletedCompletionSource.SetResult(true);
}, LoggerFactory))
{
using (var connection = testServer.CreateConnection())
{
await SendContentLength1Post(connection);
await requestStartedCompletionSource.Task.TimeoutAfterDefault();
cancellationTokenSource.Cancel();
await requestCompletedCompletionSource.Task.TimeoutAfterDefault();
}
Assert.IsType<OperationCanceledException>(exception);
}
}
private static async Task SendContentLength1Post(TestConnection connection)
{
await connection.Send(
"POST / HTTP/1.1",
"Content-Length: 1",
"Host: localhost",
"Connection: close",
"",
"");
}
}
}

View File

@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
<None Include="$(MSBuildThisFileDirectory)..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\bin\$(Configuration)\x64\aspnetcorev2_inprocess.dll" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="%(FileName)%(Extension)" />
<None Include="$(MSBuildThisFileDirectory)..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\bin\$(Configuration)\x64\aspnetcorev2_inprocess.pdb" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="%(FileName)%(Extension)" />
<None Include="$(MSBuildThisFileDirectory)..\..\src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\x64\aspnetcorev2.dll" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="%(FileName)%(Extension)" />
<None Include="$(MSBuildThisFileDirectory)..\..\src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\x64\aspnetcorev2.pdb" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="%(FileName)%(Extension)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
</ItemGroup>
<ItemGroup>
<None Include="AppHostConfig\HostableWebCore.config" CopyToOutputDirectory="PreserveNewest" Link="%(FileName)%(Extension)" />
</ItemGroup>
</Project>

View File

@ -2,31 +2,26 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Logging.Testing;
using Xunit; using Xunit;
using Xunit.Abstractions;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{ {
[SkipIfHostableWebCoreNotAvailible] [SkipIfHostableWebCoreNotAvailable]
public class TestServerTest: LoggedTest [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
public class TestServerTest : LoggedTest
{ {
public TestServerTest(ITestOutputHelper output = null) : base(output)
{
}
[ConditionalFact] [ConditionalFact]
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
public async Task SingleProcessTestServer_HelloWorld() public async Task SingleProcessTestServer_HelloWorld()
{ {
var helloWorld = "Hello World"; var helloWorld = "Hello World";
var expectedPath = "/Path"; var expectedPath = "/Path";
string path = null; string path = null;
using (var testServer = await TestServer.Create(ctx => { using (var testServer = await TestServer.Create(ctx =>
{
path = ctx.Request.Path.ToString(); path = ctx.Request.Path.ToString();
return ctx.Response.WriteAsync(helloWorld); return ctx.Response.WriteAsync(helloWorld);
}, LoggerFactory)) }, LoggerFactory))

View File

@ -8,10 +8,10 @@ using Microsoft.AspNetCore.Testing.xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{ {
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
public sealed class SkipIfHostableWebCoreNotAvailibleAttribute : Attribute, ITestCondition public sealed class SkipIfHostableWebCoreNotAvailableAttribute : Attribute, ITestCondition
{ {
public bool IsMet { get; } = File.Exists(TestServer.HostableWebCoreLocation); public bool IsMet { get; } = File.Exists(TestServer.HostableWebCoreLocation);
public string SkipReason { get; } = $"Hostable Web Core not availible, {TestServer.HostableWebCoreLocation} not found."; public string SkipReason { get; } = $"Hostable Web Core not available, {TestServer.HostableWebCoreLocation} not found.";
} }
} }

View File

@ -6,8 +6,11 @@ using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Loader;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.XPath;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -24,6 +27,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
private const string HWebCoreDll = "hwebcore.dll"; private const string HWebCoreDll = "hwebcore.dll";
internal static string HostableWebCoreLocation => Environment.ExpandEnvironmentVariables($@"%windir%\system32\inetsrv\{HWebCoreDll}"); internal static string HostableWebCoreLocation => Environment.ExpandEnvironmentVariables($@"%windir%\system32\inetsrv\{HWebCoreDll}");
internal static string BasePath => Path.GetDirectoryName(new Uri(typeof(TestServer).Assembly.CodeBase).AbsolutePath);
internal static string InProcessHandlerLocation => Path.Combine(BasePath, InProcessHandlerDll);
internal static string AspNetCoreModuleLocation => Path.Combine(BasePath, AspNetCoreModuleDll);
private static readonly SemaphoreSlim WebCoreLock = new SemaphoreSlim(1, 1); private static readonly SemaphoreSlim WebCoreLock = new SemaphoreSlim(1, 1);
@ -35,14 +42,18 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
private readonly Action<IApplicationBuilder> _appBuilder; private readonly Action<IApplicationBuilder> _appBuilder;
private readonly ILoggerFactory _loggerFactory; private readonly ILoggerFactory _loggerFactory;
private readonly hostfxr_main_fn _hostfxrMainFn;
public HttpClient HttpClient { get; } public HttpClient HttpClient { get; }
public TestConnection CreateConnection() => new TestConnection(BasePort); public TestConnection CreateConnection() => new TestConnection(BasePort);
private IWebHost _host; private IWebHost _host;
private string _appHostConfigPath;
private TestServer(Action<IApplicationBuilder> appBuilder, ILoggerFactory loggerFactory) private TestServer(Action<IApplicationBuilder> appBuilder, ILoggerFactory loggerFactory)
{ {
_hostfxrMainFn = Main;
_appBuilder = appBuilder; _appBuilder = appBuilder;
_loggerFactory = loggerFactory; _loggerFactory = loggerFactory;
@ -57,7 +68,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
await WebCoreLock.WaitAsync(); await WebCoreLock.WaitAsync();
var server = new TestServer(appBuilder, loggerFactory); var server = new TestServer(appBuilder, loggerFactory);
server.Start(); server.Start();
await server.HttpClient.GetAsync("/start"); (await server.HttpClient.GetAsync("/start")).EnsureSuccessStatusCode();
await server._startedTaskCompletionSource.Task; await server._startedTaskCompletionSource.Task;
return server; return server;
} }
@ -70,11 +81,16 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
private void Start() private void Start()
{ {
LoadLibrary(HostableWebCoreLocation); LoadLibrary(HostableWebCoreLocation);
LoadLibrary(InProcessHandlerDll); _appHostConfigPath = Path.GetTempFileName();
LoadLibrary(AspNetCoreModuleDll);
set_main_handler(Main); var webHostConfig = XDocument.Load(Path.GetFullPath("HostableWebCore.config"));
var startResult = WebCoreActivate(Path.GetFullPath("HostableWebCore.config"), null, "Instance"); webHostConfig.XPathSelectElement("/configuration/system.webServer/globalModules/add[@name='AspNetCoreModuleV2']")
.SetAttributeValue("image", AspNetCoreModuleLocation);
webHostConfig.Save(_appHostConfigPath);
set_main_handler(_hostfxrMainFn);
var startResult = WebCoreActivate(_appHostConfigPath, null, "Instance");
if (startResult != 0) if (startResult != 0)
{ {
throw new InvalidOperationException($"Error while running WebCoreActivate: {startResult}"); throw new InvalidOperationException($"Error while running WebCoreActivate: {startResult}");
@ -87,8 +103,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
.UseIIS() .UseIIS()
.ConfigureServices(services => { .ConfigureServices(services => {
services.AddSingleton<IStartup>(this); services.AddSingleton<IStartup>(this);
services.AddSingleton<ILoggerFactory>(_loggerFactory); services.AddSingleton(_loggerFactory);
}) })
.UseSetting(WebHostDefaults.ApplicationKey, typeof(TestServer).GetTypeInfo().Assembly.FullName) .UseSetting(WebHostDefaults.ApplicationKey, typeof(TestServer).GetTypeInfo().Assembly.FullName)
.Build(); .Build();

View File

@ -12,6 +12,7 @@
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
<ProjectReference Include="..\WebSites\**\*.csproj"> <ProjectReference Include="..\WebSites\**\*.csproj">
<ReferenceOutputAssembly>False</ReferenceOutputAssembly> <ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference> </ProjectReference>

View File

@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.Inprocess
var hostShutdownToken = deploymentResult.DeploymentResult.HostShutdownToken; var hostShutdownToken = deploymentResult.DeploymentResult.HostShutdownToken;
Assert.True(hostShutdownToken.WaitHandle.WaitOne(Helpers.DefaultTimeout)); Assert.True(hostShutdownToken.WaitHandle.WaitOne(TimeoutExtensions.DefaultTimeout));
Assert.True(hostShutdownToken.IsCancellationRequested); Assert.True(hostShutdownToken.IsCancellationRequested);
} }

View File

@ -3,6 +3,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
var result = await DeployAsync(parameters); var result = await DeployAsync(parameters);
var response = await result.RetryingHttpClient.GetAsync("/Shutdown"); var response = await result.RetryingHttpClient.GetAsync("/Shutdown");
Assert.True(result.DeploymentResult.HostShutdownToken.WaitHandle.WaitOne(Helpers.DefaultTimeout)); Assert.True(result.DeploymentResult.HostShutdownToken.WaitHandle.WaitOne(TimeoutExtensions.DefaultTimeout));
} }
} }
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -10,6 +11,13 @@ namespace IISTestSite
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
var envVariable = Environment.GetEnvironmentVariable("ASPNETCORE_INPROCESS_INITIAL_WRITE");
if (!string.IsNullOrEmpty(envVariable))
{
Console.WriteLine(envVariable);
Console.Error.WriteLine(envVariable);
}
var host = new WebHostBuilder() var host = new WebHostBuilder()
.ConfigureLogging((_, factory) => .ConfigureLogging((_, factory) =>
{ {

View File

@ -753,6 +753,5 @@ namespace IISTestSite
} }
await context.Response.WriteAsync("Response End"); await context.Response.WriteAsync("Response End");
} }
} }
} }