Skip to content

Commit

Permalink
work
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotalik committed Feb 17, 2021
1 parent 2f66d58 commit 08c642b
Show file tree
Hide file tree
Showing 33 changed files with 818 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class AppOfflineHandler: public REQUEST_HANDLER
public:
AppOfflineHandler(IHttpContext& pContext, const std::string& appOfflineContent)
: REQUEST_HANDLER(pContext),
m_pContext(pContext),
m_strAppOfflineContent(appOfflineContent)
m_pContext(pContext),
m_strAppOfflineContent(appOfflineContent)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ class ApplicationFactory
HRESULT Execute(
_In_ IHttpServer *pServer,
_In_ IHttpContext *pHttpContext,
_In_ std::wstring shadowCopyDirectory,
_Outptr_ IAPPLICATION **pApplication) const
{
// m_location.data() is const ptr copy to local to get mutable pointer
auto location = m_location;
std::array<APPLICATION_PARAMETER, 3> parameters {
std::array<APPLICATION_PARAMETER, 4> parameters {
{
{"InProcessExeLocation", location.data()},
{"TraceContext", pHttpContext->GetTraceContext()},
{"Site", pHttpContext->GetSite()}
{"Site", pHttpContext->GetSite()},
{"ShadowCopyDirectory", shadowCopyDirectory.data()}
}
};

Expand Down
10 changes: 5 additions & 5 deletions src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
Expand Down Expand Up @@ -147,7 +147,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
Expand Down Expand Up @@ -188,7 +188,7 @@
<AdditionalOptions>/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions)</AdditionalOptions>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<ResourceCompile>
Expand Down Expand Up @@ -228,7 +228,7 @@
<AdditionalOptions>/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions)</AdditionalOptions>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<ResourceCompile>
Expand Down Expand Up @@ -317,4 +317,4 @@
</ItemGroup>
<WriteLinesToFile File="$(InstallersOutputPath)aspnetcoremodule.version" Lines="@(VersionFileContents)" OverWrite="true" WriteOnlyWhenDifferent="True" />
</Target>
</Project>
</Project>
14 changes: 11 additions & 3 deletions src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ HandlerResolver::HandlerResolver(HMODULE hModule, const IHttpServer &pServer)

HRESULT
HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication,
std::filesystem::path shadowCopyPath,
const ShimOptions& pConfiguration,
std::unique_ptr<ApplicationFactory>& pApplicationFactory,
ErrorContext& errorContext)
Expand Down Expand Up @@ -62,7 +63,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
RETURN_IF_FAILED(HostFxrResolutionResult::Create(
L"",
pConfiguration.QueryProcessPath(),
pApplication.GetApplicationPhysicalPath(),
shadowCopyPath.empty() ? pApplication.GetApplicationPhysicalPath() : shadowCopyPath,
pConfiguration.QueryArguments(),
errorContext,
options));
Expand Down Expand Up @@ -125,7 +126,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
}

HRESULT
HandlerResolver::GetApplicationFactory(const IHttpApplication& pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext)
HandlerResolver::GetApplicationFactory(const IHttpApplication& pApplication, std::filesystem::path shadowCopyPath, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext)
{
SRWExclusiveLock lock(m_requestHandlerLoadLock);
if (m_loadedApplicationHostingModel != HOSTING_UNKNOWN)
Expand Down Expand Up @@ -168,7 +169,7 @@ HandlerResolver::GetApplicationFactory(const IHttpApplication& pApplication, std

m_loadedApplicationHostingModel = options.QueryHostingModel();
m_loadedApplicationId = pApplication.GetApplicationId();
RETURN_IF_FAILED(LoadRequestHandlerAssembly(pApplication, options, pApplicationFactory, errorContext));
RETURN_IF_FAILED(LoadRequestHandlerAssembly(pApplication, shadowCopyPath, options, pApplicationFactory, errorContext));

return S_OK;
}
Expand All @@ -181,6 +182,13 @@ void HandlerResolver::ResetHostingModel()
m_loadedApplicationId.resize(0);
}

APP_HOSTING_MODEL HandlerResolver::GetHostingModel()
{
SRWExclusiveLock lock(m_requestHandlerLoadLock);

return m_loadedApplicationHostingModel;
}

HRESULT
HandlerResolver::FindNativeAssemblyFromGlobalLocation(
const ShimOptions& pConfiguration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ class HandlerResolver
{
public:
HandlerResolver(HMODULE hModule, const IHttpServer &pServer);
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext);
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::filesystem::path shadowCopyPath, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext);
void ResetHostingModel();
APP_HOSTING_MODEL GetHostingModel();

private:
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory, ErrorContext& errorContext);
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, std::filesystem::path shadowCopyPath, 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,
Expand Down
14 changes: 13 additions & 1 deletion src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ShimOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include "Environment.h"

#define CS_ASPNETCORE_HANDLER_VERSION L"handlerVersion"
#define CS_ASPNETCORE_SHADOW_COPY L"enableShadowCopy"
#define CS_ASPNETCORE_SHADOW_COPY_DIRECTORY L"shadowCopyDirectory"
#define CS_ASPNETCORE_CLEAN_SHADOW_DIRECTORY_CONTENT L"cleanShadowCopyDirectory"

ShimOptions::ShimOptions(const ConfigurationSource &configurationSource) :
m_hostingModel(HOSTING_UNKNOWN),
Expand All @@ -31,12 +34,21 @@ ShimOptions::ShimOptions(const ConfigurationSource &configurationSource) :
"or hostingModel=\"outofprocess\" in the web.config file.", hostingModel.c_str()));
}

const auto handlerSettings = section->GetKeyValuePairs(CS_ASPNETCORE_HANDLER_SETTINGS);

if (m_hostingModel == HOSTING_OUT_PROCESS)
{
const auto handlerSettings = section->GetKeyValuePairs(CS_ASPNETCORE_HANDLER_SETTINGS);
m_strHandlerVersion = find_element(handlerSettings, CS_ASPNETCORE_HANDLER_VERSION).value_or(std::wstring());
}

auto enableShadowCopyElement = find_element(handlerSettings, CS_ASPNETCORE_SHADOW_COPY).value_or(std::wstring());
m_fEnableShadowCopying = equals_ignore_case(L"true", enableShadowCopyElement);

auto cleanShadowCopyDirectory = find_element(handlerSettings, CS_ASPNETCORE_CLEAN_SHADOW_DIRECTORY_CONTENT).value_or(std::wstring());
m_fCleanShadowCopyDirectory = equals_ignore_case(L"true", cleanShadowCopyDirectory);

m_strShadowCopyingDirectory = find_element(handlerSettings, CS_ASPNETCORE_SHADOW_COPY_DIRECTORY).value_or(std::wstring());

m_strProcessPath = section->GetRequiredString(CS_ASPNETCORE_PROCESS_EXE_PATH);
m_strArguments = section->GetString(CS_ASPNETCORE_PROCESS_ARGUMENTS).value_or(CS_ASPNETCORE_PROCESS_ARGUMENTS_DEFAULT);
m_fStdoutLogEnabled = section->GetRequiredBool(CS_ASPNETCORE_STDOUT_LOG_ENABLED);
Expand Down
21 changes: 21 additions & 0 deletions src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ShimOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ class ShimOptions: NonCopyable
return m_fShowDetailedErrors;
}

bool
QueryShadowCopyEnabled() const noexcept
{
return m_fEnableShadowCopying;
}

bool
QueryCleanShadowCopyDirectory() const noexcept
{
return m_fCleanShadowCopyDirectory;
}

const std::wstring&
QueryShadowCopyDirectory() const noexcept
{
return m_strShadowCopyingDirectory;
}

ShimOptions(const ConfigurationSource &configurationSource);

private:
Expand All @@ -76,4 +94,7 @@ class ShimOptions: NonCopyable
bool m_fStdoutLogEnabled;
bool m_fDisableStartupPage;
bool m_fShowDetailedErrors;
bool m_fEnableShadowCopying;
bool m_fCleanShadowCopyDirectory;
std::wstring m_strShadowCopyingDirectory;
};
107 changes: 100 additions & 7 deletions src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "applicationinfo.h"

#include "rpcdce.h"
#include "Rpc.h"
#include "proxymodule.h"
#include "HostFxrResolver.h"
#include "debugutil.h"
Expand All @@ -18,6 +20,7 @@
#include "file_utility.h"

extern HINSTANCE g_hServerModule;
extern BOOL g_fInAppOfflineShutdown;

HRESULT
APPLICATION_INFO::CreateHandler(
Expand Down Expand Up @@ -49,7 +52,6 @@ APPLICATION_INFO::CreateHandler(
while (hr != S_OK)
{
// At this point application is either null or shutdown and is returning S_FALSE

if (m_pApplication != nullptr)
{
LOG_INFO(L"Application went offline");
Expand Down Expand Up @@ -80,6 +82,20 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)

return S_OK;
}

if (g_fInAppOfflineShutdown)
{
m_pApplication = make_application<ServerErrorApplication>(
pHttpApplication,
E_FAIL,
false /* disableStartupPage */,
"" /* responseContent */,
503i16 /* statusCode */,
0i16 /* subStatusCode */,
"Application Shutting Down");
return S_OK;
}

try
{
const WebConfigConfigurationSource configurationSource(m_pServer.GetAdminManager(), pHttpApplication);
Expand All @@ -93,6 +109,7 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)

if (FAILED_LOG(hr))
{
OBSERVE_CAUGHT_EXCEPTION();
EventLog::Error(
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR,
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG,
Expand Down Expand Up @@ -175,13 +192,16 @@ APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOpt
}
}

RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(*pHttpContext.GetApplication(), m_pApplicationFactory, options, error));
std::filesystem::path shadowCopyPath = HandleShadowCopy(options, pHttpContext);

RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(*pHttpContext.GetApplication(), shadowCopyPath, m_pApplicationFactory, options, error));
LOG_INFO(L"Creating handler application");

IAPPLICATION * newApplication;
RETURN_IF_FAILED(m_pApplicationFactory->Execute(
&m_pServer,
&pHttpContext,
shadowCopyPath,
&newApplication));

m_pApplication.reset(newApplication);
Expand All @@ -206,19 +226,92 @@ APPLICATION_INFO::TryCreateHandler(
return S_OK;
}
}

return S_FALSE;
}

VOID
APPLICATION_INFO::ShutDownApplication(const bool fServerInitiated)
{
IAPPLICATION* app = nullptr;
{
SRWExclusiveLock lock(m_applicationLock);
if (!m_pApplication)
{
return;
}
app = m_pApplication.get();
}

LOG_INFOF(L"Stopping application '%ls'", QueryApplicationInfoKey().c_str());
app->Stop(fServerInitiated);
LOG_INFO(L"Setting app to null");

SRWExclusiveLock lock(m_applicationLock);
LOG_INFO(L"lock acquired");

m_pApplication = nullptr;
m_pApplicationFactory = nullptr;
}

if (m_pApplication)
std::wstring
APPLICATION_INFO::HandleShadowCopy(const ShimOptions& options, IHttpContext& pHttpContext)
{
std::filesystem::path shadowCopyPath;

if (options.QueryShadowCopyEnabled())
{
LOG_INFOF(L"Stopping application '%ls'", QueryApplicationInfoKey().c_str());
m_pApplication->Stop(fServerInitiated);
m_pApplication = nullptr;
m_pApplicationFactory = nullptr;
shadowCopyPath = options.QueryShadowCopyDirectory();
std::wstring physicalPath = pHttpContext.GetApplication()->GetApplicationPhysicalPath();

// Make shadow copy path absolute.
if (!shadowCopyPath.is_absolute())
{
shadowCopyPath = std::filesystem::absolute(std::filesystem::path(physicalPath) / shadowCopyPath);
}

// The shadow copy directory itself isn't copied to directly.
// Instead subdirectories with numerically increasing names are created.
// This is because on shutdown, the app itself will still have all dlls loaded,
// meaning we can't copy to the same subdirectory. Therefore, on shutdown,
// we create a directory that is one larger than the previous largest directory number.
auto directoryName = 0;
std::string directoryNameStr = "0";
auto shadowCopyBaseDirectory = std::filesystem::directory_entry(shadowCopyPath);
if (!shadowCopyBaseDirectory.exists())
{
CreateDirectory(shadowCopyBaseDirectory.path().wstring().c_str(), NULL);
}

for (auto& entry : std::filesystem::directory_iterator(shadowCopyPath))
{
if (entry.is_directory())
{
try
{
std::string::size_type size;
int intFileName = std::stoi(entry.path().filename().string(), &size);
if (intFileName > directoryName)
{
directoryName = intFileName;
directoryNameStr = std::string(entry.path().string());
}
}
catch (...)
{
OBSERVE_CAUGHT_EXCEPTION();
// Ignore any folders that can't be converted to an int.
}
}
}

shadowCopyPath = shadowCopyPath / std::filesystem::path(directoryNameStr);
HRESULT hr = Environment::CopyToDirectory(physicalPath, shadowCopyPath, options.QueryCleanShadowCopyDirectory(), shadowCopyBaseDirectory.path().parent_path());
if (hr != S_OK)
{
return std::wstring();
}
}

return shadowCopyPath;
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class APPLICATION_INFO: NonCopyable
return false;
}


private:

HRESULT
Expand All @@ -79,6 +80,9 @@ class APPLICATION_INFO: NonCopyable
HRESULT
TryCreateApplication(IHttpContext& pHttpContext, const ShimOptions& options, ErrorContext& error);

std::wstring
HandleShadowCopy(const ShimOptions& options, IHttpContext& pHttpContext);

IHttpServer &m_pServer;
HandlerResolver &m_handlerResolver;

Expand Down
Loading

0 comments on commit 08c642b

Please sign in to comment.