Return static 500.30 file on startup fails for in-process (#934)

This commit is contained in:
Justin Kotalik 2018-06-25 17:12:30 -07:00 committed by GitHub
parent 4a0691a36c
commit 0d96354eef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 324 additions and 152 deletions

View File

@ -55,7 +55,6 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo(
if (*ppApplicationInfo == NULL)
{
pApplicationInfo = new APPLICATION_INFO();
if (pApplicationInfo == NULL)
{

View File

@ -147,8 +147,8 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
m_pApplicationInfo->ExtractApplication(&pApplication);
// make sure application is in running state
// cannot recreate the application as we cannot reload clr for inprocess
// make sure application is in running state
// cannot recreate the application as we cannot reload clr for inprocess
if (pApplication != NULL &&
pApplication->QueryStatus() != APPLICATION_STATUS::RUNNING &&
pApplication->QueryStatus() != APPLICATION_STATUS::STARTING)
@ -156,7 +156,6 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
goto Finished;
}
// Create RequestHandler and process the request
hr = pApplication->CreateHandler(pHttpContext,
&m_pHandler);
@ -167,7 +166,6 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
}
retVal = m_pHandler->OnExecuteRequestHandler();
}
catch (...)
{

View File

@ -3,7 +3,7 @@
#include "SRWExclusiveLock.h"
SRWExclusiveLock:: SRWExclusiveLock(const SRWLOCK& lock)
SRWExclusiveLock::SRWExclusiveLock(const SRWLOCK& lock)
: m_lock(lock)
{
AcquireSRWLockExclusive(const_cast<SRWLOCK*>(&m_lock));

View File

@ -3,7 +3,7 @@
#include "SRWSharedLock.h"
SRWSharedLock:: SRWSharedLock(const SRWLOCK& lock)
SRWSharedLock::SRWSharedLock(const SRWLOCK& lock)
: m_lock(lock)
{
AcquireSRWLockShared(const_cast<SRWLOCK*>(&m_lock));

View File

@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "InProcessApplicationBase.h"
#include "SRWExclusiveLock.h"
hostfxr_main_fn InProcessApplicationBase::s_fMainCallback = NULL;
InProcessApplicationBase::InProcessApplicationBase(
IHttpServer *pHttpServer)
:
m_srwLock(),
m_fRecycleCalled(FALSE),
m_pHttpServer(pHttpServer)
{
InitializeSRWLock(&m_srwLock);
}
VOID
InProcessApplicationBase::Recycle(
VOID
)
{
// We need to guarantee that recycle is only called once, as calling pHttpServer->RecycleProcess
// multiple times can lead to AVs.
if (m_fRecycleCalled)
{
return;
}
{
SRWExclusiveLock lock(m_srwLock);
if (m_fRecycleCalled)
{
return;
}
m_fRecycleCalled = true;
}
if (!m_pHttpServer->IsCommandLineLaunch())
{
// IIS scenario.
// We don't actually handle any shutdown logic here.
// Instead, we notify IIS that the process needs to be recycled, which will call
// ApplicationManager->Shutdown(). This will call shutdown on the application.
m_pHttpServer->RecycleProcess(L"AspNetCore InProcess Recycle Process on Demand");
}
else
{
// IISExpress scenario
// Try to graceful shutdown the managed application
// and call exit to terminate current process
ShutDown();
// If we set a static callback, we don't want to kill the current process as
// that will kill the test process and means we are running in hostable webcore mode.
if (m_pHttpServer->IsCommandLineLaunch()
&& s_fMainCallback == NULL)
{
exit(0);
}
}
}

View File

@ -0,0 +1,30 @@
// 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 "precomp.hxx"
#include "application.h"
#include "requesthandler_config.h"
typedef INT(*hostfxr_main_fn) (CONST DWORD argc, CONST PCWSTR argv[]); // TODO these may need to be BSTRs
class InProcessApplicationBase : public APPLICATION
{
public:
InProcessApplicationBase(IHttpServer* pHttpServer);
~InProcessApplicationBase() = default;
VOID Recycle(VOID) override;
protected:
BOOL m_fRecycleCalled;
SRWLOCK m_srwLock;
IHttpServer* const m_pHttpServer;
// Allows to override call to hostfxr_main with custome callback
// used in testing
static hostfxr_main_fn s_fMainCallback;
};

View File

@ -212,14 +212,20 @@
<ItemGroup>
<ClInclude Include="aspnetcore_event.h" />
<ClInclude Include="inprocessapplication.h" />
<ClInclude Include="InProcessApplicationBase.h" />
<ClInclude Include="inprocesshandler.h" />
<ClInclude Include="precomp.hxx" />
<ClInclude Include="StartupExceptionApplication.h" />
<ClInclude Include="StartupExceptionHandler.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cxx" />
<ClCompile Include="inprocessapplication.cpp" />
<ClCompile Include="InProcessApplicationBase.cpp" />
<ClCompile Include="inprocesshandler.cpp" />
<ClCompile Include="managedexports.cxx" />
<ClCompile Include="StartupExceptionApplication.cpp" />
<ClCompile Include="StartupExceptionHandler.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">

View File

@ -0,0 +1,15 @@
// 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"
VOID StartupExceptionApplication::ShutDown()
{
exit(0);
}
HRESULT StartupExceptionApplication::CreateHandler(IHttpContext *pContext, IREQUEST_HANDLER ** pRequestHandler)
{
*pRequestHandler = new StartupExceptionHandler(pContext, m_disableLogs, this);
return S_OK;
}

View File

@ -0,0 +1,70 @@
// 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 "precomp.hxx"
#include "InProcessApplicationBase.h"
#include "StartupExceptionHandler.h"
#include "SRWExclusiveLock.h"
class StartupExceptionApplication : public InProcessApplicationBase
{
public:
StartupExceptionApplication(IHttpServer* pServer, BOOL disableLogs)
: m_disableLogs(disableLogs),
m_pHttpServer(pServer),
InProcessApplicationBase(pServer)
{
InitializeSRWLock(&m_srwLock);
m_status = APPLICATION_STATUS::RUNNING;
}
~StartupExceptionApplication() = default;
virtual VOID ShutDown() override;
virtual HRESULT CreateHandler(IHttpContext * pHttpContext, IREQUEST_HANDLER ** pRequestHandler) override;
std::string&
GetStaticHtml500Content()
{
{
SRWExclusiveLock lock(m_srwLock);
if (html500Page.empty())
{
html500Page = std::string("<!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>");
}
}
return html500Page;
}
private:
std::string html500Page;
SRWLOCK m_srwLock;
BOOL m_disableLogs;
IHttpServer* m_pHttpServer;
};

View File

@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "StartupExceptionHandler.h"
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
);
const std::string& html500Page = m_pApplication->GetStaticHtml500Content();
DataChunk.DataChunkType = HttpDataChunkFromMemory;
DataChunk.FromMemory.pBuffer = (PVOID)html500Page.c_str();
DataChunk.FromMemory.BufferLength = (ULONG)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;
}
REQUEST_NOTIFICATION_STATUS StartupExceptionHandler::OnAsyncCompletion(DWORD , HRESULT )
{
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
}
VOID StartupExceptionHandler::TerminateRequest(bool )
{
return VOID();
}

View File

@ -0,0 +1,38 @@
// 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 "precomp.hxx"
#include "requesthandler.h"
#include "StartupExceptionApplication.h"
class StartupExceptionApplication;
class StartupExceptionHandler : public REQUEST_HANDLER
{
public:
virtual REQUEST_NOTIFICATION_STATUS OnExecuteRequestHandler() override;
virtual REQUEST_NOTIFICATION_STATUS OnAsyncCompletion(DWORD cbCompletion, HRESULT hrCompletionStatus) override;
virtual VOID TerminateRequest(bool fClientInitiated) override;
StartupExceptionHandler(IHttpContext* pContext, BOOL disableLogs, StartupExceptionApplication* pApplication)
:
m_pContext(pContext),
m_disableLogs(disableLogs),
m_pApplication(pApplication)
{
}
~StartupExceptionHandler()
{
}
private:
IHttpContext * m_pContext;
BOOL m_disableLogs;
StartupExceptionApplication* m_pApplication;
};

View File

@ -8,9 +8,12 @@
#include <VersionHelpers.h>
#include "inprocessapplication.h"
#include "StartupExceptionApplication.h"
#include "inprocesshandler.h"
#include "requesthandler_config.h"
#include "debugutil.h"
#include "resources.h"
#include "exceptions.h"
DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2_inprocess.dll");
@ -90,46 +93,30 @@ CreateApplication(
_Out_ IAPPLICATION **ppApplication
)
{
HRESULT hr = S_OK;
IN_PROCESS_APPLICATION *pApplication = NULL;
REQUESTHANDLER_CONFIG *pConfig = NULL;
// Initialze some global variables here
InitializeGlobalConfiguration(pServer);
try
{
hr = REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(pServer, pHttpApplication, &pConfig);
if (FAILED(hr))
REQUESTHANDLER_CONFIG *pConfig = NULL;
RETURN_IF_FAILED(REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(pServer, pHttpApplication, &pConfig));
auto config = std::unique_ptr<REQUESTHANDLER_CONFIG>(pConfig);
BOOL disableStartupPage = pConfig->QueryDisableStartUpErrorPage();
auto pApplication = std::make_unique<IN_PROCESS_APPLICATION>(pServer, std::move(config));
if (FAILED(pApplication->LoadManagedApplication()))
{
goto Finished;
// Set the currently running application to a fake application that returns startup exceptions.
*ppApplication = new StartupExceptionApplication(pServer, disableStartupPage);
}
pApplication = new IN_PROCESS_APPLICATION(pServer, pConfig);
pConfig = NULL;
*ppApplication = pApplication;
}
catch (std::bad_alloc&)
{
hr = E_OUTOFMEMORY;
}
Finished:
if (FAILED(hr))
{
if (pApplication != NULL)
else
{
delete pApplication;
pApplication = NULL;
}
if (pConfig != NULL)
{
delete pConfig;
pConfig = NULL;
*ppApplication = pApplication.release();
}
}
CATCH_RETURN();
return hr;
return S_OK;
}

View File

@ -13,39 +13,30 @@
#include "exceptions.h"
IN_PROCESS_APPLICATION* IN_PROCESS_APPLICATION::s_Application = NULL;
hostfxr_main_fn IN_PROCESS_APPLICATION::s_fMainCallback = NULL;
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
IHttpServer *pHttpServer,
REQUESTHANDLER_CONFIG *pConfig) :
std::unique_ptr<REQUESTHANDLER_CONFIG> pConfig) :
m_pHttpServer(pHttpServer),
m_ProcessExitCode(0),
m_fBlockCallbacksIntoManaged(FALSE),
m_fInitialized(FALSE),
m_fShutdownCalledFromNative(FALSE),
m_fShutdownCalledFromManaged(FALSE),
m_srwLock()
InProcessApplicationBase(pHttpServer),
m_pConfig(std::move(pConfig))
{
// is it guaranteed that we have already checked app offline at this point?
// If so, I don't think there is much to do here.
DBG_ASSERT(pHttpServer != NULL);
DBG_ASSERT(pConfig != NULL);
InitializeSRWLock(&m_srwLock);
m_pConfig = pConfig;
m_status = APPLICATION_STATUS::STARTING;
}
IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
{
if (m_pConfig != NULL)
{
delete m_pConfig;
m_pConfig = NULL;
}
m_hThread = NULL;
s_Application = NULL;
}
@ -129,7 +120,6 @@ Finished:
}
}
VOID
IN_PROCESS_APPLICATION::ShutDownInternal()
{
@ -205,54 +195,6 @@ IN_PROCESS_APPLICATION::ShutDownInternal()
s_Application = NULL;
}
__override
VOID
IN_PROCESS_APPLICATION::Recycle(
VOID
)
{
// We need to guarantee that recycle is only called once, as calling pHttpServer->RecycleProcess
// multiple times can lead to AVs.
if (m_fRecycleCalled)
{
return;
}
{
SRWExclusiveLock lock(m_srwLock);
if (m_fRecycleCalled)
{
return;
}
m_fRecycleCalled = true;
}
if (!m_pHttpServer->IsCommandLineLaunch())
{
// IIS scenario.
// We don't actually handle any shutdown logic here.
// Instead, we notify IIS that the process needs to be recycled, which will call
// ApplicationManager->Shutdown(). This will call shutdown on the application.
m_pHttpServer->RecycleProcess(L"AspNetCore InProcess Recycle Process on Demand");
}
else
{
// IISExpress scenario
// Try to graceful shutdown the managed application
// and call exit to terminate current process
ShutDown();
// If we set a static callback, we don't want to kill the current process as
// that will kill the test process and means we are running in hostable webcore mode.
if (s_fMainCallback == NULL)
{
exit(0);
}
}
}
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_APPLICATION::OnAsyncCompletion(
DWORD cbCompletion,
@ -712,7 +654,7 @@ IN_PROCESS_APPLICATION::RunDotnetApplication(DWORD argc, CONST PCWSTR* argv, hos
REQUESTHANDLER_CONFIG*
IN_PROCESS_APPLICATION::QueryConfig() const
{
return m_pConfig;
return m_pConfig.get();
}
HRESULT

View File

@ -4,22 +4,21 @@
#pragma once
#include "precomp.hxx"
#include "application.h"
#include "InProcessApplicationBase.h"
#include "inprocesshandler.h"
#include "requesthandler_config.h"
typedef INT(*hostfxr_main_fn) (CONST DWORD argc, CONST PCWSTR argv[]); // TODO these may need to be BSTRs
typedef REQUEST_NOTIFICATION_STATUS(WINAPI * PFN_REQUEST_HANDLER) (IN_PROCESS_HANDLER* pInProcessHandler, void* pvRequestHandlerContext);
typedef BOOL(WINAPI * PFN_SHUTDOWN_HANDLER) (void* pvShutdownHandlerContext);
typedef REQUEST_NOTIFICATION_STATUS(WINAPI * PFN_MANAGED_CONTEXT_HANDLER)(void *pvManagedHttpContext, HRESULT hrCompletionStatus, DWORD cbCompletion);
class IN_PROCESS_APPLICATION : public APPLICATION
class IN_PROCESS_APPLICATION : public InProcessApplicationBase
{
public:
IN_PROCESS_APPLICATION(
IHttpServer* pHttpServer,
REQUESTHANDLER_CONFIG *pConfig);
std::unique_ptr<REQUESTHANDLER_CONFIG> pConfig);
~IN_PROCESS_APPLICATION();
@ -36,12 +35,6 @@ public:
_In_ VOID* pvShutdownHandlerContext
);
__override
VOID
Recycle(
VOID
);
__override
HRESULT
CreateHandler(
@ -163,7 +156,6 @@ private:
BOOL m_fRecycleCalled;
BOOL m_fInitialized;
SRWLOCK m_srwLock;
// Thread for capturing startup stderr logs when logging is disabled
HANDLE m_hErrThread;
@ -172,11 +164,9 @@ private:
static IN_PROCESS_APPLICATION* s_Application;
IOutputManager* m_pLoggerProvider;
REQUESTHANDLER_CONFIG* m_pConfig;
std::unique_ptr<REQUESTHANDLER_CONFIG> m_pConfig;
// Allows to override call to hostfxr_main with custome callback
// used in testing
static hostfxr_main_fn s_fMainCallback;
static
VOID

View File

@ -23,28 +23,6 @@ __override
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_HANDLER::OnExecuteRequestHandler()
{
// First get the in process Application
HRESULT hr;
hr = m_pApplication->LoadManagedApplication();
if (FAILED(hr))
{
// TODO remove com_error?
/*_com_error err(hr);
if (ANCMEvents::ANCM_START_APPLICATION_FAIL::IsEnabled(m_pW3Context->GetTraceContext()))
{
ANCMEvents::ANCM_START_APPLICATION_FAIL::RaiseEvent(
m_pW3Context->GetTraceContext(),
NULL,
err.ErrorMessage());
}
*/
//fInternalError = TRUE;
m_pW3Context->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
}
// FREB log
if (ANCMEvents::ANCM_START_APPLICATION_SUCCESS::IsEnabled(m_pW3Context->GetTraceContext()))

View File

@ -53,9 +53,8 @@ enum APP_HOSTING_MODEL
class REQUESTHANDLER_CONFIG
{
public:
virtual
~REQUESTHANDLER_CONFIG();
~REQUESTHANDLER_CONFIG();
static
HRESULT

View File

@ -101,7 +101,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\;</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>
@ -127,7 +127,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\;</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>
@ -153,7 +153,7 @@
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\;</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>
@ -179,7 +179,7 @@
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\;</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>

View File

@ -16,7 +16,8 @@ namespace InprocessTests
{
auto server = new MockHttpServer();
auto requestHandlerConfig = MockRequestHandlerConfig::CreateConfig();
IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, requestHandlerConfig);
auto config = std::unique_ptr<REQUESTHANDLER_CONFIG>(requestHandlerConfig);
IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, std::move(config));
{
std::wstring exePath(L"hello");
app->SetParameter(L"InProcessExeLocation", exePath.c_str());
@ -24,5 +25,3 @@ namespace InprocessTests
ASSERT_STREQ(app->QueryExeLocation(), L"hello");
}
}

View File

@ -2,10 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Net;
using System.Threading.Tasks;
using IISIntegration.FunctionalTests.Utilities;
using Xunit;
using System.Net;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
@ -18,7 +18,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public async Task CheckStdoutWithRandomNumber(string path)
{
var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite");
deploymentParameters.PublishApplicationBeforeDeployment = true;
deploymentParameters.EnvironmentVariables["ASPNETCORE_INPROCESS_STARTUP_VALUE"] = path;
var randomNumberString = new Random(Guid.NewGuid().GetHashCode()).Next(10000000).ToString();
deploymentParameters.EnvironmentVariables["ASPNETCORE_INPROCESS_RANDOM_VALUE"] = randomNumberString;
@ -42,8 +41,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
public async Task CheckStdoutWithLargeWrites(string path)
{
var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite");
deploymentParameters.PublishApplicationBeforeDeployment = true;
deploymentParameters.EnvironmentVariables["ASPNETCORE_INPROCESS_STARTUP_VALUE"] = path;
var deploymentResult = await DeployAsync(deploymentParameters);
var response = await deploymentResult.RetryingHttpClient.GetAsync(path);
@ -54,5 +53,20 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
Assert.Contains(TestSink.Writes, context => context.Message.Contains(new string('a', 4096)));
}
[Fact]
public async Task Gets500_30_ErrorPage()
{
var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite");
var deploymentResult = await DeployAsync(deploymentParameters);
var response = await deploymentResult.HttpClient.GetAsync("/");
Assert.False(response.IsSuccessStatusCode);
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
var responseText = await response.Content.ReadAsStringAsync();
Assert.Contains("500.30 - ANCM In-Process Start Failure", responseText);
}
}
}

View File

@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
var deploymentParameters = new DeploymentParameters(variant)
{
ApplicationPath = Helpers.GetInProcessTestSitesPath(),
PublishApplicationBeforeDeployment = true,
PublishApplicationBeforeDeployment = true
};
var deploymentResult = await DeployAsync(deploymentParameters);

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\..\build\testsite.props" />