Improve error messages and add static html pages for failure to start site. (#1421)

This commit is contained in:
Justin Kotalik 2018-09-25 15:40:15 -07:00 committed by GitHub
parent 2018a43d63
commit 1eb5da31e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 596 additions and 230 deletions

View File

@ -232,14 +232,14 @@
<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" />
<ClInclude Include="applicationmanager.h" />
<ClInclude Include="HandlerResolver.h" />
<ClInclude Include="PollingAppOfflineApplication.h" />
<ClInclude Include="proxymodule.h" />
<ClInclude Include="ServerErrorApplication.h" />
<ClInclude Include="ServerErrorHandler.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
@ -248,11 +248,11 @@
<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" />
<ClCompile Include="HandlerResolver.cpp" />
<ClCompile Include="PollingAppOfflineApplication.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
@ -284,6 +284,17 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="HtmlResponses.rc" />
</ItemGroup>
<ItemGroup>
<None Include="InProcessShimStaticHtml.htm">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="OutOfProcessShimStaticHtml.htm">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemGroup>
<Xml Include="aspnetcore_schema_v2.xml" />
</ItemGroup>

View File

@ -73,21 +73,18 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
pApplication.GetApplicationPhysicalPath(),
outputManager));
outputManager->TryStartRedirection();
hr = FindNativeAssemblyFromHostfxr(*options.get(), pstrHandlerDllName, handlerDllPath);
hr = FindNativeAssemblyFromHostfxr(*options.get(), pstrHandlerDllName, handlerDllPath, outputManager.get());
outputManager->TryStopRedirection();
if (FAILED(hr) && m_hHostFxrDll != nullptr)
if (FAILED_LOG(hr))
{
auto output = outputManager->GetStdOutContent();
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_INPROCESS_RH_ERROR_MSG,
handlerDllPath.empty()? s_pwzAspnetcoreInProcessRequestHandlerName : handlerDllPath.c_str(),
output.c_str());
return hr;
}
}
else
@ -122,55 +119,38 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
}
HRESULT
HandlerResolver::GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory)
HandlerResolver::GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options)
{
try
SRWExclusiveLock lock(m_requestHandlerLoadLock);
if (m_loadedApplicationHostingModel != HOSTING_UNKNOWN)
{
const WebConfigConfigurationSource configurationSource(m_pServer.GetAdminManager(), pApplication);
ShimOptions options(configurationSource);
SRWExclusiveLock lock(m_requestHandlerLoadLock);
if (m_loadedApplicationHostingModel != HOSTING_UNKNOWN)
// Mixed hosting models
if (m_loadedApplicationHostingModel != options.QueryHostingModel())
{
// Mixed hosting models
if (m_loadedApplicationHostingModel != options.QueryHostingModel())
{
EventLog::Error(
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
pApplication.GetApplicationId(),
options.QueryHostingModel());
EventLog::Error(
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
pApplication.GetApplicationId(),
options.QueryHostingModel());
return E_FAIL;
}
// Multiple in-process apps
if (m_loadedApplicationHostingModel == HOSTING_IN_PROCESS && m_loadedApplicationId != pApplication.GetApplicationId())
{
EventLog::Error(
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP,
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
pApplication.GetApplicationId());
return E_FAIL;
}
return E_FAIL;
}
// Multiple in-process apps
if (m_loadedApplicationHostingModel == HOSTING_IN_PROCESS && m_loadedApplicationId != pApplication.GetApplicationId())
{
EventLog::Error(
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP,
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
pApplication.GetApplicationId());
m_loadedApplicationHostingModel = options.QueryHostingModel();
m_loadedApplicationId = pApplication.GetApplicationId();
RETURN_IF_FAILED(LoadRequestHandlerAssembly(pApplication, options, pApplicationFactory));
return E_FAIL;
}
}
catch(ConfigurationLoadException &ex)
{
EventLog::Error(
ASPNETCORE_CONFIGURATION_LOAD_ERROR,
ASPNETCORE_CONFIGURATION_LOAD_ERROR_MSG,
ex.get_message().c_str());
RETURN_HR(E_FAIL);
}
CATCH_RETURN();
m_loadedApplicationHostingModel = options.QueryHostingModel();
m_loadedApplicationId = pApplication.GetApplicationId();
RETURN_IF_FAILED(LoadRequestHandlerAssembly(pApplication, options, pApplicationFactory));
return S_OK;
}
@ -222,7 +202,8 @@ HRESULT
HandlerResolver::FindNativeAssemblyFromHostfxr(
const HOSTFXR_OPTIONS& hostfxrOptions,
PCWSTR libraryName,
std::wstring& handlerDllPath
std::wstring& handlerDllPath,
BaseOutputManager* outputManager
)
{
std::wstring struNativeSearchPaths;
@ -230,23 +211,29 @@ HandlerResolver::FindNativeAssemblyFromHostfxr(
size_t intPrevIndex = 0;
DWORD dwBufferSize = s_initialGetNativeSearchDirectoriesBufferSize;
DWORD dwRequiredBufferSize = 0;
hostfxr_get_native_search_directories_fn pFnHostFxrSearchDirectories = nullptr;
RETURN_LAST_ERROR_IF_NULL(m_hHostFxrDll = LoadLibraryW(hostfxrOptions.GetHostFxrLocation().c_str()));
const auto pFnHostFxrSearchDirectories = ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(m_hHostFxrDll, "hostfxr_get_native_search_directories");
if (pFnHostFxrSearchDirectories == nullptr)
try
{
pFnHostFxrSearchDirectories = ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(m_hHostFxrDll, "hostfxr_get_native_search_directories");
}
catch (...)
{
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG,
hostfxrOptions.GetHostFxrLocation().c_str()
);
RETURN_IF_FAILED(E_FAIL);
);
return OBSERVE_CAUGHT_EXCEPTION();
}
RETURN_LAST_ERROR_IF_NULL(pFnHostFxrSearchDirectories);
struNativeSearchPaths.resize(dwBufferSize);
outputManager->TryStartRedirection();
while (TRUE)
{
DWORD hostfxrArgc;
@ -273,11 +260,23 @@ HandlerResolver::FindNativeAssemblyFromHostfxr(
}
else
{
// Log "Error finding native search directories from aspnetcore application.
// Stop redirecting before logging to event log to avoid logging debug logs
// twice.
outputManager->TryStopRedirection();
// If hostfxr didn't set the required buffer size, something in the app is misconfigured
// Ex: Framework not found.
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_HOSTFXR_FAILURE_MSG
);
return E_UNEXPECTED;
}
}
outputManager->TryStopRedirection();
struNativeSearchPaths.resize(struNativeSearchPaths.find(L'\0'));
auto fFound = FALSE;
@ -307,6 +306,10 @@ HandlerResolver::FindNativeAssemblyFromHostfxr(
if (!fFound)
{
EventLog::Error(
ASPNETCORE_EVENT_GENERAL_ERROR,
ASPNETCORE_EVENT_INPROCESS_RH_REFERENCE_MSG,
handlerDllPath.empty() ? s_pwzAspnetcoreInProcessRequestHandlerName : handlerDllPath.c_str());
return HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND);
}

View File

@ -9,18 +9,19 @@
#include "hostfxroptions.h"
#include "HandleWrapper.h"
#include "ApplicationFactory.h"
#include "BaseOutputManager.h"
class HandlerResolver
{
public:
HandlerResolver(HMODULE hModule, const IHttpServer &pServer);
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory);
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options);
void ResetHostingModel();
private:
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory);
HRESULT FindNativeAssemblyFromGlobalLocation(const ShimOptions& pConfiguration, PCWSTR libraryName, std::wstring& handlerDllPath);
HRESULT FindNativeAssemblyFromHostfxr(const HOSTFXR_OPTIONS& hostfxrOptions, PCWSTR libraryName, std::wstring& handlerDllPath);
HRESULT FindNativeAssemblyFromHostfxr(const HOSTFXR_OPTIONS& hostfxrOptions, PCWSTR libraryName, std::wstring& handlerDllPath, BaseOutputManager* outputManager);
HMODULE m_hModule;
const IHttpServer &m_pServer;

Binary file not shown.

View File

@ -0,0 +1,45 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title> IIS 500 Error </title>
<style type="text/css"></style>
</head>
<body>
<div id="content">
<div class="content-container">
<h3> HTTP Error 500.0 - ANCM InProcess Startup Failure </h3>
</div>
<div class="content-container">
<fieldset>
<h4> Common causes of this issue: </h4>
<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>
</fieldset>
</div>
<div class="content-container">
<fieldset>
<h4> Troubleshooting steps: </h4>
<ul>
<li> Check the system event log for error messages </li>
<li> Enable logging the application process' stdout messages </li>
<li> Attach a debugger to the application process and inspect </li>
</ul>
</fieldset>
<fieldset>
<h4> For more information visit:
<a href="https://go.microsoft.com/fwlink/?LinkID=808681">
<cite> https://go.microsoft.com/fwlink/?LinkID=808681 </cite>
</a>
</h4>
</fieldset>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title> IIS 500 Error </title>
<style type="text/css"></style>
</head>
<body>
<div id="content">
<div class="content-container">
<h3> HTTP Error 500.0 - ANCM OutOfProcess Startup Failure </h3>
</div>
<div class="content-container">
<fieldset>
<h4> Common causes of this issue: </h4>
<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>
</fieldset>
</div>
<div class="content-container">
<fieldset>
<h4> Troubleshooting steps: </h4>
<ul>
<li> Check the system event log for error messages </li>
<li> Enable logging the application process' stdout messages </li>
<li> Attach a debugger to the application process and inspect </li>
</ul>
</fieldset>
<fieldset>
<h4> For more information visit:
<a href="https://go.microsoft.com/fwlink/?LinkID=808681">
<cite> https://go.microsoft.com/fwlink/?LinkID=808681 </cite>
</a>
</h4>
</fieldset>
</div>
</div>
</body>
</html>

View File

@ -9,8 +9,16 @@
class ServerErrorApplication : public PollingAppOfflineApplication
{
public:
ServerErrorApplication(const IHttpApplication& pApplication, HRESULT hr)
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)
: m_HR(hr),
m_disableStartupPage(disableStartupPage),
m_page(page),
m_moduleInstance(moduleInstance),
PollingAppOfflineApplication(pApplication, PollingAppOfflineApplicationMode::StopWhenAdded)
{
}
@ -19,7 +27,7 @@ public:
HRESULT CreateHandler(IHttpContext *pHttpContext, IREQUEST_HANDLER ** pRequestHandler) override
{
auto handler = std::make_unique<ServerErrorHandler>(*pHttpContext, m_HR);
auto handler = std::make_unique<ServerErrorHandler>(*pHttpContext, m_HR, m_moduleInstance, m_disableStartupPage, m_page);
*pRequestHandler = handler.release();
return S_OK;
}
@ -27,5 +35,8 @@ public:
HRESULT OnAppOfflineFound() noexcept override { return S_OK; }
private:
HRESULT m_HR;
bool m_disableStartupPage;
int m_page;
HINSTANCE m_moduleInstance;
};

View File

@ -1,23 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#include "requesthandler.h"
class ServerErrorHandler : public REQUEST_HANDLER
{
public:
ServerErrorHandler(IHttpContext &pContext, HRESULT hr) : m_pContext(pContext), m_HR(hr)
{
}
REQUEST_NOTIFICATION_STATUS OnExecuteRequestHandler() override
{
m_pContext.GetResponse()->SetStatus(500, "Internal Server Error", 0, m_HR);
return RQ_NOTIFICATION_FINISH_REQUEST;
}
private:
IHttpContext &m_pContext;
HRESULT m_HR;
};

View File

@ -40,4 +40,5 @@ ShimOptions::ShimOptions(const ConfigurationSource &configurationSource) :
m_strArguments = section->GetString(CS_ASPNETCORE_PROCESS_ARGUMENTS).value_or(CS_ASPNETCORE_PROCESS_ARGUMENTS_DEFAULT);
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);
}

View File

@ -53,6 +53,12 @@ public:
return m_struStdoutLogFile;
}
bool
QueryDisableStartupPage() const noexcept
{
return m_fDisableStartupPage;
}
ShimOptions(const ConfigurationSource &configurationSource);
private:
@ -62,4 +68,5 @@ private:
std::wstring m_strHandlerVersion;
std::wstring m_struStdoutLogFile;
bool m_fStdoutLogEnabled;
bool m_fDisableStartupPage;
};

View File

@ -12,6 +12,11 @@
#include "EventLog.h"
#include "ServerErrorApplication.h"
#include "AppOfflineApplication.h"
#include "WebConfigConfigurationSource.h"
#include "ConfigurationLoadException.h"
#include "resource.h"
extern HINSTANCE g_hServerModule;
HRESULT
APPLICATION_INFO::CreateHandler(
@ -23,7 +28,7 @@ APPLICATION_INFO::CreateHandler(
{
SRWSharedLock lock(m_applicationLock);
RETURN_IF_FAILED(hr = TryCreateHandler(pHttpContext, pHandler));
if (hr == S_OK)
@ -31,10 +36,10 @@ APPLICATION_INFO::CreateHandler(
return S_OK;
}
}
{
SRWExclusiveLock lock(m_applicationLock);
// check if other thread created application
RETURN_IF_FAILED(hr = TryCreateHandler(pHttpContext, pHandler));
@ -66,48 +71,78 @@ APPLICATION_INFO::CreateHandler(
HRESULT
APPLICATION_INFO::CreateApplication(const IHttpApplication& pHttpApplication)
{
HRESULT hr = S_OK;
if (AppOfflineApplication::ShouldBeStarted(pHttpApplication))
{
LOG_INFO(L"Detected app_offline file, creating polling application");
#pragma warning( push )
#pragma warning ( disable : 26409 ) // Disable "Avoid using new", using custom deleter here
m_pApplication.reset(new AppOfflineApplication(pHttpApplication));
#pragma warning( pop )
m_pApplication = make_application<AppOfflineApplication>(pHttpApplication);
return S_OK;
}
else
{
FINISHED_IF_FAILED(m_handlerResolver.GetApplicationFactory(pHttpApplication, m_pApplicationFactory));
try
{
const WebConfigConfigurationSource configurationSource(m_pServer.GetAdminManager(), pHttpApplication);
ShimOptions options(configurationSource);
LOG_INFO(L"Creating handler application");
IAPPLICATION * newApplication;
FINISHED_IF_FAILED(m_pApplicationFactory->Execute(
&m_pServer,
&pHttpApplication,
&newApplication));
const auto hr = TryCreateApplication(pHttpApplication, options);
m_pApplication.reset(newApplication);
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);
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);
}
return S_OK;
}
catch (ConfigurationLoadException &ex)
{
EventLog::Error(
ASPNETCORE_CONFIGURATION_LOAD_ERROR,
ASPNETCORE_CONFIGURATION_LOAD_ERROR_MSG,
ex.get_message().c_str());
}
catch (...)
{
EventLog::Error(
ASPNETCORE_CONFIGURATION_LOAD_ERROR,
ASPNETCORE_CONFIGURATION_LOAD_ERROR_MSG,
L"");
}
m_pApplication = make_application<ServerErrorApplication>(
pHttpApplication,
E_FAIL,
g_hServerModule);
return S_OK;
}
}
Finished:
HRESULT
APPLICATION_INFO::TryCreateApplication(const IHttpApplication& pHttpApplication, const ShimOptions& options)
{
RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(pHttpApplication, m_pApplicationFactory, options));
LOG_INFO(L"Creating handler application");
if (m_pApplication == nullptr || FAILED(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);
#pragma warning( push )
#pragma warning ( disable : 26409 ) // Disable "Avoid using new", using custom deleter here
m_pApplication.reset(new ServerErrorApplication(pHttpApplication, hr));
#pragma warning( pop )
}
IAPPLICATION * newApplication;
RETURN_IF_FAILED(m_pApplicationFactory->Execute(
&m_pServer,
&pHttpApplication,
&newApplication));
return hr;
m_pApplication.reset(newApplication);
return S_OK;
}
HRESULT
@ -139,7 +174,7 @@ APPLICATION_INFO::ShutDownApplication(bool fServerInitiated)
if (m_pApplication)
{
LOG_INFOF(L"Stopping application '%ls'", QueryApplicationInfoKey().c_str());
m_pApplication ->Stop(fServerInitiated);
m_pApplication->Stop(fServerInitiated);
m_pApplication = nullptr;
m_pApplicationFactory = nullptr;
}

View File

@ -76,6 +76,9 @@ private:
HRESULT
CreateApplication(const IHttpApplication& pHttpApplication);
HRESULT
TryCreateApplication(const IHttpApplication& pHttpApplication, const ShimOptions& options);
IHttpServer &m_pServer;
HandlerResolver &m_handlerResolver;

View File

@ -13,7 +13,7 @@ extern BOOL g_fInShutdown;
//
// Retrieves the application info from the application manager
// Will create the application info if it isn't initalized
// Will create the application info if it isn't initialized
//
HRESULT
APPLICATION_MANAGER::GetOrCreateApplicationInfo(
@ -21,7 +21,6 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo(
_Out_ std::shared_ptr<APPLICATION_INFO>& ppApplicationInfo
)
{
auto &pApplication = *pHttpContext.GetApplication();
// The configuration path is unique for each application and is used for the

View File

@ -0,0 +1,19 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by HtmlResponses.rc
//
#define IN_PROCESS_SHIM_STATIC_HTML 101
#define OUT_OF_PROCESS_SHIM_STATIC_HTML 102
#define UNKNOWN_HOSTING_STATIC_HTML 103
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -223,12 +223,14 @@
<ClInclude Include="NonCopyable.h" />
<ClInclude Include="NullOutputManager.h" />
<ClInclude Include="PipeOutputManager.h" />
<ClInclude Include="StdWrapper.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" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="StdWrapper.h" />
<ClInclude Include="StringHelpers.h" />
<ClInclude Include="sttimer.h" />
<ClInclude Include="WebConfigConfigurationSection.h" />

View File

@ -11,8 +11,6 @@
#include "StdWrapper.h"
#include "StringHelpers.h"
extern HINSTANCE g_hModule;
FileOutputManager::FileOutputManager(std::wstring pwzStdOutLogFileName, std::wstring pwzApplicationPath) :
FileOutputManager(pwzStdOutLogFileName, pwzApplicationPath, /* fEnableNativeLogging */ true) { }

View File

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#include "requesthandler.h"
#include "file_utility.h"
class ServerErrorHandler : public REQUEST_HANDLER
{
public:
ServerErrorHandler(IHttpContext &pContext, HRESULT hr, HINSTANCE moduleInstance, bool disableStartupPage, int page)
: m_pContext(pContext), m_HR(hr), m_disableStartupPage(disableStartupPage), m_page(page), m_moduleInstance(moduleInstance)
{
}
REQUEST_NOTIFICATION_STATUS OnExecuteRequestHandler() override
{
static std::string s_html500Page = FILE_UTILITY::GetHtml(m_moduleInstance, m_page);
WriteStaticResponse(m_pContext, s_html500Page, m_HR, m_disableStartupPage);
return RQ_NOTIFICATION_FINISH_REQUEST;
}
private:
IHttpContext &m_pContext;
HRESULT m_HR;
bool m_disableStartupPage;
int m_page;
HINSTANCE m_moduleInstance;
};

View File

@ -5,6 +5,7 @@
#include <Shlwapi.h>
#include "debugutil.h"
#include "exceptions.h"
HRESULT
FILE_UTILITY::IsPathUnc(
@ -165,3 +166,24 @@ FILE_UTILITY::EnsureDirectoryPathExist(
Finished:
return hr;
}
std::string
FILE_UTILITY::GetHtml(HMODULE module, int page)
{
HRESULT hr = S_OK;
HRSRC rc = nullptr;
HGLOBAL rcData = nullptr;
const char* data = nullptr;
DWORD size = 0;
FINISHED_LAST_ERROR_IF_NULL(rc = FindResource(module, MAKEINTRESOURCE(page), RT_HTML));
FINISHED_LAST_ERROR_IF_NULL(rcData = LoadResource(module, rc));
size = SizeofResource(module, rc);
FINISHED_LAST_ERROR_IF(size == 0);
FINISHED_LAST_ERROR_IF_NULL(data = static_cast<const char*>(LockResource(rcData)));
return data;
Finished:
return "";
}

View File

@ -25,6 +25,11 @@ public:
EnsureDirectoryPathExist(
_In_ LPCWSTR pszPath
);
static
std::string
GetHtml(HMODULE module, int page);
private:
static
HRESULT
@ -32,5 +37,6 @@ private:
__in LPCWSTR pszPath,
__out BOOL * pfIsUnc
);
};

View File

@ -51,3 +51,13 @@ std::unique_ptr<APPLICATION, IAPPLICATION_DELETER> ReferenceApplication(APPLICAT
application->ReferenceApplication();
return std::unique_ptr<APPLICATION, IAPPLICATION_DELETER>(application);
};
template< class APPLICATION, typename ...Params >
std::unique_ptr<IAPPLICATION, IAPPLICATION_DELETER> make_application(Params&&... params)
{
#pragma warning( push )
#pragma warning ( disable : 26409 ) // Disable "Avoid using new", using custom deleter here
return std::unique_ptr<IAPPLICATION, IAPPLICATION_DELETER>(new APPLICATION(std::forward<Params>(params)...));
#pragma warning( pop )
}

View File

@ -46,6 +46,32 @@ public:
{
}
protected:
static
void WriteStaticResponse(IHttpContext& pContext, std::string &s_html500Page, HRESULT hr, bool disableStartupErrorPage)
{
if (disableStartupErrorPage)
{
pContext.GetResponse()->SetStatus(500, "Internal Server Error", 30, E_FAIL);
return;
}
HTTP_DATA_CHUNK dataChunk = {};
IHttpResponse* pResponse = pContext.GetResponse();
pResponse->SetStatus(500, "Internal Server Error", 0, hr, nullptr, true);
pResponse->SetHeader("Content-Type",
"text/html",
(USHORT)strlen("text/html"),
FALSE
);
dataChunk.DataChunkType = HttpDataChunkFromMemory;
dataChunk.FromMemory.pBuffer = s_html500Page.data();
dataChunk.FromMemory.BufferLength = static_cast<ULONG>(s_html500Page.size());
pResponse->WriteEntityChunkByReference(&dataChunk);
}
private:
mutable LONG m_cRefs = 1;
};

View File

@ -28,7 +28,7 @@
#define ASPNETCORE_EVENT_APP_SHUTDOWN_SUCCESSFUL_MSG L"Application '%s' has shutdown."
#define ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG L"Only one inprocess application is allowed per IIS application pool. Please assign the application '%s' to a different IIS application pool."
#define ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG L"Mixed hosting model is not supported. Application '%s' configured with different hostingModel value '%d' other than the one of running application(s)."
#define ASPNETCORE_CONFIGURATION_LOAD_ERROR_MSG L"Configuration load error. %s"
#define ASPNETCORE_CONFIGURATION_LOAD_ERROR_MSG L"Could not load configuration. Exception message: %s"
#define ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG L"Failed to start application '%s', ErrorCode '0x%x'."
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_STDOUT_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, exit code = '%d'. Last 4KB characters of captured stdout and stderr logs:\r\n%s"
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, exit code = '%d'. Please check the stderr logs for more information."
@ -39,9 +39,11 @@
#define ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG L"Failed to recycle application due to a configuration change at '%s'. Recycling worker process."
#define ASPNETCORE_EVENT_MODULE_DISABLED_MSG L"AspNetCore Module is disabled"
#define ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG L"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '%s'."
#define ASPNETCORE_EVENT_HOSTFXR_FAILURE_MSG L"Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. This most likely means the app is misconfigured, please check the versions of Microsoft.NetCore.App and Microsoft.AspNetCore.App that are targeted by the application and are installed on the machine."
#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'. Last 4KB characters of captured stdout and stderr logs:\r\n%s"
#define ASPNETCORE_EVENT_INPROCESS_RH_ERROR_MSG L"Could not find the assembly '%s' for in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application. Captured output: %s"
#define ASPNETCORE_EVENT_INPROCESS_RH_ERROR_MSG L"Could not find inprocess request handler. Captured output from invoking hostfxr: %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_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 the coreclr in-process successfully."
#define ASPNETCORE_EVENT_INPROCESS_START_ERROR_MSG L"Application '%s' wasn't able to start. %s"

View File

@ -229,10 +229,10 @@
<ClInclude Include="InProcessApplicationBase.h" />
<ClInclude Include="inprocesshandler.h" />
<ClInclude Include="InProcessOptions.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="ShuttingDownApplication.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="StartupExceptionApplication.h" />
<ClInclude Include="StartupExceptionHandler.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
@ -247,8 +247,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="StartupExceptionApplication.cpp" />
<ClCompile Include="StartupExceptionHandler.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">
@ -262,9 +260,13 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="HtmlResponses.rc" />
<ResourceCompile Include="inprocessrequesthandler.rc" />
</ItemGroup>
<ItemGroup>
<None Include="InProcessRhStaticHtml.htm">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="Source.def" />
</ItemGroup>
<Import Project="..\..\..\build\native.targets" />

View File

@ -0,0 +1,44 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title> IIS 500.30 Error </title>
<style type="text/css"></style>
</head>
<body>
<div id="content">
<div class="content-container"><h3> HTTP Error 500.30 - ANCM In-Process Start Failure </h3></div>
<div class="content-container">
<fieldset>
<h4> Common causes of this issue: </h4>
<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>
</fieldset>
</div>
<div class="content-container">
<fieldset>
<h4> Troubleshooting steps: </h4>
<ul>
<li> Check the system event log for error messages </li>
<li> Enable logging the application process' stdout messages </li>
<li> Attach a debugger to the application process and inspect </li>
</ul>
</fieldset>
<fieldset>
<h4>
For more information visit:
<a href="https://go.microsoft.com/fwlink/?LinkID =808681"> <cite> https://go.microsoft.com/fwlink/?LinkID=808681 </cite></a>
</h4>
</fieldset>
</div>
</div>
</body>
</html>

View File

@ -1,10 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "StartupExceptionApplication.h"
HRESULT StartupExceptionApplication::CreateHandler(IHttpContext *pHttpContext, IREQUEST_HANDLER ** pRequestHandler)
{
*pRequestHandler = new StartupExceptionHandler(pHttpContext, m_disableLogs);
return S_OK;
}

View File

@ -4,7 +4,8 @@
#pragma once
#include "InProcessApplicationBase.h"
#include "StartupExceptionHandler.h"
#include "ServerErrorHandler.h"
#include "resource.h"
class StartupExceptionApplication : public InProcessApplicationBase
{
@ -12,15 +13,24 @@ public:
StartupExceptionApplication(
IHttpServer& pServer,
IHttpApplication& pApplication,
BOOL disableLogs)
HINSTANCE moduleInstance,
BOOL disableLogs,
HRESULT hr)
: m_disableLogs(disableLogs),
m_HR(hr),
m_moduleInstance(moduleInstance),
InProcessApplicationBase(pServer, pApplication)
{
}
~StartupExceptionApplication() = default;
HRESULT CreateHandler(IHttpContext * pHttpContext, IREQUEST_HANDLER ** pRequestHandler) override;
HRESULT
CreateHandler(IHttpContext *pHttpContext, IREQUEST_HANDLER ** pRequestHandler)
{
*pRequestHandler = new ServerErrorHandler(*pHttpContext, m_HR,m_moduleInstance, m_disableLogs, IN_PROCESS_RH_STATIC_HTML);
return S_OK;
}
std::string&
GetStaticHtml500Content()
@ -31,5 +41,7 @@ public:
private:
std::string html500Page;
BOOL m_disableLogs;
HRESULT m_HR;
HINSTANCE m_moduleInstance;
};

View File

@ -1,55 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "StartupExceptionApplication.h"
#include "StartupExceptionHandler.h"
std::string StartupExceptionHandler::s_html500Page = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> \
<html xmlns=\"http://www.w3.org/1999/xhtml\"> \
<head> \
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" /> \
<title> IIS 500.30 Error </title><style type=\"text/css\"></style></head> \
<body> <div id = \"content\"> \
<div class = \"content-container\"><h3> HTTP Error 500.30 - ANCM In-Process Start Failure </h3></div> \
<div class = \"content-container\"> \
<fieldset> <h4> Common causes of this issue: </h4> \
<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></fieldset> \
</div> \
<div class = \"content-container\"> \
<fieldset><h4> Troubleshooting steps: </h4> \
<ul><li> Check the system event log for error messages </li> \
<li> Enable logging the application process' stdout messages </li> \
<li> Attach a debugger to the application process and inspect </li></ul></fieldset> \
<fieldset><h4> For more information visit: \
<a href=\"https://go.microsoft.com/fwlink/?LinkID=808681\"> <cite> https://go.microsoft.com/fwlink/?LinkID=808681 </cite></a></h4> \
</fieldset> \
</div> \
</div></body></html>";
REQUEST_NOTIFICATION_STATUS StartupExceptionHandler::OnExecuteRequestHandler()
{
if (!m_disableLogs)
{
HTTP_DATA_CHUNK DataChunk;
IHttpResponse* pResponse = m_pContext->GetResponse();
pResponse->SetStatus(500, "Internal Server Error", 30, E_FAIL, NULL, TRUE);
pResponse->SetHeader("Content-Type",
"text/html",
(USHORT)strlen("text/html"),
FALSE
);
DataChunk.DataChunkType = HttpDataChunkFromMemory;
DataChunk.FromMemory.pBuffer = (PVOID)s_html500Page.c_str();
DataChunk.FromMemory.BufferLength = (ULONG)s_html500Page.size();
pResponse->WriteEntityChunkByReference(&DataChunk);
}
else
{
m_pContext->GetResponse()->SetStatus(500, "Internal Server Error", 30, E_FAIL);
}
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
}

View File

@ -3,31 +3,38 @@
#pragma once
#include <string>
#include "requesthandler.h"
#include "resource.h"
#include "file_utility.h"
class StartupExceptionApplication;
class StartupExceptionHandler : public REQUEST_HANDLER
{
public:
StartupExceptionHandler(IHttpContext* pContext, BOOL disableLogs)
:
m_pContext(pContext),
m_disableLogs(disableLogs)
StartupExceptionHandler(IHttpContext& pContext, BOOL disableLogs, HRESULT hr)
: m_pContext(pContext),
m_disableLogs(disableLogs),
m_HR(hr)
{
}
~StartupExceptionHandler()
{
}
REQUEST_NOTIFICATION_STATUS OnExecuteRequestHandler() override;
REQUEST_NOTIFICATION_STATUS OnExecuteRequestHandler()
{
static std::string s_html500Page = FILE_UTILITY::GetHtml(g_hModule, IN_PROCESS_SHIM_STATIC_HTML);
WriteStaticResponse(m_pContext, s_html500Page, m_HR, m_disableLogs);
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
}
private:
IHttpContext * m_pContext;
IHttpContext& m_pContext;
BOOL m_disableLogs;
static
std::string s_html500Page;
HRESULT m_HR;
};

View File

@ -6,7 +6,6 @@
#include <VersionHelpers.h>
#include "inprocessapplication.h"
#include "StartupExceptionApplication.h"
#include "inprocesshandler.h"
#include "requesthandler_config.h"
#include "debugutil.h"
@ -17,6 +16,7 @@
#include "EventLog.h"
#include "WebConfigConfigurationSource.h"
#include "ConfigurationLoadException.h"
#include "StartupExceptionApplication.h"
DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2_inprocess.dll");
@ -28,6 +28,7 @@ HINSTANCE g_hWinHttpModule;
HINSTANCE g_hAspNetCoreModule;
HANDLE g_hEventLog = NULL;
bool g_fInProcessApplicationCreated = false;
HINSTANCE g_hServerModule;
HRESULT
InitializeGlobalConfiguration(
@ -69,7 +70,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
)
{
UNREFERENCED_PARAMETER(lpReserved);
g_hServerModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
@ -100,6 +101,7 @@ CreateApplication(
{
try
{
HRESULT hr = S_OK;
RETURN_IF_FAILED(InitializeGlobalConfiguration(pServer, pHttpApplication));
// In process application was already created so another call to CreateApplication
@ -114,7 +116,7 @@ CreateApplication(
g_fInProcessApplicationCreated = true;
std::unique_ptr<IN_PROCESS_APPLICATION, IAPPLICATION_DELETER> inProcessApplication;
if (!FAILED_LOG(IN_PROCESS_APPLICATION::Start(*pServer, *pHttpApplication, pParameters, nParameters, inProcessApplication)))
if (!FAILED_LOG(hr = IN_PROCESS_APPLICATION::Start(*pServer, *pHttpApplication, pParameters, nParameters, inProcessApplication)))
{
*ppApplication = inProcessApplication.release();
}
@ -123,7 +125,7 @@ CreateApplication(
std::unique_ptr<InProcessOptions> options;
THROW_IF_FAILED(InProcessOptions::Create(*pServer, *pHttpApplication, options));
// Set the currently running application to a fake application that returns startup exceptions.
auto pErrorApplication = std::make_unique<StartupExceptionApplication>(*pServer, *pHttpApplication, options->QueryDisableStartUpErrorPage());
auto pErrorApplication = std::make_unique<StartupExceptionApplication>(*pServer, *pHttpApplication, g_hServerModule, options->QueryDisableStartUpErrorPage(), hr);
RETURN_IF_FAILED(pErrorApplication->StartMonitoringAppOffline());
*ppApplication = pErrorApplication.release();

View File

@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by HtmlResponses.rc
//
#define IN_PROCESS_RH_STATIC_HTML 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
{
private const string DetailedErrorsEnvironmentVariable = "ASPNETCORE_DETAILEDERRORS";
private static readonly TimeSpan _timeout = TimeSpan.FromSeconds(10);
private static readonly TimeSpan _timeout = TimeSpan.FromSeconds(60);
private static readonly TimeSpan _retryDelay = TimeSpan.FromMilliseconds(200);
private CancellationTokenSource _hostShutdownToken = new CancellationTokenSource();

View File

@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
await deploymentResult.HttpClient.RetryRequestAsync("/HelloWorld", r => r.StatusCode == HttpStatusCode.InternalServerError);
StopServer();
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not find the assembly 'aspnetcorev2_inprocess.dll'");
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not find the assembly 'aspnetcorev2_inprocess.dll'", Logger);
}
[ConditionalTheory]

View File

@ -1,12 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
@ -21,6 +23,25 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
AssertSingleEntry(expectedRegexMatchString, entries);
}
public static void VerifyEventLogEvent(IISDeploymentResult deploymentResult, string expectedRegexMatchString, ILogger logger)
{
Assert.True(deploymentResult.HostProcess.HasExited);
var entries = GetEntries(deploymentResult);
try
{
AssertSingleEntry(expectedRegexMatchString, entries);
}
catch (Exception ex)
{
foreach (var entry in entries)
{
logger.LogInformation(entry.Message);
}
throw ex;
}
}
public static void VerifyEventLogEvents(IISDeploymentResult deploymentResult, params string[] expectedRegexMatchString)
{
Assert.True(deploymentResult.HostProcess.HasExited);
@ -149,7 +170,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public static string ConfigurationLoadError(IISDeploymentResult deploymentResult, string reason)
{
return $"Configuration load error. {reason}";
return $"Could not load configuration. Exception message: {reason}";
}
public static string OutOfProcessFailedToStart(IISDeploymentResult deploymentResult)
@ -159,6 +180,23 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
$"The last try of listening port is '(.*)'. See previous warnings for details.";
}
public static string InProcessHostfxrInvalid(IISDeploymentResult deploymentResult)
{
return $"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '(.*)'.";
}
public static string InProcessFailedToFindNativeDependencies(IISDeploymentResult deploymentResult)
{
return "Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. " +
"This most likely means the app is misconfigured, please check the versions of Microsoft.NetCore.App and Microsoft.AspNetCore.App that " +
"are targeted by the application and are installed on the machine.";
}
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.";
}
private static string EscapedContentRoot(IISDeploymentResult deploymentResult)
{
var contentRoot = deploymentResult.ContentRoot;

View File

@ -12,6 +12,8 @@ using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
@ -159,5 +161,14 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
return Directory.GetFiles(logFolderPath).Single();
}
}
public static void ModifyFrameworkVersionInRuntimeConfig(IISDeploymentResult deploymentResult)
{
var path = Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.runtimeconfig.json");
dynamic depsFileContent = JsonConvert.DeserializeObject(File.ReadAllText(path));
depsFileContent["runtimeOptions"]["framework"]["version"] = "2.9.9";
var output = JsonConvert.SerializeObject(depsFileContent);
File.WriteAllText(path, output);
}
}
}

View File

@ -32,7 +32,7 @@ namespace IIS.FunctionalTests.Inprocess
var deploymentResult = await DeployAsync(deploymentParameters);
InvalidateRuntimeConfig(deploymentResult);
Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult);
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
Assert.False(response.IsSuccessStatusCode);
@ -54,7 +54,7 @@ namespace IIS.FunctionalTests.Inprocess
var deploymentResult = await DeployAsync(deploymentParameters);
InvalidateRuntimeConfig(deploymentResult);
Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult);
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
Assert.False(response.IsSuccessStatusCode);
@ -146,14 +146,5 @@ namespace IIS.FunctionalTests.Inprocess
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Invoked hostfxr");
Assert.Contains("Invoked hostfxr", contents);
}
private static void InvalidateRuntimeConfig(IISDeploymentResult deploymentResult)
{
var path = Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.runtimeconfig.json");
dynamic depsFileContent = JsonConvert.DeserializeObject(File.ReadAllText(path));
depsFileContent["runtimeOptions"]["framework"]["version"] = "2.9.9";
var output = JsonConvert.SerializeObject(depsFileContent);
File.WriteAllText(path, output);
}
}
}

View File

@ -151,8 +151,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
if (capabilities.HasFlag(IISCapability.ApplicationInitialization))
{
IsMet &= _dynamicCompressionAvailable;
if (!_dynamicCompressionAvailable)
IsMet &= _applicationInitializationModule;
if (!_applicationInitializationModule)
{
SkipReason += "The machine does not have IIS ApplicationInitialization installed.";
}

View File

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.AspNetCore.Testing.xunit;
using Newtonsoft.Json;
using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
@ -60,6 +61,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
StopServer();
EventLogHelpers.VerifyEventLogEvent(deploymentResult, $@"Application '{Regex.Escape(deploymentResult.ContentRoot)}\\' wasn't able to start. {subError}");
Assert.Contains("HTTP Error 500.0 - ANCM InProcess Startup Failure", await response.Content.ReadAsStringAsync());
}
[ConditionalFact]
@ -185,6 +188,48 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
EventLogHelpers.InProcessThreadExit(deploymentResult, "12"));
}
[ConditionalFact]
public async Task RemoveHostfxrFromApp_InProcessHostfxrInvalid()
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
deploymentParameters.ApplicationType = ApplicationType.Standalone;
var deploymentResult = await DeployAsync(deploymentParameters);
File.Copy(
Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll"),
Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"),
true);
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrInvalid(deploymentResult), Logger);
}
[ConditionalFact]
public async Task TargedDifferenceSharedFramework_FailedToFindNativeDependencies()
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
var deploymentResult = await DeployAsync(deploymentParameters);
Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult);
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindNativeDependencies(deploymentResult), Logger);
}
[ConditionalFact]
public async Task RemoveInProcessReference_FailedToFindRequestHandler()
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
deploymentParameters.ApplicationType = ApplicationType.Standalone;
var deploymentResult = await DeployAsync(deploymentParameters);
File.Delete(Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll"));
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindRequestHandler(deploymentResult), Logger);
}
[ConditionalFact]
public async Task StartupTimeoutIsApplied()
{
@ -239,7 +284,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
StopServer();
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
EventLogHelpers.FailedToStartApplication(deploymentResult, "0x80004005"),
EventLogHelpers.ConfigurationLoadError(deploymentResult, "Unknown hosting model 'bogus'. Please specify either hostingModel=\"inprocess\" or hostingModel=\"outofprocess\" in the web.config file.")
);
}
@ -259,8 +303,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode);
StopServer();
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
EventLogHelpers.FailedToStartApplication(deploymentResult, "0x80004005"),
EventLogHelpers.ConfigurationLoadError(deploymentResult, expectedError)
);
}
@ -407,5 +451,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
}
});
}
private async Task AssertSiteFailsToStartWithInProcessStaticContent(IISDeploymentResult deploymentResult)
{
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.Contains("HTTP Error 500.0 - ANCM InProcess Startup Failure", await response.Content.ReadAsStringAsync());
StopServer();
}
}
}

View File

@ -64,6 +64,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest);
Assert.False(response.IsSuccessStatusCode);
var responseString = await response.Content.ReadAsStringAsync();
Assert.Contains("HTTP Error 500.0 - ANCM OutOfProcess Startup Failure", responseString);
}
[ConditionalTheory]