Write Premain errors to the response and write different status codes (#10282)
This commit is contained in:
parent
833ddbe899
commit
2d1c14d5a9
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
IHttpContext& m_pHttpContext;
|
||||
mutable LONG m_cRefs = 1;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue