aspnetcore/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp

174 lines
4.5 KiB
C++

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "proxymodule.h"
#include "applicationmanager.h"
#include "applicationinfo.h"
#include "exceptions.h"
#include "DisconnectHandler.h"
extern BOOL g_fInShutdown;
__override
ASPNET_CORE_PROXY_MODULE_FACTORY::ASPNET_CORE_PROXY_MODULE_FACTORY(HTTP_MODULE_ID moduleId, std::shared_ptr<APPLICATION_MANAGER> applicationManager) noexcept
: m_pApplicationManager(std::move(applicationManager)),
m_moduleId(moduleId)
{
}
HRESULT
ASPNET_CORE_PROXY_MODULE_FACTORY::GetHttpModule(
CHttpModule ** ppModule,
IModuleAllocator * pAllocator
)
{
#pragma warning( push )
#pragma warning ( disable : 26409 ) // Disable "Avoid using new"
*ppModule = new (pAllocator) ASPNET_CORE_PROXY_MODULE(m_moduleId, m_pApplicationManager);
#pragma warning( push )
if (*ppModule == nullptr)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
__override
VOID
ASPNET_CORE_PROXY_MODULE_FACTORY::Terminate(
VOID
) noexcept
/*++
Routine description:
Function called by IIS for global (non-request-specific) notifications
Arguments:
None.
Return value:
None
--*/
{
delete this;
}
ASPNET_CORE_PROXY_MODULE::ASPNET_CORE_PROXY_MODULE(HTTP_MODULE_ID moduleId, std::shared_ptr<APPLICATION_MANAGER> applicationManager) noexcept
: m_pApplicationManager(std::move(applicationManager)),
m_pApplicationInfo(nullptr),
m_pHandler(nullptr),
m_moduleId(moduleId),
m_pDisconnectHandler(nullptr)
{
}
ASPNET_CORE_PROXY_MODULE::~ASPNET_CORE_PROXY_MODULE()
{
if (m_pDisconnectHandler != nullptr)
{
m_pDisconnectHandler->SetHandler(nullptr);
}
}
__override
REQUEST_NOTIFICATION_STATUS
ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
IHttpContext * pHttpContext,
IHttpEventProvider *
)
{
HRESULT hr = S_OK;
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
try
{
if (g_fInShutdown)
{
FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS));
}
auto moduleContainer = pHttpContext
->GetConnection()
->GetModuleContextContainer();
#pragma warning( push )
#pragma warning ( disable : 26466 ) // Disable "Don't use static_cast downcasts". We build without RTTI support so dynamic_cast is not available
m_pDisconnectHandler = static_cast<DisconnectHandler*>(moduleContainer->GetConnectionModuleContext(m_moduleId));
#pragma warning( push )
if (m_pDisconnectHandler == nullptr)
{
auto disconnectHandler = std::make_unique<DisconnectHandler>();
m_pDisconnectHandler = disconnectHandler.get();
// ModuleContextContainer takes ownership of disconnectHandler
// we are trusting that it would not release it before deleting the context
FINISHED_IF_FAILED(moduleContainer->SetConnectionModuleContext(static_cast<IHttpConnectionStoredContext*>(disconnectHandler.release()), m_moduleId));
}
m_pDisconnectHandler->SetHandler(this);
FINISHED_IF_FAILED(m_pApplicationManager->GetOrCreateApplicationInfo(
*pHttpContext,
m_pApplicationInfo));
FINISHED_IF_FAILED(m_pApplicationInfo->CreateHandler(*pHttpContext, m_pHandler));
retVal = m_pHandler->OnExecuteRequestHandler();
}
catch (...)
{
hr = OBSERVE_CAUGHT_EXCEPTION();
}
Finished:
if (FAILED(LOG_IF_FAILED(hr)))
{
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
if (hr == HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS))
{
pHttpContext->GetResponse()->SetStatus(503, "Service Unavailable", 0, hr);
}
else
{
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
}
}
return retVal;
}
__override
REQUEST_NOTIFICATION_STATUS
ASPNET_CORE_PROXY_MODULE::OnAsyncCompletion(
IHttpContext *,
DWORD,
BOOL,
IHttpEventProvider *,
IHttpCompletionInfo * pCompletionInfo
)
{
try
{
return m_pHandler->OnAsyncCompletion(
pCompletionInfo->GetCompletionBytes(),
pCompletionInfo->GetCompletionStatus());
}
catch (...)
{
OBSERVE_CAUGHT_EXCEPTION();
return RQ_NOTIFICATION_FINISH_REQUEST;
}
}
void ASPNET_CORE_PROXY_MODULE::NotifyDisconnect() const
{
m_pHandler->NotifyDisconnect();
}