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
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
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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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|x86.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -411,6 +439,8 @@ Global
{1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
{D182103F-8405-4647-B158-C36F598657EF} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{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
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}

View File

@ -120,6 +120,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.FunctionalTests", "test
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}"
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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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|x86.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -441,6 +469,8 @@ Global
{1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
{1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{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
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}

View File

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

View File

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

View File

@ -12,12 +12,21 @@
#include "SRWExclusiveLock.h"
#include "GlobalVersionUtility.h"
#include "exceptions.h"
#include "HandleWrapper.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_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()
{
if (m_pApplication != NULL)
@ -39,23 +48,14 @@ APPLICATION_INFO::~APPLICATION_INFO()
HRESULT
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);
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;
return S_OK;
}
@ -125,7 +125,7 @@ APPLICATION_INFO::EnsureApplicationCreated(
};
LOG_INFO("Creating handler application");
FINISHED_IF_FAILED(m_pfnAspNetCoreCreateApplication(
m_pServer,
&m_pServer,
pHttpContext->GetApplication(),
parameters.data(),
static_cast<DWORD>(parameters.size()),
@ -157,19 +157,18 @@ APPLICATION_INFO::FindRequestHandlerAssembly(STRU& location)
PCWSTR pstrHandlerDllName;
STACK_STRU(struFileName, 256);
if (g_fAspnetcoreRHLoadedError)
if (s_fAspnetcoreRHLoadedError)
{
FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE);
}
else if (!g_fAspnetcoreRHAssemblyLoaded)
else if (!s_fAspnetcoreRHAssemblyLoaded)
{
SRWExclusiveLock lock(g_srwLock);
if (g_fAspnetcoreRHLoadedError)
SRWExclusiveLock lock(s_requestHandlerLoadLock);
if (s_fAspnetcoreRHLoadedError)
{
FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE);
}
if (g_fAspnetcoreRHAssemblyLoaded)
if (s_fAspnetcoreRHAssemblyLoaded)
{
FINISHED(S_OK);
}
@ -184,9 +183,9 @@ APPLICATION_INFO::FindRequestHandlerAssembly(STRU& location)
}
// 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)
{
@ -229,22 +228,22 @@ APPLICATION_INFO::FindRequestHandlerAssembly(STRU& location)
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()));
}
}
g_pfnAspNetCoreCreateApplication = (PFN_ASPNETCORE_CREATE_APPLICATION)
GetProcAddress(g_hAspnetCoreRH, "CreateApplication");
if (g_pfnAspNetCoreCreateApplication == NULL)
s_pfnAspNetCoreCreateApplication = (PFN_ASPNETCORE_CREATE_APPLICATION)
GetProcAddress(s_hAspnetCoreRH, "CreateApplication");
if (s_pfnAspNetCoreCreateApplication == NULL)
{
FINISHED(HRESULT_FROM_WIN32(GetLastError()));
}
g_fAspnetcoreRHAssemblyLoaded = TRUE;
s_fAspnetcoreRHAssemblyLoaded = TRUE;
}
Finished:
@ -252,11 +251,11 @@ Finished:
// Question: we remember the load failure so that we will not try again.
// 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;
}
@ -457,7 +456,7 @@ APPLICATION_INFO::RecycleApplication()
if (m_pConfiguration->QueryHostingModel() == HOSTING_IN_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)
{
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

View File

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

View File

@ -8,6 +8,9 @@
#include "resources.h"
#include "SRWExclusiveLock.h"
#include "exceptions.h"
#include "EventLog.h"
extern BOOL g_fInShutdown;
// The application manager is a singleton across ANCM.
APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
@ -18,7 +21,6 @@ APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
//
HRESULT
APPLICATION_MANAGER::GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ IHttpContext* pHttpContext,
_Out_ APPLICATION_INFO ** ppApplicationInfo
)
@ -32,56 +34,37 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo(
STACK_STRU ( strEventMsg, 256 );
DBG_ASSERT(pServer);
DBG_ASSERT(pHttpContext);
DBG_ASSERT(ppApplicationInfo);
*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
// key in the applicationInfoHash.
pszApplicationId = pHttpContext->GetApplication()->GetApplicationId();
pszApplicationId = pApplication.GetApplicationId();
// When accessing the m_pApplicationInfoHash, we need to acquire the application manager
// lock to avoid races on setting state.
SRWSharedLock lock(m_srwLock);
if (!m_fDebugInitialize)
{
SRWSharedLock lock(m_srwLock);
if (g_fInShutdown)
{
FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
}
m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
DebugInitializeFromConfig(m_pHttpServer, pApplication);
m_fDebugInitialize = TRUE;
}
if (g_fInShutdown)
{
FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
}
m_pApplicationInfoHash->FindKey(pszApplicationId, ppApplicationInfo);
if (*ppApplicationInfo == NULL)
{
pApplicationInfo = new APPLICATION_INFO();
pApplicationInfo = new APPLICATION_INFO(m_pHttpServer);
FINISHED_IF_FAILED(pApplicationInfo->Initialize(pServer, pHttpContext->GetApplication()));
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);
}
FINISHED_IF_FAILED(pApplicationInfo->Initialize(pApplication));
hostingModel = pApplicationInfo->QueryConfig()->QueryHostingModel();
@ -309,7 +292,7 @@ Finished:
if (!g_fRecycleProcessCalled)
{
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
APPLICATION_MANAGER*
GetInstance(
VOID
)
GetInstance()
{
if ( sm_pApplicationManager == NULL )
{
sm_pApplicationManager = new APPLICATION_MANAGER();
}
assert(sm_pApplicationManager);
return sm_pApplicationManager;
}
@ -68,7 +62,6 @@ public:
HRESULT
GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ IHttpContext* pHttpContext,
_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()
{
if(m_pApplicationInfoHash == NULL)
@ -107,12 +110,11 @@ public:
}
private:
//
// we currently limit the size of m_pstrErrorInfo to 5000, be careful if you want to change its payload
//
APPLICATION_MANAGER() : m_pApplicationInfoHash(NULL),
APPLICATION_MANAGER(IHttpServer& pHttpServer) :
m_pApplicationInfoHash(NULL),
m_hostingModel(HOSTING_UNKNOWN),
m_fDebugInitialize(FALSE)
m_fDebugInitialize(FALSE),
m_pHttpServer(pHttpServer)
{
InitializeSRWLock(&m_srwLock);
}
@ -120,6 +122,7 @@ private:
APPLICATION_INFO_HASH *m_pApplicationInfoHash;
static APPLICATION_MANAGER *sm_pApplicationManager;
SRWLOCK m_srwLock;
APP_HOSTING_MODEL m_hostingModel;
APP_HOSTING_MODEL m_hostingModel;
BOOL m_fDebugInitialize;
IHttpServer &m_pHttpServer;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,8 +9,8 @@
//
#define WIN32_LEAN_AND_MEAN
#define NTDDI_VERSION 0x06010000
#define WINVER 0x0601
#define NTDDI_VERSION NTDDI_WIN7
#define WINVER _WIN32_WINNT_WIN7
#define _WIN32_WINNT 0x0601
#include <Windows.h>
@ -20,16 +20,4 @@
#include "stringu.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)

View File

@ -6,4 +6,6 @@
#include "Utility.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__)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,9 @@ PipeOutputManager::PipeOutputManager() :
m_hErrReadPipe(INVALID_HANDLE_VALUE),
m_hErrWritePipe(INVALID_HANDLE_VALUE),
m_hErrThread(NULL),
m_fDisposed(FALSE)
m_fDisposed(FALSE),
m_fdPreviousStdOut(-1),
m_fdPreviousStdErr(-1)
{
InitializeSRWLock(&m_srwLock);
}
@ -54,7 +56,7 @@ PipeOutputManager::StopOutputRedirection()
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
{
@ -63,7 +65,7 @@ PipeOutputManager::StopOutputRedirection()
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
{

View File

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

View File

@ -3,6 +3,7 @@
using System;
using System.Buffers;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
while (true)
{
var result = await _bodyInputPipe.Reader.ReadAsync();
var result = await _bodyInputPipe.Reader.ReadAsync(cancellationToken);
var readableBuffer = result.Buffer;
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)
{
_bodyOutput.Reader.Complete(ex);
if (!(ex is IOException))
{
_bodyOutput.Reader.Complete(ex);
}
}
finally
{

View File

@ -217,7 +217,16 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
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);

View File

@ -90,8 +90,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
await _writeBodyTask;
}
// Cancell all remaining IO, thre might be reads pending if not entire request body was sent
// by client
// Cancel all remaining IO, there might be reads pending if not entire request body was sent by client
AsyncIO.Dispose();
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.
using System;
using System.IO;
namespace Microsoft.AspNetCore.Server.IIS.Core
{
@ -31,7 +32,39 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
IntPtr requestContext,
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()

View File

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

View File

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

View File

@ -13,6 +13,7 @@ namespace Microsoft.AspNetCore.Server.IIS
internal const int HR_OK = 0;
internal const int ERROR_NOT_FOUND = unchecked((int)0x80070490);
internal const int ERROR_OPERATION_ABORTED = unchecked((int)0x800703E3);
internal const int COR_E_IO = unchecked((int)0x80131620);
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);
[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)]
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));
}
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)

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.ManagedRuntimeVersion = string.Empty;
pool.StartMode = StartMode.AlwaysRunning;
AddEnvironmentVariables(contentRoot, pool);
_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]
[InlineData("CheckErrLogFile")]
[InlineData("CheckLogFile")]
public async Task CheckStdoutLogging(string path)
public async Task CheckStdoutLoggingToFile(string path)
{
var deploymentParameters = Helpers.GetBaseDeploymentParameters();
deploymentParameters.PublishApplicationBeforeDeployment = true;
deploymentParameters.PreservePublishedApplicationForDebugging = true; // workaround for keeping
var deploymentResult = await DeployAsync(deploymentParameters);
var pathToLogs = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
try
{
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);
var responseText = await response.Content.ReadAsStringAsync();
Assert.Equal("Hello World", responseText);
await Helpers.AssertStarts(deploymentResult, path);
StopServer();
var folderPath = Path.Combine(deploymentResult.DeploymentResult.ContentRoot, @"logs");
var fileInDirectory = Directory.GetFiles(pathToLogs).Single();
var fileInDirectory = Directory.GetFiles(folderPath).Single();
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);
var contents = File.ReadAllText(fileInDirectory);
Assert.NotNull(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
{
RetryHelper.RetryOperation(
() => Directory.Delete(deploymentParameters.PublishedApplicationRootPath, true),
() => Directory.Delete(pathToLogs, true),
e => Logger.LogWarning($"Failed to delete directory : {e.Message}"),
retryCount: 3,
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]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
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]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig()

View File

@ -14,10 +14,8 @@ using Xunit;
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)
{
return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name);
@ -41,6 +39,22 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
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)
{
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.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.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">
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>

View File

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

View File

@ -177,8 +177,6 @@
-->
<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="AspNetCoreModuleV2" image="aspnetcorev2.dll" />
</globalModules>
@ -193,8 +191,7 @@
<add name="AspNetCoreModuleV2" lockItem="true" />
</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>

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.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging.Testing;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
[SkipIfHostableWebCoreNotAvailible]
public class TestServerTest: LoggedTest
[SkipIfHostableWebCoreNotAvailable]
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
public class TestServerTest : LoggedTest
{
public TestServerTest(ITestOutputHelper output = null) : base(output)
{
}
[ConditionalFact]
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
public async Task SingleProcessTestServer_HelloWorld()
{
var helloWorld = "Hello World";
var expectedPath = "/Path";
string path = null;
using (var testServer = await TestServer.Create(ctx => {
using (var testServer = await TestServer.Create(ctx =>
{
path = ctx.Request.Path.ToString();
return ctx.Response.WriteAsync(helloWorld);
}, LoggerFactory))

View File

@ -8,10 +8,10 @@ using Microsoft.AspNetCore.Testing.xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
[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 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.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Loader;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.XPath;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@ -24,6 +27,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
private const string HWebCoreDll = "hwebcore.dll";
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);
@ -35,14 +42,18 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
private readonly Action<IApplicationBuilder> _appBuilder;
private readonly ILoggerFactory _loggerFactory;
private readonly hostfxr_main_fn _hostfxrMainFn;
public HttpClient HttpClient { get; }
public TestConnection CreateConnection() => new TestConnection(BasePort);
private IWebHost _host;
private string _appHostConfigPath;
private TestServer(Action<IApplicationBuilder> appBuilder, ILoggerFactory loggerFactory)
{
_hostfxrMainFn = Main;
_appBuilder = appBuilder;
_loggerFactory = loggerFactory;
@ -57,7 +68,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
await WebCoreLock.WaitAsync();
var server = new TestServer(appBuilder, loggerFactory);
server.Start();
await server.HttpClient.GetAsync("/start");
(await server.HttpClient.GetAsync("/start")).EnsureSuccessStatusCode();
await server._startedTaskCompletionSource.Task;
return server;
}
@ -70,11 +81,16 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
private void Start()
{
LoadLibrary(HostableWebCoreLocation);
LoadLibrary(InProcessHandlerDll);
LoadLibrary(AspNetCoreModuleDll);
_appHostConfigPath = Path.GetTempFileName();
set_main_handler(Main);
var startResult = WebCoreActivate(Path.GetFullPath("HostableWebCore.config"), null, "Instance");
var webHostConfig = XDocument.Load(Path.GetFullPath("HostableWebCore.config"));
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)
{
throw new InvalidOperationException($"Error while running WebCoreActivate: {startResult}");
@ -87,8 +103,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
.UseIIS()
.ConfigureServices(services => {
services.AddSingleton<IStartup>(this);
services.AddSingleton<ILoggerFactory>(_loggerFactory);
})
services.AddSingleton(_loggerFactory);
})
.UseSetting(WebHostDefaults.ApplicationKey, typeof(TestServer).GetTypeInfo().Assembly.FullName)
.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.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.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">
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>

View File

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

View File

@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Testing.xunit;
using Xunit;
using Xunit.Abstractions;
@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
var result = await DeployAsync(parameters);
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.
// 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.Extensions.Logging;
@ -10,6 +11,13 @@ namespace IISTestSite
{
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()
.ConfigureLogging((_, factory) =>
{

View File

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