Write Premain errors to the response and write different status codes (#10282)

This commit is contained in:
Justin Kotalik 2019-05-25 15:19:06 -07:00 committed by GitHub
parent 833ddbe899
commit 2d1c14d5a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 415 additions and 165 deletions

View File

@ -233,8 +233,6 @@
<ClInclude Include="AppOfflineApplication.h" />
<ClInclude Include="AppOfflineHandler.h" />
<ClInclude Include="DisconnectHandler.h" />
<ClInclude Include="PollingAppOfflineApplication.h" />
<ClInclude Include="ServerErrorApplication.h" />
<ClInclude Include="ShimOptions.h" />
<ClInclude Include="globalmodule.h" />
<ClInclude Include="resource.h" />
@ -249,7 +247,6 @@
<ClCompile Include="AppOfflineApplication.cpp" />
<ClCompile Include="AppOfflineHandler.cpp" />
<ClCompile Include="DisconnectHandler.cpp" />
<ClCompile Include="PollingAppOfflineApplication.cpp" />
<ClCompile Include="ShimOptions.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="globalmodule.cpp" />

View File

@ -28,7 +28,10 @@ HandlerResolver::HandlerResolver(HMODULE hModule, const IHttpServer &pServer)
}
HRESULT
HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory)
HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication,
const ShimOptions& pConfiguration,
std::unique_ptr<ApplicationFactory>& pApplicationFactory,
ErrorContext& errorContext)
{
HRESULT hr = S_OK;
PCWSTR pstrHandlerDllName = nullptr;
@ -53,6 +56,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
{
if (pConfiguration.QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
errorContext.generalErrorType = "ANCM In-Process Handler Load Failure";
std::unique_ptr<HostFxrResolutionResult> options;
RETURN_IF_FAILED(HostFxrResolutionResult::Create(
@ -66,12 +70,12 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
auto redirectionOutput = std::make_shared<StringStreamRedirectionOutput>();
hr = FindNativeAssemblyFromHostfxr(*options, pstrHandlerDllName, handlerDllPath, pApplication, pConfiguration, redirectionOutput);
hr = FindNativeAssemblyFromHostfxr(*options, pstrHandlerDllName, handlerDllPath, pApplication, pConfiguration, redirectionOutput, errorContext);
auto output = redirectionOutput->GetOutput();
if (FAILED_LOG(hr))
{
auto output = redirectionOutput->GetOutput();
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_INPROCESS_RH_ERROR_MSG,
@ -81,12 +85,20 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
}
else
{
errorContext.generalErrorType = "ANCM Out-Of-Process Handler Load Failure";
if (FAILED_LOG(hr = FindNativeAssemblyFromGlobalLocation(pConfiguration, pstrHandlerDllName, handlerDllPath)))
{
auto handlerName = handlerDllPath.empty() ? s_pwzAspnetcoreOutOfProcessRequestHandlerName : handlerDllPath.c_str();
EventLog::Error(
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING,
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG,
handlerDllPath.empty() ? s_pwzAspnetcoreOutOfProcessRequestHandlerName : handlerDllPath.c_str());
handlerName);
errorContext.detailedErrorContent = to_multi_byte_string(format(ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG, handlerName), CP_UTF8);
errorContext.statusCode = 500i16;
errorContext.subStatusCode = 36i16;
errorContext.errorReason = "The out of process request handler, aspnetcorev2_outofprocess.dll, could not be found next to the aspnetcorev2.dll.";
return hr;
}
@ -96,6 +108,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
hRequestHandlerDll = LoadLibrary(handlerDllPath.c_str());
RETURN_LAST_ERROR_IF_NULL(hRequestHandlerDll);
if (preventUnload)
{
// Pin module in memory
@ -111,7 +124,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
}
HRESULT
HandlerResolver::GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options)
HandlerResolver::GetApplicationFactory(const IHttpApplication& pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext)
{
SRWExclusiveLock lock(m_requestHandlerLoadLock);
if (m_loadedApplicationHostingModel != HOSTING_UNKNOWN)
@ -119,6 +132,12 @@ HandlerResolver::GetApplicationFactory(const IHttpApplication &pApplication, std
// Mixed hosting models
if (m_loadedApplicationHostingModel != options.QueryHostingModel())
{
errorContext.detailedErrorContent = to_multi_byte_string(format(ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG, pApplication.GetApplicationId(), options.QueryHostingModel()), CP_UTF8);
errorContext.statusCode = 500i16;
errorContext.subStatusCode = 34i16;
errorContext.generalErrorType = "ANCM Mixed Hosting Models Not Supported";
errorContext.errorReason = "Select a different application pool to create another application.";
EventLog::Error(
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
@ -130,6 +149,13 @@ HandlerResolver::GetApplicationFactory(const IHttpApplication &pApplication, std
// Multiple in-process apps
if (m_loadedApplicationHostingModel == HOSTING_IN_PROCESS && m_loadedApplicationId != pApplication.GetApplicationId())
{
errorContext.detailedErrorContent = to_multi_byte_string(format(ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG, pApplication.GetApplicationId()), CP_UTF8);
errorContext.statusCode = 500i16;
errorContext.subStatusCode = 35i16;
errorContext.generalErrorType = "ANCM Multiple In-Process Applications in same Process";
errorContext.errorReason = "Select a different application pool to create another in-process application.";
EventLog::Error(
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP,
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
@ -141,7 +167,7 @@ HandlerResolver::GetApplicationFactory(const IHttpApplication &pApplication, std
m_loadedApplicationHostingModel = options.QueryHostingModel();
m_loadedApplicationId = pApplication.GetApplicationId();
RETURN_IF_FAILED(LoadRequestHandlerAssembly(pApplication, options, pApplicationFactory));
RETURN_IF_FAILED(LoadRequestHandlerAssembly(pApplication, options, pApplicationFactory, errorContext));
return S_OK;
}
@ -181,7 +207,7 @@ HandlerResolver::FindNativeAssemblyFromGlobalLocation(
}
catch (...)
{
EventLog::Info(
EventLog::Info(
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING,
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG,
pstrHandlerDllName);
@ -204,7 +230,8 @@ HandlerResolver::FindNativeAssemblyFromHostfxr(
std::wstring& handlerDllPath,
const IHttpApplication &pApplication,
const ShimOptions& pConfiguration,
std::shared_ptr<RedirectionOutput> stringRedirectionOutput
std::shared_ptr<StringStreamRedirectionOutput> stringRedirectionOutput,
ErrorContext& errorContext
)
try
{
@ -214,14 +241,25 @@ try
DWORD dwBufferSize = s_initialGetNativeSearchDirectoriesBufferSize;
DWORD dwRequiredBufferSize = 0;
m_hHostFxrDll.Load(hostfxrOptions.GetHostFxrLocation());
try
{
m_hHostFxrDll.Load(hostfxrOptions.GetHostFxrLocation());
}
catch (...)
{
errorContext.detailedErrorContent = "Could not load hostfxr.dll.";
errorContext.statusCode = 500i16;
errorContext.subStatusCode = 32i16;
errorContext.generalErrorType = "ANCM Failed to Load dll";
errorContext.errorReason = "The application was likely published for a different bitness than w3wp.exe/iisexpress.exe is running as.";
throw;
}
{
auto redirectionOutput = LoggingHelpers::CreateOutputs(
pConfiguration.QueryStdoutLogEnabled(),
pConfiguration.QueryStdoutLogFile(),
pApplication.GetApplicationPhysicalPath(),
std::move(stringRedirectionOutput)
stringRedirectionOutput
);
StandardStreamRedirection stdOutRedirection(*redirectionOutput.get(), m_pServer.IsCommandLineLaunch());
@ -256,7 +294,16 @@ try
else
{
// If hostfxr didn't set the required buffer size, something in the app is misconfigured
// Ex: Framework not found.
// This like almost always is framework not found.
auto output = to_multi_byte_string(stringRedirectionOutput->GetOutput(), CP_UTF8);
errorContext.detailedErrorContent.resize(output.length());
memcpy(&errorContext.detailedErrorContent[0], output.c_str(), output.length());
errorContext.statusCode = 500i16;
errorContext.subStatusCode = 31i16;
errorContext.generalErrorType = "ANCM Failed to Find Native Dependencies";
errorContext.errorReason = "The specified version of Microsoft.NetCore.App or Microsoft.AspNetCore.App was not found.";
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_HOSTFXR_FAILURE_MSG
@ -296,6 +343,16 @@ try
if (!fFound)
{
// This only occurs if the request handler isn't referenced by the app, which rarely happens if they are targeting the shared framework.
errorContext.statusCode = 500i16;
errorContext.subStatusCode = 33i16;
errorContext.generalErrorType = "ANCM Request Handler Load Failure";
errorContext.detailedErrorContent = to_multi_byte_string(format(ASPNETCORE_EVENT_INPROCESS_RH_REFERENCE_MSG, handlerDllPath.empty()
? s_pwzAspnetcoreInProcessRequestHandlerName
: handlerDllPath.c_str()),
CP_UTF8);
errorContext.errorReason = "Make sure Microsoft.AspNetCore.App is referenced by your application.";
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_INPROCESS_RH_REFERENCE_MSG,

View File

@ -16,11 +16,11 @@ class HandlerResolver
{
public:
HandlerResolver(HMODULE hModule, const IHttpServer &pServer);
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options);
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext);
void ResetHostingModel();
private:
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory);
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory, ErrorContext& errorContext);
HRESULT FindNativeAssemblyFromGlobalLocation(const ShimOptions& pConfiguration, PCWSTR libraryName, std::wstring& handlerDllPath);
HRESULT FindNativeAssemblyFromHostfxr(
const HostFxrResolutionResult& hostfxrOptions,
@ -28,7 +28,8 @@ private:
std::wstring& handlerDllPath,
const IHttpApplication &pApplication,
const ShimOptions& pConfiguration,
std::shared_ptr<RedirectionOutput> stringRedirectionOutput);
std::shared_ptr<StringStreamRedirectionOutput> stringRedirectionOutput,
ErrorContext& errorContext);
HMODULE m_hModule;
const IHttpServer &m_pServer;

View File

@ -2,7 +2,7 @@
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title> HTTP Error 500.0 - ANCM In-Process Handler Load Failure </title>
<title> HTTP Error %d.%d - %s </title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
@ -58,15 +58,11 @@
</style>
</head>
<body>
<h1> HTTP Error 500.0 - ANCM In-Process Handler Load Failure </h1>
<h1> HTTP Error %d.%d - %s </h1>
<h2> Common causes of this issue: </h2>
%s
<ul>
<li> The specified version of Microsoft.NetCore.App or Microsoft.AspNetCore.App was not found. </li>
<li> The in process request handler, Microsoft.AspNetCore.Server.IIS, was not referenced in the application. </li>
<li> ANCM could not find dotnet. </li>
</ul>
%s
<h2> Troubleshooting steps: </h2>

View File

@ -2,7 +2,7 @@
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title> HTTP Error 500.0 - ANCM Out-Of-Process Handler Load Failure </title>
<title> HTTP Error %d.%d - %s </title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
@ -58,13 +58,11 @@
</style>
</head>
<body>
<h1> HTTP Error 500.0 - ANCM Out-Of-Process Handler Load Failure </h1>
<h1> HTTP Error %d.%d - %s </h1>
<h2> Common causes of this issue: </h2>
<ul>
<li>The out of process request handler, aspnetcorev2_outofprocess.dll, could not be found next to the aspnetcorev2.dll.</li>
<li> Could not read configuration correctly. Check the application's associated web.config.</li>
</ul>
%s
%s
<h2> Troubleshooting steps: </h2>
<ul>

View File

@ -5,6 +5,7 @@
#include "StringHelpers.h"
#include "ConfigurationLoadException.h"
#include "Environment.h"
#define CS_ASPNETCORE_HANDLER_VERSION L"handlerVersion"
@ -41,4 +42,16 @@ ShimOptions::ShimOptions(const ConfigurationSource &configurationSource) :
m_fStdoutLogEnabled = section->GetRequiredBool(CS_ASPNETCORE_STDOUT_LOG_ENABLED);
m_struStdoutLogFile = section->GetRequiredString(CS_ASPNETCORE_STDOUT_LOG_FILE);
m_fDisableStartupPage = section->GetRequiredBool(CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE);
// This will not include environment variables defined in the web.config.
// Reading environment variables can be added here, but it adds more code to the shim.
const auto detailedErrors = Environment::GetEnvironmentVariableValue(L"ASPNETCORE_DETAILEDERRORS").value_or(L"");
const auto aspnetCoreEnvironment = Environment::GetEnvironmentVariableValue(L"ASPNETCORE_ENVIRONMENT").value_or(L"");
const auto dotnetEnvironment = Environment::GetEnvironmentVariableValue(L"DOTNET_ENVIRONMENT").value_or(L"");
auto detailedErrorsEnabled = equals_ignore_case(L"1", detailedErrors) || equals_ignore_case(L"true", detailedErrors);
auto aspnetCoreEnvironmentEnabled = equals_ignore_case(L"Development", aspnetCoreEnvironment);
auto dotnetEnvironmentEnabled = equals_ignore_case(L"Development", dotnetEnvironment);
m_fShowDetailedErrors = detailedErrorsEnabled || aspnetCoreEnvironmentEnabled || dotnetEnvironmentEnabled;
}

View File

@ -59,6 +59,12 @@ public:
return m_fDisableStartupPage;
}
bool
QueryShowDetailedErrors() const noexcept
{
return m_fShowDetailedErrors;
}
ShimOptions(const ConfigurationSource &configurationSource);
private:
@ -69,4 +75,5 @@ private:
std::wstring m_struStdoutLogFile;
bool m_fStdoutLogEnabled;
bool m_fDisableStartupPage;
bool m_fShowDetailedErrors;
};

View File

@ -15,6 +15,7 @@
#include "WebConfigConfigurationSource.h"
#include "ConfigurationLoadException.h"
#include "resource.h"
#include "file_utility.h"
extern HINSTANCE g_hServerModule;
@ -86,23 +87,39 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)
const WebConfigConfigurationSource configurationSource(m_pServer.GetAdminManager(), pHttpApplication);
ShimOptions options(configurationSource);
const auto hr = TryCreateApplication(pHttpContext, options);
ErrorContext errorContext;
errorContext.statusCode = 500i16;
errorContext.subStatusCode = 0i16;
const auto hr = TryCreateApplication(pHttpContext, options, errorContext);
if (FAILED_LOG(hr))
{
// Log the failure and update application info to not try again
EventLog::Error(
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR,
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG,
pHttpApplication.GetApplicationId(),
hr);
auto page = options.QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS ? IN_PROCESS_SHIM_STATIC_HTML : OUT_OF_PROCESS_SHIM_STATIC_HTML;
std::string responseContent;
if (options.QueryShowDetailedErrors())
{
responseContent = FILE_UTILITY::GetHtml(g_hServerModule, page, errorContext.statusCode, errorContext.subStatusCode, errorContext.generalErrorType, errorContext.errorReason, errorContext.detailedErrorContent);
}
else
{
responseContent = FILE_UTILITY::GetHtml(g_hServerModule, page, errorContext.statusCode, errorContext.subStatusCode, errorContext.generalErrorType, errorContext.errorReason);
}
m_pApplication = make_application<ServerErrorApplication>(
pHttpApplication,
hr,
g_hServerModule,
options.QueryDisableStartupPage(),
options.QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS ? IN_PROCESS_SHIM_STATIC_HTML : OUT_OF_PROCESS_SHIM_STATIC_HTML);
responseContent,
errorContext.statusCode,
errorContext.subStatusCode,
"Internal Server Error");
}
return S_OK;
}
@ -124,14 +141,18 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)
m_pApplication = make_application<ServerErrorApplication>(
pHttpApplication,
E_FAIL,
g_hServerModule);
false /* disableStartupPage */,
"" /* responseContent */,
500i16 /* statusCode */,
0i16 /* subStatusCode */,
"Internal Server Error");
return S_OK;
}
}
HRESULT
APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOptions& options)
APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOptions& options, ErrorContext& error)
{
const auto startupEvent = Environment::GetEnvironmentVariableValue(L"ASPNETCORE_STARTUP_SUSPEND_EVENT");
if (startupEvent.has_value())
@ -157,7 +178,7 @@ APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOpt
}
}
RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(*pHttpContext.GetApplication(), m_pApplicationFactory, options));
RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(*pHttpContext.GetApplication(), m_pApplicationFactory, options, error));
LOG_INFO(L"Creating handler application");
IAPPLICATION * newApplication;

View File

@ -77,7 +77,7 @@ private:
CreateApplication(IHttpContext& pHttpContext);
HRESULT
TryCreateApplication(IHttpContext& pHttpContext, const ShimOptions& options);
TryCreateApplication(IHttpContext& pHttpContext, const ShimOptions& options, ErrorContext& error);
IHttpServer &m_pServer;
HandlerResolver &m_handlerResolver;

View File

@ -196,6 +196,7 @@
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="PollingAppOfflineApplication.h" />
<ClInclude Include="application.h" />
<ClInclude Include="BindingInformation.h" />
<ClInclude Include="ConfigurationSection.h" />
@ -220,11 +221,11 @@
<ClInclude Include="LoggingHelpers.h" />
<ClInclude Include="ModuleHelpers.h" />
<ClInclude Include="NonCopyable.h" />
<ClInclude Include="ServerErrorApplication.h" />
<ClInclude Include="StandardStreamRedirection.h" />
<ClInclude Include="RegistryKey.h" />
<ClInclude Include="requesthandler.h" />
<ClInclude Include="resources.h" />
<ClInclude Include="ServerErrorApplication.h" />
<ClInclude Include="ServerErrorHandler.h" />
<ClInclude Include="SRWExclusiveLock.h" />
<ClInclude Include="SRWSharedLock.h" />
@ -249,6 +250,7 @@
<ClCompile Include="HostFxrResolver.cpp" />
<ClCompile Include="HostFxrResolutionResult.cpp" />
<ClCompile Include="LoggingHelpers.cpp" />
<ClCompile Include="PollingAppOfflineApplication.cpp" />
<ClCompile Include="StandardStreamRedirection.cpp" />
<ClCompile Include="RedirectionOutput.cpp" />
<ClCompile Include="RegistryKey.cpp" />
@ -277,4 +279,4 @@
<Import Project="..\..\build\native.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -45,6 +45,13 @@ Environment::GetEnvironmentVariableValue(const std::wstring & str)
throw std::system_error(GetLastError(), std::system_category(), "GetEnvironmentVariableW");
}
else if (requestedSize == 1)
{
// String just contains a nullcharacter, return empty string
// GetEnvironmentVariableW has inconsistent behavior when returning size for an empty
// environment variable.
return L"";
}
std::wstring expandedStr;
do
@ -53,6 +60,10 @@ Environment::GetEnvironmentVariableValue(const std::wstring & str)
requestedSize = GetEnvironmentVariableW(str.c_str(), expandedStr.data(), requestedSize);
if (requestedSize == 0)
{
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
{
return std::nullopt;
}
throw std::system_error(GetLastError(), std::system_category(), "ExpandEnvironmentStringsW");
}
} while (expandedStr.size() != requestedSize + 1);

View File

@ -12,6 +12,16 @@ typedef INT(*hostfxr_main_fn) (DWORD argc, CONST PCWSTR argv[]);
typedef void(*corehost_error_writer_fn) (const WCHAR* message);
typedef corehost_error_writer_fn(*corehost_set_error_writer_fn) (corehost_error_writer_fn error_writer);
struct ErrorContext
{
// TODO consider adding HRESULT here
std::string detailedErrorContent;
USHORT statusCode;
USHORT subStatusCode;
std::string generalErrorType;
std::string errorReason;
};
class HostFxrErrorRedirector: NonCopyable
{
public:

View File

@ -9,16 +9,13 @@
class ServerErrorApplication : public PollingAppOfflineApplication
{
public:
ServerErrorApplication(const IHttpApplication& pApplication, HRESULT hr, HINSTANCE moduleInstance)
: ServerErrorApplication(pApplication, hr, moduleInstance, true /* disableStartupPage*/, 0 /* page */)
{
}
ServerErrorApplication(const IHttpApplication& pApplication, HRESULT hr, HINSTANCE moduleInstance, bool disableStartupPage, int page)
ServerErrorApplication(const IHttpApplication& pApplication, HRESULT hr, bool disableStartupPage, const std::string& responseContent, USHORT status, USHORT substatus, const std::string& statusText)
: m_HR(hr),
m_disableStartupPage(disableStartupPage),
m_page(page),
m_moduleInstance(moduleInstance),
m_responseContent(responseContent),
m_statusCode(status),
m_subStatusCode(substatus),
m_statusText(statusText),
PollingAppOfflineApplication(pApplication, PollingAppOfflineApplicationMode::StopWhenAdded)
{
}
@ -27,8 +24,8 @@ public:
HRESULT CreateHandler(IHttpContext *pHttpContext, IREQUEST_HANDLER ** pRequestHandler) override
{
auto handler = std::make_unique<ServerErrorHandler>(*pHttpContext, 500ui16, 0ui16, "Internal Server Error", m_HR, m_moduleInstance, m_disableStartupPage, m_page);
*pRequestHandler = handler.release();
*pRequestHandler = std::make_unique<ServerErrorHandler>(*pHttpContext, m_statusCode, m_subStatusCode, m_statusText, m_HR, m_disableStartupPage, m_responseContent).release();
return S_OK;
}
@ -36,6 +33,8 @@ public:
private:
HRESULT m_HR;
bool m_disableStartupPage;
int m_page;
HINSTANCE m_moduleInstance;
std::string m_responseContent;
USHORT m_statusCode;
USHORT m_subStatusCode;
std::string m_statusText;
};

View File

@ -9,44 +9,36 @@
class ServerErrorHandler : public REQUEST_HANDLER
{
public:
ServerErrorHandler(IHttpContext& pContext, USHORT statusCode, USHORT subStatusCode, const std::string& statusText, HRESULT hr, HINSTANCE module, bool disableStartupPage, int page) noexcept
: ServerErrorHandler(pContext, statusCode, subStatusCode, statusText, hr, module, disableStartupPage, page, std::vector<byte>())
{
}
ServerErrorHandler(IHttpContext& pContext, USHORT statusCode, USHORT subStatusCode, const std::string& statusText, HRESULT hr, HINSTANCE module, bool disableStartupPage, int page, const std::vector<byte>& content) noexcept
ServerErrorHandler(IHttpContext& pContext, USHORT statusCode, USHORT subStatusCode, const std::string& statusText, HRESULT hr, bool disableStartupPage, std::string& responseContent) noexcept
: REQUEST_HANDLER(pContext),
m_pContext(pContext),
m_HR(hr),
m_disableStartupPage(disableStartupPage),
m_statusCode(statusCode),
m_subStatusCode(subStatusCode),
m_statusText(std::move(statusText)),
m_page(page),
m_ExceptionInfoContent(content),
m_moduleInstance(module)
m_ExceptionInfoContent(responseContent)
{
}
REQUEST_NOTIFICATION_STATUS ExecuteRequestHandler() override
{
WriteStaticResponse(m_pContext, m_HR, m_disableStartupPage);
WriteResponse();
return RQ_NOTIFICATION_FINISH_REQUEST;
}
private:
void WriteStaticResponse(IHttpContext& pContext, HRESULT hr, bool disableStartupErrorPage)
void WriteResponse()
{
if (disableStartupErrorPage)
if (m_disableStartupPage)
{
pContext.GetResponse()->SetStatus(m_statusCode, m_statusText.c_str(), m_subStatusCode, E_FAIL);
m_pHttpContext.GetResponse()->SetStatus(m_statusCode, m_statusText.c_str(), m_subStatusCode, E_FAIL);
return;
}
HTTP_DATA_CHUNK dataChunk = {};
IHttpResponse* pResponse = pContext.GetResponse();
pResponse->SetStatus(m_statusCode, m_statusText.c_str(), m_subStatusCode, hr, nullptr, true);
IHttpResponse* pResponse = m_pHttpContext.GetResponse();
pResponse->SetStatus(m_statusCode, m_statusText.c_str(), m_subStatusCode, m_HR, nullptr, true);
pResponse->SetHeader("Content-Type",
"text/html",
(USHORT)strlen("text/html"),
@ -54,62 +46,16 @@ private:
);
dataChunk.DataChunkType = HttpDataChunkFromMemory;
if (m_ExceptionInfoContent.size() > 0)
{
dataChunk.FromMemory.pBuffer = &m_ExceptionInfoContent[0];
dataChunk.FromMemory.BufferLength = static_cast<ULONG>(m_ExceptionInfoContent.size());
}
else
{
static std::string s_html500Page = GetHtml(m_moduleInstance, m_page);
dataChunk.FromMemory.pBuffer = s_html500Page.data();
dataChunk.FromMemory.BufferLength = static_cast<ULONG>(s_html500Page.size());
}
dataChunk.FromMemory.pBuffer = m_ExceptionInfoContent.data();
dataChunk.FromMemory.BufferLength = static_cast<ULONG>(m_ExceptionInfoContent.size());
pResponse->WriteEntityChunkByReference(&dataChunk);
}
std::string
GetHtml(HMODULE module, int page)
{
try
{
HRSRC rc = nullptr;
HGLOBAL rcData = nullptr;
std::string data;
const char* pTempData = nullptr;
THROW_LAST_ERROR_IF_NULL(rc = FindResource(module, MAKEINTRESOURCE(page), RT_HTML));
THROW_LAST_ERROR_IF_NULL(rcData = LoadResource(module, rc));
auto const size = SizeofResource(module, rc);
THROW_LAST_ERROR_IF(size == 0);
THROW_LAST_ERROR_IF_NULL(pTempData = static_cast<const char*>(LockResource(rcData)));
data = std::string(pTempData, size);
auto additionalErrorLink = Environment::GetEnvironmentVariableValue(L"ANCM_ADDITIONAL_ERROR_PAGE_LINK");
std::string additionalHtml;
if (additionalErrorLink.has_value())
{
additionalHtml = format("<a href=\"%S\"> <cite> %S </cite></a> and ", additionalErrorLink->c_str(), additionalErrorLink->c_str());
}
return format(data, additionalHtml.c_str());
}
catch (...)
{
OBSERVE_CAUGHT_EXCEPTION();
return "";
}
}
IHttpContext& m_pContext;
HRESULT m_HR;
bool m_disableStartupPage;
int m_page;
HINSTANCE m_moduleInstance;
USHORT m_statusCode;
USHORT m_subStatusCode;
std::string m_statusText;
std::vector<byte> m_ExceptionInfoContent;
std::string& m_ExceptionInfoContent;
};

View File

@ -6,6 +6,7 @@
#include <Shlwapi.h>
#include "debugutil.h"
#include "exceptions.h"
#include "Environment.h"
HRESULT
FILE_UTILITY::IsPathUnc(
@ -167,3 +168,53 @@ Finished:
return hr;
}
std::string FILE_UTILITY::GetHtml(HMODULE module, int page, USHORT statusCode, USHORT subStatusCode, const std::string& speicificReasonPhrase, const std::string& solution)
{
return GetHtml(module, page, statusCode, subStatusCode, speicificReasonPhrase, solution, std::string());
}
std::string
FILE_UTILITY::GetHtml(HMODULE module, int page, USHORT statusCode, USHORT subStatusCode, const std::string& specificReasonPhrase, const std::string& errorReason, const std::string& specificError)
{
try
{
HRSRC rc = nullptr;
HGLOBAL rcData = nullptr;
std::string data;
const char* pTempData = nullptr;
THROW_LAST_ERROR_IF_NULL(rc = FindResource(module, MAKEINTRESOURCE(page), RT_HTML));
THROW_LAST_ERROR_IF_NULL(rcData = LoadResource(module, rc));
auto const size = SizeofResource(module, rc);
THROW_LAST_ERROR_IF(size == 0);
THROW_LAST_ERROR_IF_NULL(pTempData = static_cast<const char*>(LockResource(rcData)));
data = std::string(pTempData, size);
auto additionalErrorLink = Environment::GetEnvironmentVariableValue(L"ANCM_ADDITIONAL_ERROR_PAGE_LINK");
std::string additionalHtml;
if (additionalErrorLink.has_value())
{
additionalHtml = format("<a href=\"%S\"> <cite> %S </cite></a> and ", additionalErrorLink->c_str(), additionalErrorLink->c_str());
}
std::string formattedError;
if (!specificError.empty())
{
formattedError = format("<h2>Specific error detected by ANCM:</h2><h3>%s</h3>", specificError.c_str());
}
std::string formattedErrorReason;
if (!errorReason.empty())
{
formattedErrorReason = format("<h2> Common solutions to this issue: </h2>%s", errorReason.c_str());
}
return format(data, statusCode, subStatusCode, specificReasonPhrase.c_str(), statusCode, subStatusCode, specificReasonPhrase.c_str(), formattedErrorReason.c_str(), formattedError.c_str(), additionalHtml.c_str());
}
catch (...)
{
OBSERVE_CAUGHT_EXCEPTION();
return "";
}
}

View File

@ -28,7 +28,11 @@ public:
static
std::string
GetHtml(HMODULE module, int page);
GetHtml(HMODULE module, int page, USHORT statusCode, USHORT subStatusCode, const std::string& speicificReasonPhrase, const std::string& solution);
static
std::string
GetHtml(HMODULE module, int page, USHORT statusCode, USHORT subStatusCode, const std::string& speicificReasonPhrase, const std::string& solution, const std::string& error);
private:
static

View File

@ -75,7 +75,7 @@ public:
{
}
private:
protected:
IHttpContext& m_pHttpContext;
mutable LONG m_cRefs = 1;
};

View File

@ -43,7 +43,7 @@
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, exception code = '0x%x'. Please check the stderr logs for more information."
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_STDOUT_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, exception code = '0x%x'. First 30KB characters of captured stdout and stderr logs:\r\n%s"
#define ASPNETCORE_EVENT_INPROCESS_RH_ERROR_MSG L"Could not find 'aspnetcorev2_inprocess.dll'. Exception message:\r\n%s"
#define ASPNETCORE_EVENT_INPROCESS_RH_REFERENCE_MSG L"Could not find the assembly '%s' referenced for the in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application."
#define ASPNETCORE_EVENT_INPROCESS_RH_REFERENCE_MSG L"Could not find the assembly '%s' referenced for the in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS or Microsoft.AspNetCore.App is referenced in your application."
#define ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG L"Could not find the assembly '%s' for out-of-process application. Please confirm the assembly is installed correctly for IIS or IISExpress."
#define ASPNETCORE_EVENT_INPROCESS_START_SUCCESS_MSG L"Application '%s' started successfully."
#define ASPNETCORE_EVENT_INPROCESS_START_ERROR_MSG L"Application '%s' failed to start. Exception message:\r\n%s"

View File

@ -2,7 +2,7 @@
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title> HTTP Error 500.30 - ANCM In-Process Start Failure </title>
<title> HTTP Error %d.%d - %s </title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
@ -58,14 +58,11 @@
</style>
</head>
<body>
<h1> HTTP Error 500.30 - ANCM In-Process Start Failure </h1>
<h1> HTTP Error %d.%d - %s </h1>
<h2> Common causes of this issue: </h2>
<ul>
<li> The application failed to start </li>
<li> The application started but then stopped </li>
<li> The application started but threw an exception during startup </li>
</ul>
%s
%s
<h2> Troubleshooting steps: </h2>
<ul>

View File

@ -13,15 +13,18 @@ public:
StartupExceptionApplication(
IHttpServer& pServer,
IHttpApplication& pApplication,
HINSTANCE moduleInstance,
BOOL disableLogs,
HRESULT hr,
std::vector<byte>&& errorPageContent
)
const std::string& errorPageContent,
USHORT statusCode,
USHORT subStatusCode,
const std::string& statusText)
: m_disableLogs(disableLogs),
m_HR(hr),
m_moduleInstance(moduleInstance),
m_errorPageContent(std::move(errorPageContent)),
m_error(errorPageContent),
m_statusCode(statusCode),
m_subStatusCode(subStatusCode),
m_statusText(std::move(statusText)),
InProcessApplicationBase(pServer, pApplication)
{
}
@ -30,15 +33,17 @@ public:
HRESULT CreateHandler(IHttpContext* pHttpContext, IREQUEST_HANDLER** pRequestHandler)
{
*pRequestHandler = new ServerErrorHandler(*pHttpContext, 500, 30, "Internal Server Error", m_HR, m_moduleInstance, m_disableLogs, IN_PROCESS_RH_STATIC_HTML, m_errorPageContent);
*pRequestHandler = new ServerErrorHandler(*pHttpContext, m_statusCode, m_subStatusCode, m_statusText, m_HR, m_disableLogs, m_error);
return S_OK;
}
private:
std::vector<byte> m_errorPageContent;
std::string m_error;
BOOL m_disableLogs;
HRESULT m_HR;
HINSTANCE m_moduleInstance;
USHORT m_statusCode;
USHORT m_subStatusCode;
std::string m_statusText;
};

View File

@ -17,6 +17,7 @@
#include "WebConfigConfigurationSource.h"
#include "ConfigurationLoadException.h"
#include "StartupExceptionApplication.h"
#include "file_utility.h"
DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2_inprocess.dll");
@ -28,7 +29,7 @@ HINSTANCE g_hWinHttpModule;
HINSTANCE g_hAspNetCoreModule;
HANDLE g_hEventLog = NULL;
bool g_fInProcessApplicationCreated = false;
std::vector<byte> g_errorPageContent;
std::string g_errorPageContent;
HINSTANCE g_hServerModule;
HRESULT
@ -120,6 +121,10 @@ CreateApplication(
g_fInProcessApplicationCreated = true;
std::unique_ptr<IN_PROCESS_APPLICATION, IAPPLICATION_DELETER> inProcessApplication;
// TODO not sure how easy it will be to untangle errors here
// ErrorContext errorContext;
if (!FAILED_LOG(hr = IN_PROCESS_APPLICATION::Start(*pServer, pSite, *pHttpApplication, pParameters, nParameters, inProcessApplication)))
{
*ppApplication = inProcessApplication.release();
@ -129,7 +134,20 @@ CreateApplication(
std::unique_ptr<InProcessOptions> options;
THROW_IF_FAILED(InProcessOptions::Create(*pServer, pSite, *pHttpApplication, options));
// Set the currently running application to a fake application that returns startup exceptions.
auto pErrorApplication = std::make_unique<StartupExceptionApplication>(*pServer, *pHttpApplication, g_hServerModule, options->QueryDisableStartUpErrorPage(), hr, std::move(g_errorPageContent));
auto pErrorApplication = std::make_unique<StartupExceptionApplication>(*pServer,
*pHttpApplication,
options->QueryDisableStartUpErrorPage(),
hr,
FILE_UTILITY::GetHtml(g_hServerModule,
IN_PROCESS_RH_STATIC_HTML,
500i16,
30i16,
"ANCM In-Process Start Failure",
"<ul><li>The application failed to start</li><li>The application started but then stopped</li><li>The application started but threw an exception during startup</li></ul>",
g_errorPageContent),
500i16,
30i16,
"Internal Server Error");
RETURN_IF_FAILED(pErrorApplication->StartMonitoringAppOffline());
*ppApplication = pErrorApplication.release();

View File

@ -7,7 +7,7 @@
#include "EventLog.h"
extern bool g_fInProcessApplicationCreated;
extern std::vector<byte> g_errorPageContent;
extern std::string g_errorPageContent;
extern IHttpServer* g_pHttpServer;
//

View File

@ -2,7 +2,7 @@
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title> HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure </title>
<title> HTTP Error %d.%d - %s </title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
@ -58,17 +58,13 @@
</style>
</head>
<body>
<h1> HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure </h1>
<h1> HTTP Error %d.%d - %s </h1>
<h1> Common causes of this issue: </h1>
%s
<ul>
<li> The application process failed to start </li>
<li> The application process started but then stopped </li>
<li> The application process started but failed to listen on the configured port </li>
</ul>
%s
<h4> Troubleshooting steps: </h4>
<h2> Troubleshooting steps: </h2>
<ul>
<li> Check the system event log for error messages </li>

View File

@ -4,8 +4,10 @@
#include "forwardinghandler.h"
#include "url_utility.h"
#include "exceptions.h"
#include "ServerErrorApplication.h"
#include "ServerErrorHandler.h"
#include "resource.h"
#include "file_utility.h"
// Just to be aware of the FORWARDING_HANDLER object size.
C_ASSERT(sizeof(FORWARDING_HANDLER) <= 632);
@ -302,7 +304,21 @@ Failure:
}
else if (fFailedToStartKestrel && !m_pApplication->QueryConfig()->QueryDisableStartUpErrorPage())
{
ServerErrorHandler handler(*m_pW3Context, 502, 5, "Bad Gateway", hr, g_hOutOfProcessRHModule, m_pApplication->QueryConfig()->QueryDisableStartUpErrorPage(), OUT_OF_PROCESS_RH_STATIC_HTML);
static std::string htmlResponse = FILE_UTILITY::GetHtml(g_hOutOfProcessRHModule,
OUT_OF_PROCESS_RH_STATIC_HTML,
502,
5,
"ANCM Out-Of-Process Startup Failure",
"<ul><li> The application process failed to start </li><li> The application process started but then stopped </li><li> The application process started but failed to listen on the configured port </li></ul>");
ServerErrorHandler handler(*m_pW3Context,
502,
5,
"Bad Gateway",
hr,
m_pApplication->QueryConfig()->QueryDisableStartUpErrorPage(),
htmlResponse);
handler.ExecuteRequestHandler();
}
else

View File

@ -7,6 +7,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
@ -268,11 +269,60 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll"),
Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"),
true);
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
if (DeployerSelector.HasNewShim)
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "HTTP Error 500.32 - ANCM Failed to Load dll");
}
else
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
}
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrInvalid(deploymentResult), Logger);
}
[ConditionalFact]
public async Task PublishWithWrongBitness()
{
var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite);
if (deploymentParameters.ServerType == ServerType.IISExpress)
{
// TODO skip conditions for IISExpress
return;
}
deploymentParameters.ApplicationType = ApplicationType.Standalone;
deploymentParameters.AddServerConfigAction(element =>
{
element.RequiredElement("system.applicationHost").RequiredElement("applicationPools").RequiredElement("add").SetAttributeValue("enable32BitAppOnWin64", "true");
});
// Change ANCM dll to 32 bit
deploymentParameters.AddServerConfigAction(
element =>
{
var ancmElement = element
.RequiredElement("system.webServer")
.RequiredElement("globalModules")
.Elements("add")
.FirstOrDefault(e => e.Attribute("name").Value == "AspNetCoreModuleV2");
ancmElement.SetAttributeValue("image", ancmElement.Attribute("image").Value.Replace("x64", "x86"));
});
var deploymentResult = await DeployAsync(deploymentParameters);
if (DeployerSelector.HasNewShim)
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "500.32 - ANCM Failed to Load dll");
}
else
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "500.0 - ANCM In-Process Handler Load Failure");
}
}
[ConditionalFact]
[RequiresNewShim]
public async Task RemoveHostfxrFromApp_InProcessHostfxrLoadFailure()
@ -283,7 +333,15 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
// We don't distinguish between load failure types so making dll empty should be enough
File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"), "");
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
if (DeployerSelector.HasNewShim)
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "HTTP Error 500.32 - ANCM Failed to Load dll");
}
else
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
}
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrUnableToLoad(deploymentResult), Logger);
}
@ -295,7 +353,14 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
var deploymentResult = await DeployAsync(deploymentParameters);
Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult);
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
if (DeployerSelector.HasNewShim)
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "HTTP Error 500.31 - ANCM Failed to Find Native Dependencies");
}
else
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
}
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindNativeDependencies(deploymentResult), Logger);
}
@ -309,14 +374,23 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
File.Delete(Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll"));
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
if (DeployerSelector.IsForwardsCompatibilityTest)
if (DeployerSelector.HasNewShim && DeployerSelector.HasNewHandler)
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "HTTP Error 500.33 - ANCM Request Handler Load Failure ");
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindRequestHandler(deploymentResult), Logger);
}
else if (DeployerSelector.HasNewShim)
{
// Forwards compat tests fail earlier due to a error with the M.AspNetCore.Server.IIS package.
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "HTTP Error 500.31 - ANCM Failed to Find Native Dependencies");
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindNativeDependencies(deploymentResult), Logger);
}
else
{
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindRequestHandler(deploymentResult), Logger);
}
}
@ -750,11 +824,23 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
});
}
private async Task AssertSiteFailsToStartWithInProcessStaticContent(IISDeploymentResult deploymentResult)
private Task AssertSiteFailsToStartWithInProcessStaticContent(IISDeploymentResult deploymentResult)
{
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
return AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult, "HTTP Error 500.0 - ANCM In-Process Handler Load Failure");
}
private async Task AssertSiteFailsToStartWithInProcessStaticContent(IISDeploymentResult deploymentResult, string error)
{
HttpResponseMessage response = null;
// Make sure strings aren't freed.
for (var i = 0; i < 2; i++)
{
response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
}
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.Contains("HTTP Error 500.0 - ANCM In-Process Handler Load Failure", await response.Content.ReadAsStringAsync());
Assert.Contains(error, await response.Content.ReadAsStringAsync());
StopServer();
}
}

View File

@ -47,6 +47,12 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Assert.Equal(200, (int)result1.StatusCode);
Assert.Equal(500, (int)result2.StatusCode);
StopServer();
if (DeployerSelector.HasNewShim)
{
Assert.Contains("500.35 - ANCM Multiple In-Process Applications in same Process", await result2.Content.ReadAsStringAsync());
}
EventLogHelpers.VerifyEventLogEvent(result, EventLogHelpers.OnlyOneAppPerAppPool(), Logger);
}
@ -68,6 +74,12 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Assert.Equal(200, (int)result1.StatusCode);
Assert.Equal(500, (int)result2.StatusCode);
StopServer();
if (DeployerSelector.HasNewShim)
{
Assert.Contains("500.34 - ANCM Mixed Hosting Models Not Supported", await result2.Content.ReadAsStringAsync());
}
EventLogHelpers.VerifyEventLogEvent(result, "Mixed hosting model is not supported.", Logger);
}

View File

@ -259,7 +259,15 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public static string InProcessFailedToFindRequestHandler(IISDeploymentResult deploymentResult)
{
return "Could not find the assembly '(.*)' referenced for the in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application.";
if (DeployerSelector.HasNewShim)
{
return "Could not find the assembly '(.*)' referenced for the in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS or Microsoft.AspNetCore.App is referenced in your application.";
}
else
{
return "Could not find the assembly '(.*)' referenced for the in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application.";
}
}
public static string CouldNotStartStdoutFileRedirection(string file, IISDeploymentResult deploymentResult)

View File

@ -47,6 +47,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
public IDictionary<string, string> WebConfigBasedEnvironmentVariables { get; set; } = new Dictionary<string, string>();
public IDictionary<string, string> HandlerSettings { get; set; } = new Dictionary<string, string>();
}
}