Split config and hostfxr parsing between shim and request handler. (#814)

This commit is contained in:
Justin Kotalik 2018-05-16 16:45:18 -07:00 committed by GitHub
parent 63c00b3c68
commit f72d366603
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 919 additions and 506 deletions

View File

@ -9,11 +9,11 @@
</handlers>
<!-- This set of attributes are used for launching the sample using IISExpress via Visual Studio tooling -->
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
<!-- This set of attributes are used for launching the sample for full CLR (net46) without Visual Studio tooling
<aspNetCore processPath=".\IISSample.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
-->
<!-- This set of attributes are used for launching the sample for Core CLR (netcoreapp2.0) without Visual Studio tooling
<aspNetCore processPath="dotnet" arguments=".\IISSample.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
-->

View File

@ -82,7 +82,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\IISLib;inc;..\CommonLib</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
@ -115,7 +115,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\IISLib;inc;..\CommonLib</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
@ -148,7 +148,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\IISLib;inc;..\CommonLib</AdditionalIncludeDirectories>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
@ -184,7 +184,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\IISLib;inc;..\CommonLib</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
@ -213,6 +213,7 @@
<ItemGroup>
<ClInclude Include="Inc\applicationinfo.h" />
<ClInclude Include="Inc\appoffline.h" />
<ClInclude Include="Inc\aspnetcore_shim_config.h" />
<ClInclude Include="inc\globalmodule.h" />
<ClInclude Include="Inc\applicationmanager.h" />
<ClInclude Include="Inc\filewatcher.h" />
@ -222,6 +223,7 @@
<ItemGroup>
<ClCompile Include="Src\applicationinfo.cpp" />
<ClCompile Include="Src\applicationmanager.cxx" />
<ClCompile Include="src\aspnetcore_shim_config.cpp" />
<ClCompile Include="Src\dllmain.cpp" />
<ClCompile Include="Src\filewatcher.cxx" />
<ClCompile Include="src\globalmodule.cpp" />

View File

@ -9,9 +9,10 @@ extern BOOL g_fRecycleProcessCalled;
typedef
HRESULT
(WINAPI * PFN_ASPNETCORE_CREATE_APPLICATION)(
_In_ IHttpServer *pServer,
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ IAPPLICATION **pApplication
_In_ IHttpServer *pServer,
_In_ IHttpContext *pHttpContext,
_In_ PCWSTR pwzExeLocation, // TODO remove both pwzExeLocation and pHttpContext from this api
_Out_ IAPPLICATION **pApplication
);
//
@ -79,7 +80,7 @@ public:
HRESULT
Initialize(
_In_ ASPNETCORE_CONFIG *pConfiguration,
_In_ ASPNETCORE_SHIM_CONFIG *pConfiguration,
_In_ FILE_WATCHER *pFileWatcher
);
@ -115,7 +116,7 @@ public:
HRESULT
StartMonitoringAppOffline();
ASPNETCORE_CONFIG*
ASPNETCORE_SHIM_CONFIG*
QueryConfig()
{
return m_pConfiguration;
@ -145,7 +146,10 @@ public:
ShutDownApplication();
HRESULT
EnsureApplicationCreated();
EnsureApplicationCreated(
IHttpContext *pHttpContext,
STRU* exeLocation
);
private:
HRESULT FindRequestHandlerAssembly();
@ -159,8 +163,8 @@ private:
BOOL m_fAppOfflineFound;
APP_OFFLINE_HTM *m_pAppOfflineHtm;
FILE_WATCHER_ENTRY *m_pFileWatcherEntry;
ASPNETCORE_CONFIG *m_pConfiguration;
IAPPLICATION *m_pApplication;
ASPNETCORE_SHIM_CONFIG *m_pConfiguration;
IAPPLICATION *m_pApplication;
SRWLOCK m_srwLock;
IHttpServer *m_pServer;
PFN_ASPNETCORE_CREATE_APPLICATION m_pfnAspNetCoreCreateApplication;

View File

@ -65,7 +65,7 @@ public:
HRESULT
GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ ASPNETCORE_CONFIG* pConfig,
_In_ ASPNETCORE_SHIM_CONFIG* pConfig,
_Out_ APPLICATION_INFO ** ppApplicationInfo
);

View File

@ -0,0 +1,176 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#define CS_ASPNETCORE_SECTION L"system.webServer/aspNetCore"
#define CS_ASPNETCORE_PROCESS_EXE_PATH L"processPath"
#define CS_ASPNETCORE_PROCESS_ARGUMENTS L"arguments"
#define CS_ASPNETCORE_HOSTING_MODEL L"hostingModel"
enum APP_HOSTING_MODEL
{
HOSTING_UNKNOWN = 0,
HOSTING_IN_PROCESS,
HOSTING_OUT_PROCESS
};
class ASPNETCORE_SHIM_CONFIG : IHttpStoredContext
{
public:
virtual
~ASPNETCORE_SHIM_CONFIG();
static
HRESULT
GetConfig(
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpApplication *pHttpApplication,
_In_ HANDLE hEventLog,
_Out_ STRU *pcwzExePath,
_Out_ ASPNETCORE_SHIM_CONFIG **ppAspNetCoreConfig
);
HRESULT
Populate(
IHttpServer *pHttpServer,
IHttpApplication *pHttpContext
);
VOID
ReferenceConfiguration(
VOID
) const;
VOID
DereferenceConfiguration(
VOID
) const;
VOID
CleanupStoredContext(
VOID
)
{
DereferenceConfiguration();
}
STRU*
QueryApplicationPhysicalPath(
VOID
)
{
return &m_struApplicationPhysicalPath;
}
STRU*
QueryApplicationPath(
VOID
)
{
return &m_struApplication;
}
CONST
PCWSTR*
QueryHostFxrArguments(
VOID
)
{
return m_ppStrArguments;
}
CONST
DWORD
QueryHostFxrArgCount(
VOID
)
{
return m_dwArgc;
}
STRU*
QueryConfigPath(
VOID
)
{
return &m_struConfigPath;
}
STRU*
QueryProcessPath(
VOID
)
{
return &m_struProcessPath;
}
STRU*
QueryArguments(
VOID
)
{
return &m_struArguments;
}
HRESULT
SetHostFxrFullPath(
PCWSTR pStrHostFxrFullPath
)
{
return m_struHostFxrLocation.Copy(pStrHostFxrFullPath);
}
APP_HOSTING_MODEL
QueryHostingModel(
VOID
)
{
return m_hostingModel;
}
CONST
PCWSTR
QueryHostFxrFullPath(
VOID
)
{
return m_struHostFxrLocation.QueryStr();
}
VOID
SetHostFxrArguments(
DWORD dwArgc,
PWSTR* ppStrArguments
)
{
if (m_ppStrArguments != NULL)
{
delete[] m_ppStrArguments;
}
m_dwArgc = dwArgc;
m_ppStrArguments = ppStrArguments;
}
private:
ASPNETCORE_SHIM_CONFIG() :
m_cRefs(1),
m_hostingModel(HOSTING_UNKNOWN),
m_ppStrArguments(NULL)
{
}
mutable LONG m_cRefs;
STRU m_struArguments;
STRU m_struProcessPath;
STRU m_struApplication;
STRU m_struApplicationPhysicalPath;
STRU m_struConfigPath;
APP_HOSTING_MODEL m_hostingModel;
STRU m_struHostFxrLocation;
PWSTR* m_ppStrArguments;
DWORD m_dwArgc;
};

View File

@ -1,49 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#ifndef __FX_VER_H__
#define __FX_VER_H__
#include <string>
// Note: This is not SemVer (esp., in comparing pre-release part, fx_ver_t does not
// compare multiple dot separated identifiers individually.) ex: 1.0.0-beta.2 vs. 1.0.0-beta.11
struct fx_ver_t
{
fx_ver_t(int major, int minor, int patch);
fx_ver_t(int major, int minor, int patch, const std::wstring& pre);
fx_ver_t(int major, int minor, int patch, const std::wstring& pre, const std::wstring& build);
int get_major() const { return m_major; }
int get_minor() const { return m_minor; }
int get_patch() const { return m_patch; }
void set_major(int m) { m_major = m; }
void set_minor(int m) { m_minor = m; }
void set_patch(int p) { m_patch = p; }
bool is_prerelease() const { return !m_pre.empty(); }
std::wstring as_str() const;
std::wstring prerelease_glob() const;
std::wstring patch_glob() const;
bool operator ==(const fx_ver_t& b) const;
bool operator !=(const fx_ver_t& b) const;
bool operator <(const fx_ver_t& b) const;
bool operator >(const fx_ver_t& b) const;
bool operator <=(const fx_ver_t& b) const;
bool operator >=(const fx_ver_t& b) const;
static bool parse(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production = false);
private:
int m_major;
int m_minor;
int m_patch;
std::wstring m_pre;
std::wstring m_build;
static int compare(const fx_ver_t&a, const fx_ver_t& b);
};
#endif // __FX_VER_H__

View File

@ -42,8 +42,8 @@ APPLICATION_INFO::~APPLICATION_INFO()
HRESULT
APPLICATION_INFO::Initialize(
_In_ ASPNETCORE_CONFIG *pConfiguration,
_In_ FILE_WATCHER *pFileWatcher
_In_ ASPNETCORE_SHIM_CONFIG *pConfiguration,
_In_ FILE_WATCHER *pFileWatcher
)
{
HRESULT hr = S_OK;
@ -177,11 +177,14 @@ APPLICATION_INFO::UpdateAppOfflineFileHandle()
}
HRESULT
APPLICATION_INFO::EnsureApplicationCreated()
APPLICATION_INFO::EnsureApplicationCreated(
IHttpContext *pHttpContext,
STRU* struExeLocation
)
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
IAPPLICATION* pApplication = NULL;
IAPPLICATION *pApplication = NULL;
STACK_STRU(struFileName, 300); // >MAX_PATH
STRU struHostFxrDllLocation;
@ -222,11 +225,8 @@ APPLICATION_INFO::EnsureApplicationCreated()
goto Finished;
}
hr = m_pfnAspNetCoreCreateApplication(m_pServer, m_pConfiguration, &pApplication);
if (FAILED(hr))
{
goto Finished;
}
hr = m_pfnAspNetCoreCreateApplication(m_pServer, pHttpContext, struExeLocation->QueryStr(), &pApplication);
m_pApplication = pApplication;
}
}
@ -314,6 +314,7 @@ APPLICATION_INFO::FindRequestHandlerAssembly()
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_fAspnetcoreRHAssemblyLoaded = TRUE;
}
@ -323,6 +324,7 @@ Finished:
// User needs to check whether the fuction pointer is NULL
//
m_pfnAspNetCoreCreateApplication = g_pfnAspNetCoreCreateApplication;
if (!g_fAspnetcoreRHLoadedError && FAILED(hr))
{
g_fAspnetcoreRHLoadedError = TRUE;

View File

@ -13,7 +13,7 @@ APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
HRESULT
APPLICATION_MANAGER::GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ ASPNETCORE_CONFIG* pConfig,
_In_ ASPNETCORE_SHIM_CONFIG* pConfig,
_Out_ APPLICATION_INFO ** ppApplicationInfo
)
{

View File

@ -0,0 +1,240 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
ASPNETCORE_SHIM_CONFIG::~ASPNETCORE_SHIM_CONFIG()
{
if (m_ppStrArguments != NULL)
{
delete[] m_ppStrArguments;
m_ppStrArguments = NULL;
}
}
VOID
ASPNETCORE_SHIM_CONFIG::ReferenceConfiguration(
VOID
) const
{
InterlockedIncrement(&m_cRefs);
}
VOID
ASPNETCORE_SHIM_CONFIG::DereferenceConfiguration(
VOID
) const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
delete this;
}
}
HRESULT
ASPNETCORE_SHIM_CONFIG::GetConfig(
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpApplication *pHttpApplication,
_In_ HANDLE hEventLog,
_Out_ STRU *struExeLocation,
_Out_ ASPNETCORE_SHIM_CONFIG **ppAspNetCoreShimConfig
)
{
HRESULT hr = S_OK;
ASPNETCORE_SHIM_CONFIG *pAspNetCoreShimConfig = NULL;
STRU struHostFxrDllLocation;
STRU struExeAbsolutePath;
BSTR* pwzArgv;
DWORD dwArgCount;
if (ppAspNetCoreShimConfig == NULL)
{
hr = E_INVALIDARG;
goto Finished;
}
*ppAspNetCoreShimConfig = NULL;
// potential bug if user sepcific config at virtual dir level
pAspNetCoreShimConfig = (ASPNETCORE_SHIM_CONFIG*)
pHttpApplication->GetModuleContextContainer()->GetModuleContext(pModuleId);
if (pAspNetCoreShimConfig != NULL)
{
*ppAspNetCoreShimConfig = pAspNetCoreShimConfig;
pAspNetCoreShimConfig = NULL;
goto Finished;
}
pAspNetCoreShimConfig = new ASPNETCORE_SHIM_CONFIG;
if (pAspNetCoreShimConfig == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAspNetCoreShimConfig->Populate(pHttpServer, pHttpApplication);
if (FAILED(hr))
{
goto Finished;
}
// Modify Inprocess specific configuration here.
if (pAspNetCoreShimConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
if (FAILED(hr = HOSTFXR_UTILITY::GetHostFxrParameters(
hEventLog,
pAspNetCoreShimConfig->QueryProcessPath()->QueryStr(),
pAspNetCoreShimConfig->QueryApplicationPhysicalPath()->QueryStr(),
pAspNetCoreShimConfig->QueryArguments()->QueryStr(),
&struHostFxrDllLocation,
&struExeAbsolutePath,
&dwArgCount,
&pwzArgv)))
{
goto Finished;
}
if (FAILED(hr = pAspNetCoreShimConfig->SetHostFxrFullPath(struHostFxrDllLocation.QueryStr())))
{
goto Finished;
}
pAspNetCoreShimConfig->SetHostFxrArguments(dwArgCount, pwzArgv);
struExeLocation->Copy(struExeAbsolutePath);
}
hr = pHttpApplication->GetModuleContextContainer()->
SetModuleContext(pAspNetCoreShimConfig, pModuleId);
if (FAILED(hr))
{
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
{
delete pAspNetCoreShimConfig;
pAspNetCoreShimConfig = (ASPNETCORE_SHIM_CONFIG*)pHttpApplication->
GetModuleContextContainer()->
GetModuleContext(pModuleId);
_ASSERT(pAspNetCoreShimConfig != NULL);
hr = S_OK;
}
else
{
goto Finished;
}
}
else
{
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"ASPNETCORE_SHIM_CONFIG::GetConfig, set config to ModuleContext");
}
*ppAspNetCoreShimConfig = pAspNetCoreShimConfig;
pAspNetCoreShimConfig = NULL;
Finished:
if (pAspNetCoreShimConfig != NULL)
{
delete pAspNetCoreShimConfig;
pAspNetCoreShimConfig = NULL;
}
return hr;
}
HRESULT
ASPNETCORE_SHIM_CONFIG::Populate(
IHttpServer *pHttpServer,
IHttpApplication *pHttpApplication
)
{
STACK_STRU(strHostingModel, 300);
HRESULT hr = S_OK;
STRU strApplicationFullPath;
IAppHostAdminManager *pAdminManager = NULL;
IAppHostElement *pAspNetCoreElement = NULL;
BSTR bstrAspNetCoreSection = NULL;
pAdminManager = pHttpServer->GetAdminManager();
hr = m_struConfigPath.Copy(pHttpApplication->GetAppConfigPath());
if (FAILED(hr))
{
goto Finished;
}
hr = m_struApplicationPhysicalPath.Copy(pHttpApplication->GetApplicationPhysicalPath());
if (FAILED(hr))
{
goto Finished;
}
bstrAspNetCoreSection = SysAllocString(CS_ASPNETCORE_SECTION);
hr = pAdminManager->GetAdminSection(bstrAspNetCoreSection,
m_struConfigPath.QueryStr(),
&pAspNetCoreElement);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_EXE_PATH,
&m_struProcessPath);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_HOSTING_MODEL,
&strHostingModel);
if (FAILED(hr))
{
// Swallow this error for backward compatability
// Use default behavior for empty string
hr = S_OK;
}
if (strHostingModel.IsEmpty() || strHostingModel.Equals(L"outofprocess", TRUE))
{
m_hostingModel = HOSTING_OUT_PROCESS;
}
else if (strHostingModel.Equals(L"inprocess", TRUE))
{
m_hostingModel = HOSTING_IN_PROCESS;
}
else
{
// block unknown hosting value
hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
goto Finished;
}
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_ARGUMENTS,
&m_struArguments);
if (FAILED(hr))
{
goto Finished;
}
Finished:
if (pAspNetCoreElement != NULL)
{
pAspNetCoreElement->Release();
pAspNetCoreElement = NULL;
}
return hr;
}

View File

@ -101,16 +101,17 @@ inline bool IsSpace(char ch)
#include <acache.h>
#include <time.h>
#include "..\..\CommonLib\environmentvariablehash.h"
#include "..\..\CommonLib\aspnetcoreconfig.h"
#include "..\..\CommonLib\hostfxr_utility.h"
#include "..\..\CommonLib\iapplication.h"
#include "..\..\CommonLib\utility.h"
#include "..\..\CommonLib\debugutil.h"
#include "..\..\CommonLib\requesthandler.h"
#include "..\..\CommonLib\resources.h"
#include "..\..\CommonLib\aspnetcore_msg.h"
#include "environmentvariablehash.h"
#include "hostfxr_utility.h"
#include "utility.h"
#include "debugutil.h"
#include "requesthandler.h"
#include "resources.h"
#include "aspnetcore_msg.h"
//#include "aspnetcore_event.h"
#include "aspnetcore_shim_config.h"
#include "fx_ver.h"
#include "appoffline.h"
#include "filewatcher.h"
#include "applicationinfo.h"

View File

@ -46,7 +46,6 @@ Return value:
WEBSOCKET_HANDLER::StaticTerminate();*/
ALLOC_CACHE_HANDLER::StaticTerminate();
delete this;
}
@ -78,18 +77,20 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
)
{
HRESULT hr = S_OK;
ASPNETCORE_CONFIG *pConfig = NULL;
ASPNETCORE_SHIM_CONFIG *pConfig = NULL;
APPLICATION_MANAGER *pApplicationManager = NULL;
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
IAPPLICATION* pApplication = NULL;
STRU struExeLocation;
STACK_STRU(struFileName, 256);
if (g_fInShutdown)
{
hr = HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS);
goto Finished;
}
hr = ASPNETCORE_CONFIG::GetConfig(g_pHttpServer, g_pModuleId, pHttpContext, g_hEventLog, &pConfig);
hr = ASPNETCORE_SHIM_CONFIG::GetConfig(g_pHttpServer, g_pModuleId, pHttpContext->GetApplication(), g_hEventLog, &struExeLocation, &pConfig);
if (FAILED(hr))
{
goto Finished;
@ -143,7 +144,7 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
}
// make sure assmebly is loaded and application is created
hr = m_pApplicationInfo->EnsureApplicationCreated();
hr = m_pApplicationInfo->EnsureApplicationCreated(pHttpContext, &struExeLocation);
if (FAILED(hr))
{
goto Finished;
@ -163,7 +164,6 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
// Create RequestHandler and process the request
hr = pApplication->CreateHandler(pHttpContext,
(HTTP_MODULE_ID*) &g_pModuleId,
&m_pHandler);
if (FAILED(hr))

View File

@ -95,6 +95,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\iislib;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -114,6 +115,7 @@
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
<AdditionalIncludeDirectories>..\iislib;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -133,6 +135,7 @@
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
<AdditionalIncludeDirectories>..\iislib;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -152,8 +155,7 @@
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\iislib;</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -171,13 +173,12 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="application.h" />
<ClInclude Include="fx_ver.h" />
<ClInclude Include="hostfxr_utility.h" />
<ClInclude Include="iapplication.h" />
<ClInclude Include="aspnetcoreconfig.h" />
<ClInclude Include="debugutil.h" />
<ClInclude Include="disconnectcontext.h" />
<ClInclude Include="environmentvariablehash.h" />
<ClInclude Include="fx_ver.h" />
<ClInclude Include="hostfxr_utility.h" />
<ClInclude Include="irequesthandler.h" />
<ClInclude Include="requesthandler.h" />
<ClInclude Include="resources.h" />
@ -186,7 +187,6 @@
<ClInclude Include="utility.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="aspnetcoreconfig.cxx" />
<ClCompile Include="fx_ver.cxx" />
<ClCompile Include="hostfxr_utility.cpp" />
<ClCompile Include="SRWLockWrapper.cpp" />

View File

@ -43,4 +43,3 @@ private:
static int compare(const fx_ver_t&a, const fx_ver_t& b);
};

View File

@ -26,12 +26,12 @@ HOSTFXR_UTILITY::~HOSTFXR_UTILITY()
HRESULT
HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
PCWSTR pwzExeAbsolutePath, // includes .exe file extension.
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
HANDLE hEventLog,
_Inout_ STRU* struHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ PWSTR** ppwzArgv
_Inout_ STRU* pStruHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
)
{
HRESULT hr = S_OK;
@ -42,36 +42,36 @@ HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
DWORD dwPosition;
// Obtain the app name from the processPath section.
if ( FAILED( hr = struDllPath.Copy( pwzExeAbsolutePath ) ) )
if (FAILED(hr = struDllPath.Copy(pwzExeAbsolutePath)))
{
goto Finished;
}
dwPosition = struDllPath.LastIndexOf( L'.', 0 );
if ( dwPosition == -1 )
dwPosition = struDllPath.LastIndexOf(L'.', 0);
if (dwPosition == -1)
{
hr = E_FAIL;
goto Finished;
}
hr = UTILITY::ConvertPathToFullPath( L".\\hostfxr.dll", pcwzApplicationPhysicalPath, &struHostFxrPath );
if ( FAILED( hr ) )
hr = UTILITY::ConvertPathToFullPath(L".\\hostfxr.dll", pcwzApplicationPhysicalPath, &struHostFxrPath);
if (FAILED(hr))
{
goto Finished;
}
struDllPath.QueryStr()[dwPosition] = L'\0';
if (FAILED(hr = struDllPath.SyncWithBuffer()))
{
goto Finished;
}
struDllPath.QueryStr()[dwPosition] = L'\0';
if (FAILED(hr = struDllPath.SyncWithBuffer()))
{
goto Finished;
}
if ( !UTILITY::CheckIfFileExists( struHostFxrPath.QueryStr() ) )
if (!UTILITY::CheckIfFileExists(struHostFxrPath.QueryStr()))
{
// Most likely a full framework app.
// Check that the runtime config file doesn't exist in the folder as another heuristic.
if (FAILED(hr = struRuntimeConfigLocation.Copy(struDllPath)) ||
FAILED(hr = struRuntimeConfigLocation.Append( L".runtimeconfig.json" )))
FAILED(hr = struRuntimeConfigLocation.Append(L".runtimeconfig.json")))
{
goto Finished;
}
@ -80,28 +80,28 @@ HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP,
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP_MSG,
pcwzApplicationPhysicalPath,
hr);
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP,
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP_MSG,
pcwzApplicationPhysicalPath,
hr);
}
else
{
// If a runtime config file does exist, report a file not found on the app.exe
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND,
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_MSG,
pcwzApplicationPhysicalPath,
hr);
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND,
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_MSG,
pcwzApplicationPhysicalPath,
hr);
}
goto Finished;
}
if (FAILED(hr = struHostFxrDllLocation->Copy(struHostFxrPath)))
if (FAILED(hr = pStruHostFxrDllLocation->Copy(struHostFxrPath)))
{
goto Finished;
}
@ -142,15 +142,26 @@ Finished:
return hr;
}
BOOL
HOSTFXR_UTILITY::IsDotnetExecutable(STRU *struExecutablePath)
{
if (struExecutablePath == NULL)
{
return FALSE;
}
return struExecutablePath->EndsWith(L"dotnet.exe") || struExecutablePath->EndsWith(L"dotnet");
}
HRESULT
HOSTFXR_UTILITY::GetHostFxrParameters(
HANDLE hEventLog,
PCWSTR pcwzProcessPath,
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
_Inout_ STRU* struHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** pbstrArgv
_In_ HANDLE hEventLog,
_In_ PCWSTR pcwzProcessPath,
_In_ PCWSTR pcwzApplicationPhysicalPath,
_In_ PCWSTR pcwzArguments,
_Inout_ STRU *pStruHostFxrDllLocation,
_Inout_ STRU *pStruExeAbsolutePath,
_Out_ DWORD *pdwArgCount,
_Out_ BSTR **pbstrArgv
)
{
HRESULT hr = S_OK;
@ -182,7 +193,7 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
}
// Check if the absolute path is to dotnet or not.
if (struAbsolutePathToDotnet.EndsWith(L"dotnet.exe") || struAbsolutePathToDotnet.EndsWith(L"dotnet"))
if (HOSTFXR_UTILITY::IsDotnetExecutable(&struAbsolutePathToDotnet))
{
//
// The processPath ends with dotnet.exe or dotnet
@ -199,7 +210,7 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
goto Finished;
}
if (FAILED(hr = ParseHostfxrArguments(
if (FAILED(hr = HOSTFXR_UTILITY::ParseHostfxrArguments(
struExpandedArguments.QueryStr(),
struAbsolutePathToDotnet.QueryStr(),
pcwzApplicationPhysicalPath,
@ -210,10 +221,14 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
goto Finished;
}
if (FAILED(hr = struHostFxrDllLocation->Copy(struAbsolutePathToHostFxr)))
if (FAILED(hr = pStruHostFxrDllLocation->Copy(struAbsolutePathToHostFxr)))
{
goto Finished;
}
if (FAILED(hr = pStruExeAbsolutePath->Copy(struAbsolutePathToDotnet))) {
goto Finished;
}
}
else
{
@ -224,14 +239,22 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
//
if (UTILITY::CheckIfFileExists(struAbsolutePathToDotnet.QueryStr()))
{
hr = GetStandaloneHostfxrParameters(
hr = HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
struAbsolutePathToDotnet.QueryStr(),
pcwzApplicationPhysicalPath,
struExpandedArguments.QueryStr(),
hEventLog,
struHostFxrDllLocation,
pStruHostFxrDllLocation,
pdwArgCount,
pbstrArgv);
if (FAILED(hr))
{
goto Finished;
}
if (FAILED(hr = pStruExeAbsolutePath->Copy(struAbsolutePathToDotnet))) {
goto Finished;
}
}
else
{
@ -272,10 +295,10 @@ HOSTFXR_UTILITY::ParseHostfxrArguments(
_Out_ BSTR** pbstrArgv
)
{
UNREFERENCED_PARAMETER( hEventLog ); // TODO use event log to set errors.
UNREFERENCED_PARAMETER(hEventLog); // TODO use event log to set errors.
DBG_ASSERT(dwArgCount != NULL);
DBG_ASSERT(pwzArgv != NULL);
DBG_ASSERT(dwArgCount != NULL);
DBG_ASSERT(pwzArgv != NULL);
HRESULT hr = S_OK;
INT argc = 0;
@ -484,7 +507,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
}
// As we use the logic from core-setup, we are opting to use std here.
UTILITY::FindDotNetFolders(struHostFxrSearchExpression.QueryStr(), &vVersionFolders);
HOSTFXR_UTILITY::FindDotNetFolders(struHostFxrSearchExpression.QueryStr(), &vVersionFolders);
if (vVersionFolders.size() == 0)
{
@ -498,7 +521,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
goto Finished;
}
hr = UTILITY::FindHighestDotNetVersion(vVersionFolders, &struHighestDotnetVersion);
hr = FindHighestDotNetVersion(vVersionFolders, &struHighestDotnetVersion);
if (FAILED(hr))
{
goto Finished;
@ -805,3 +828,51 @@ HOSTFXR_UTILITY::GetAbsolutePathToDotnetFromProgramFiles(
Finished:
return hr;
}
HRESULT
HOSTFXR_UTILITY::FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
)
{
HRESULT hr = S_OK;
fx_ver_t max_ver(-1, -1, -1);
for (const auto& dir : vFolders)
{
fx_ver_t fx_ver(-1, -1, -1);
if (fx_ver_t::parse(dir, &fx_ver, false))
{
// TODO using max instead of std::max works
max_ver = max(max_ver, fx_ver);
}
}
hr = pstrResult->Copy(max_ver.as_str().c_str());
// we check FAILED(hr) outside of function
return hr;
}
VOID
HOSTFXR_UTILITY::FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
)
{
HANDLE handle = NULL;
WIN32_FIND_DATAW data = { 0 };
handle = FindFirstFileExW(pszPath, FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0);
if (handle == INVALID_HANDLE_VALUE)
{
return;
}
do
{
std::wstring folder(data.cFileName);
pvFolders->push_back(folder);
} while (FindNextFileW(handle, &data));
FindClose(handle);
}

View File

@ -11,20 +11,6 @@ typedef INT(*hostfxr_main_fn) (CONST DWORD argc, CONST PCWSTR argv[]);
class HOSTFXR_UTILITY
{
public:
HOSTFXR_UTILITY();
~HOSTFXR_UTILITY();
static
HRESULT
GetHostFxrParameters(
HANDLE hEventLog,
PCWSTR pcwzProcessPath,
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
_Inout_ STRU* pStruHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
);
static
HRESULT
@ -42,11 +28,30 @@ public:
HRESULT
ParseHostfxrArguments(
PCWSTR pwzArgumentsFromConfig,
PCWSTR pwzExePath,
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pwzExePath,
PCWSTR pcwzApplicationPhysicalPath,
HANDLE hEventLog,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
_Out_ BSTR** pbstrArgv
);
static
BOOL
IsDotnetExecutable(
STRU* struExecutablePath
);
static
HRESULT
GetHostFxrParameters(
_In_ HANDLE hEventLog,
_In_ PCWSTR pcwzProcessPath,
_In_ PCWSTR pcwzApplicationPhysicalPath,
_In_ PCWSTR pcwzArguments,
_Inout_ STRU *pStruHostFxrDllLocation,
_Inout_ STRU *struExeAbsolutePath,
_Out_ DWORD *pdwArgCount,
_Out_ BSTR **ppwzArgv
);
static
@ -74,5 +79,22 @@ public:
GetAbsolutePathToDotnetFromProgramFiles(
_Inout_ STRU* pStruAbsolutePathToDotnet
);
static
HRESULT
FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
);
static
VOID
FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
);
HOSTFXR_UTILITY();
~HOSTFXR_UTILITY();
};

View File

@ -3,6 +3,8 @@
#pragma once
class IREQUEST_HANDLER;
enum APPLICATION_STATUS
{
UNKNOWN = 0,
@ -15,6 +17,7 @@ enum APPLICATION_STATUS
class IAPPLICATION
{
public:
virtual
VOID
ShutDown() = 0;
@ -42,6 +45,5 @@ public:
HRESULT
CreateHandler(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_Out_ IREQUEST_HANDLER **pRequestHandler) = 0;
_Out_ IREQUEST_HANDLER **pRequestHandler) = 0;
};

View File

@ -3,8 +3,6 @@
#pragma once
#include "stdafx.h"
//
// Pure abstract class
//

View File

@ -14,25 +14,22 @@
#include <shellapi.h>
#include <sstream>
#include "Shlwapi.h"
#include "..\IISLib\hashtable.h"
#include "..\IISLib\stringu.h"
#include "..\IISLib\stringa.h"
#include "..\IISLib\multisz.h"
#include "..\IISLib\dbgutil.h"
#include "..\IISLib\ahutil.h"
#include "..\IISLib\hashfn.h"
#include "hashtable.h"
#include "stringu.h"
#include "stringa.h"
#include "multisz.h"
#include "dbgutil.h"
#include "ahutil.h"
#include "hashfn.h"
#include "irequesthandler.h"
#include "requesthandler.h"
#include "iapplication.h"
#include "application.h"
#include "SRWLockWrapper.h"
#include "environmentvariablehash.h"
#include "utility.h"
#include "aspnetcoreconfig.h"
#include "fx_ver.h"
#include "hostfxr_utility.h"
#include "resources.h"
#include "aspnetcore_msg.h"
#include "irequesthandler.h"
#include "iapplication.h"
#include "requesthandler.h"
#include "application.h"
#include "fx_ver.h"
#include "hostfxr_utility.h"

View File

@ -506,30 +506,6 @@ Finished:
return hr;
}
HRESULT
UTILITY::FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
)
{
HRESULT hr = S_OK;
fx_ver_t max_ver(-1, -1, -1);
for (const auto& dir : vFolders)
{
fx_ver_t fx_ver(-1, -1, -1);
if (fx_ver_t::parse(dir, &fx_ver, false))
{
// TODO using max instead of std::max works
max_ver = max(max_ver, fx_ver);
}
}
hr = pstrResult->Copy(max_ver.as_str().c_str());
// we check FAILED(hr) outside of function
return hr;
}
BOOL
UTILITY::DirectoryExists(
_In_ STRU *pstrPath
@ -545,30 +521,6 @@ UTILITY::DirectoryExists(
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
}
VOID
UTILITY::FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
)
{
HANDLE handle = NULL;
WIN32_FIND_DATAW data = { 0 };
handle = FindFirstFileExW(pszPath, FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0);
if (handle == INVALID_HANDLE_VALUE)
{
return;
}
do
{
std::wstring folder(data.cFileName);
pvFolders->push_back(folder);
} while (FindNextFileW(handle, &data));
FindClose(handle);
}
BOOL
UTILITY::CheckIfFileExists(
_In_ PCWSTR pszFilePath

View File

@ -91,20 +91,6 @@ public:
_In_ STRU *pstrPath
);
static
VOID
FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
);
static
HRESULT
FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
);
static
BOOL
CheckIfFileExists(

View File

@ -209,6 +209,7 @@
<ClInclude Include="aspnetcore_event.h" />
<ClInclude Include="disconnectcontext.h" />
<ClInclude Include="environmentvariablehelpers.h" />
<ClInclude Include="requesthandler_config.h" />
<ClInclude Include="sttimer.h" />
<ClInclude Include="outofprocess\forwarderconnection.h" />
<ClInclude Include="outofprocess\processmanager.h" />
@ -237,6 +238,7 @@
<ClCompile Include="outofprocess\serverprocess.cxx" />
<ClCompile Include="outofprocess\websockethandler.cxx" />
<ClCompile Include="outofprocess\winhttphelper.cxx" />
<ClCompile Include="requesthandler_config.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">

View File

@ -4,7 +4,7 @@
#include <VersionHelpers.h>
BOOL g_fNsiApiNotSupported = FALSE;
BOOL g_fWebSocketSupported = FALSE;
BOOL g_fWebSocketStaticInitialize = FALSE;
BOOL g_fEnableReferenceCountTracing = FALSE;
BOOL g_fGlobalInitialize = FALSE;
BOOL g_fOutOfProcessInitialize = FALSE;
@ -21,7 +21,7 @@ IHttpServer * g_pHttpServer = NULL;
HINSTANCE g_hWinHttpModule;
HINSTANCE g_hAspNetCoreModule;
HANDLE g_hEventLog = NULL;
PCSTR g_szDebugLabel = "ASPNET_CORE_MODULE_REQUEST_HANDLER";
VOID
InitializeGlobalConfiguration(
@ -113,7 +113,7 @@ InitializeGlobalConfiguration(
g_fNsiApiNotSupported = TRUE;
}
g_fWebSocketSupported = IsWindows8OrGreater();
g_fWebSocketStaticInitialize = IsWindows8OrGreater();
g_fGlobalInitialize = TRUE;
}
@ -167,7 +167,7 @@ EnsureOutOfProcessInitializtion()
{
if (hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND))
{
g_fWebSocketSupported = FALSE;
g_fWebSocketStaticInitialize = FALSE;
}
else
{
@ -272,20 +272,28 @@ BOOL APIENTRY DllMain(HMODULE hModule,
return TRUE;
}
// TODO remove pHttpContext from the CreateApplication call.
HRESULT
__stdcall
CreateApplication(
_In_ IHttpServer *pServer,
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ IAPPLICATION **ppApplication
_In_ IHttpContext *pHttpContext,
_In_ PCWSTR pwzExeLocation,
_Out_ IAPPLICATION **ppApplication
)
{
HRESULT hr = S_OK;
IAPPLICATION *pApplication = NULL;
REQUESTHANDLER_CONFIG *pConfig = NULL;
// Initialze some global variables here
InitializeGlobalConfiguration(pServer);
hr = REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(pServer, pHttpContext->GetApplication(), pwzExeLocation, g_hEventLog, &pConfig);
if (FAILED(hr))
{
return hr;
}
if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
pApplication = new IN_PROCESS_APPLICATION(pServer, pConfig);
@ -303,7 +311,6 @@ CreateApplication(
goto Finished;
}
pApplication = new OUT_OF_PROCESS_APPLICATION(pConfig);
if (pApplication == NULL)
{

View File

@ -4,7 +4,7 @@ IN_PROCESS_APPLICATION* IN_PROCESS_APPLICATION::s_Application = NULL;
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
IHttpServer* pHttpServer,
ASPNETCORE_CONFIG* pConfig) :
REQUESTHANDLER_CONFIG *pConfig) :
m_pHttpServer(pHttpServer),
m_ProcessExitCode(0),
m_hLogFileHandle(INVALID_HANDLE_VALUE),
@ -16,15 +16,15 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
m_fInitialized(FALSE),
m_fShutdownCalledFromNative(FALSE),
m_fShutdownCalledFromManaged(FALSE),
m_srwLock(),
m_pConfig(pConfig)
m_srwLock()
{
// 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);
InitializeSRWLock(&m_srwLock);
m_pConfig = pConfig;
// TODO we can probably initialized as I believe we are the only ones calling recycle.
m_status = APPLICATION_STATUS::STARTING;
}
@ -38,6 +38,12 @@ IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
m_hLogFileHandle = INVALID_HANDLE_VALUE;
}
if (m_pConfig != NULL)
{
delete m_pConfig;
m_pConfig = NULL;
}
m_hThread = NULL;
s_Application = NULL;
}
@ -110,7 +116,7 @@ Finished:
// Managed layer may block the shutdown and lead to shutdown timeout
// Assumption: only one inprocess application is hosted.
// Call process exit to force shutdown
//
//
exit(hr);
}
}
@ -807,7 +813,9 @@ IN_PROCESS_APPLICATION::ExecuteApplication(
DBG_ASSERT(m_status == APPLICATION_STATUS::STARTING);
hModule = LoadLibraryW(m_pConfig->QueryHostFxrFullPath());
// hostfxr should already be loaded by the shim. If not, then we will need
// to load it ourselves by finding hostfxr again.
hModule = LoadLibraryW(L"hostfxr.dll");
if (hModule == NULL)
{
@ -986,7 +994,7 @@ IN_PROCESS_APPLICATION::FilterException(unsigned int, struct _EXCEPTION_POINTERS
return EXCEPTION_EXECUTE_HANDLER;
}
ASPNETCORE_CONFIG*
REQUESTHANDLER_CONFIG*
IN_PROCESS_APPLICATION::QueryConfig() const
{
return m_pConfig;
@ -995,12 +1003,12 @@ IN_PROCESS_APPLICATION::QueryConfig() const
HRESULT
IN_PROCESS_APPLICATION::CreateHandler(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_Out_ IREQUEST_HANDLER **pRequestHandler)
_Out_ IREQUEST_HANDLER **pRequestHandler)
{
HRESULT hr = S_OK;
IREQUEST_HANDLER* pHandler = NULL;
pHandler = new IN_PROCESS_HANDLER(pHttpContext, pModuleId, this);
pHandler = new IN_PROCESS_HANDLER(pHttpContext, this);
if (pHandler == NULL)
{

View File

@ -2,6 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
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);
@ -10,10 +11,15 @@ typedef REQUEST_NOTIFICATION_STATUS(WINAPI * PFN_MANAGED_CONTEXT_HANDLER)(void *
class IN_PROCESS_APPLICATION : public APPLICATION
{
public:
IN_PROCESS_APPLICATION(IHttpServer* pHttpServer, ASPNETCORE_CONFIG* pConfig);
IN_PROCESS_APPLICATION(IHttpServer* pHttpServer, REQUESTHANDLER_CONFIG *pConfig);
~IN_PROCESS_APPLICATION();
HRESULT
Initialize(
VOID
);
__override
VOID
ShutDown();
@ -37,7 +43,6 @@ public:
HRESULT
CreateHandler(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_Out_ IREQUEST_HANDLER **pRequestHandler)
override;
@ -106,9 +111,15 @@ public:
return s_Application;
}
ASPNETCORE_CONFIG*
REQUESTHANDLER_CONFIG*
QueryConfig() const;
PCWSTR
QueryExeLocation()
{
return m_struExeLocation.QueryStr();
}
private:
static
DWORD
@ -144,6 +155,7 @@ private:
HANDLE m_hErrReadPipe;
HANDLE m_hErrWritePipe;
STRU m_struLogFilePath;
STRU m_struExeLocation;
// The exit code of the .NET Core process
INT m_ProcessExitCode;
@ -166,7 +178,7 @@ private:
DWORD m_dwStdErrReadTotal;
static IN_PROCESS_APPLICATION* s_Application;
ASPNETCORE_CONFIG* m_pConfig;
REQUESTHANDLER_CONFIG* m_pConfig;
VOID
SetStdOut(

View File

@ -2,11 +2,9 @@
IN_PROCESS_HANDLER::IN_PROCESS_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ IN_PROCESS_APPLICATION *pApplication
): m_pW3Context(pW3Context),
m_pApplication(pApplication),
m_pModuleId(*pModuleId)
m_pApplication(pApplication)
{
m_fManagedRequestComplete = FALSE;
}
@ -22,7 +20,9 @@ IN_PROCESS_HANDLER::OnExecuteRequestHandler()
{
// First get the in process Application
HRESULT hr;
hr = m_pApplication->LoadManagedApplication();
if (FAILED(hr))
{
// TODO remove com_error?

View File

@ -8,7 +8,6 @@ public:
IN_PROCESS_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ IN_PROCESS_APPLICATION *pApplication);
~IN_PROCESS_HANDLER() override;
@ -67,11 +66,9 @@ public:
private:
PVOID m_pManagedHttpContext;
IHttpContext* m_pHttpContext;
BOOL m_fManagedRequestComplete;
REQUEST_NOTIFICATION_STATUS m_requestNotificationStatus;
IHttpContext* m_pW3Context;
IN_PROCESS_APPLICATION* m_pApplication;
HTTP_MODULE_ID m_pModuleId;
};

View File

@ -165,7 +165,7 @@ http_get_application_properties(
_In_ IISConfigurationData* pIISCofigurationData
)
{
ASPNETCORE_CONFIG* pConfiguration = NULL;
REQUESTHANDLER_CONFIG* pConfiguration = NULL;
IN_PROCESS_APPLICATION* pApplication = IN_PROCESS_APPLICATION::GetInstance();
if (pApplication == NULL)
@ -373,11 +373,6 @@ http_enable_websockets(
_In_ IN_PROCESS_HANDLER* pInProcessHandler
)
{
//if (!g_fWebSocketSupported)
//{
// return E_FAIL;
//}
((IHttpContext3*)pInProcessHandler->QueryHttpContext())->EnableFullDuplex();
((IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse())->DisableBuffering();

View File

@ -18,9 +18,8 @@ PROTOCOL_CONFIG FORWARDING_HANDLER::sm_ProtocolConfig;
RESPONSE_HEADER_HASH * FORWARDING_HANDLER::sm_pResponseHeaderHash = NULL;
FORWARDING_HANDLER::FORWARDING_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ OUT_OF_PROCESS_APPLICATION *pApplication
_In_ IHttpContext *pW3Context,
_In_ OUT_OF_PROCESS_APPLICATION *pApplication
) : IREQUEST_HANDLER(),
m_Signature(FORWARDING_HANDLER_SIGNATURE),
m_RequestStatus(FORWARDER_START),
@ -42,14 +41,14 @@ FORWARDING_HANDLER::FORWARDING_HANDLER(
m_fServerResetConn(FALSE),
m_cRefs(1),
m_pW3Context(pW3Context),
m_pApplication(pApplication),
m_pModuleId(*pModuleId)
m_pApplication(pApplication)
{
#ifdef DEBUG
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"FORWARDING_HANDLER::FORWARDING_HANDLER");
#endif
m_fWebSocketSupported = m_pApplication->QueryWebsocketStatus();
InitializeSRWLock(&m_RequestLock);
}
@ -182,7 +181,7 @@ FORWARDING_HANDLER::OnExecuteRequestHandler()
//
// Mark request as websocket if upgrade header is present.
//
if (pApplication->QueryConfig()->QueryWebSocketEnabled())
if (m_fWebSocketSupported)
{
USHORT cchHeader = 0;
PCSTR pszWebSocketHeader = pRequest->GetHeader("Upgrade", &cchHeader);

View File

@ -21,10 +21,9 @@ class FORWARDING_HANDLER : public REQUEST_HANDLER
{
public:
FORWARDING_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ OUT_OF_PROCESS_APPLICATION *pApplication);
_In_ IHttpContext *pW3Context,
_In_ OUT_OF_PROCESS_APPLICATION *pApplication
);
~FORWARDING_HANDLER();
@ -178,6 +177,7 @@ private:
FORWARDING_REQUEST_STATUS m_RequestStatus;
BOOL m_fWebSocketEnabled;
BOOL m_fWebSocketSupported;
BOOL m_fResponseHeadersReceivedAndSet;
BOOL m_fResetConnection;
BOOL m_fDoReverseRewriteHeaders;

View File

@ -1,12 +1,13 @@
#include "..\precomp.hxx"
OUT_OF_PROCESS_APPLICATION::OUT_OF_PROCESS_APPLICATION(
ASPNETCORE_CONFIG* pConfig) :
REQUESTHANDLER_CONFIG *pConfig) :
m_fWebSocketSupported(WEBSOCKET_STATUS::WEBSOCKET_UNKNOWN),
m_pConfig(pConfig)
{
m_status = APPLICATION_STATUS::RUNNING;
m_pProcessManager = NULL;
InitializeSRWLock(&rwlock);
InitializeSRWLock(&m_srwLock);
}
OUT_OF_PROCESS_APPLICATION::~OUT_OF_PROCESS_APPLICATION()
@ -17,6 +18,12 @@ OUT_OF_PROCESS_APPLICATION::~OUT_OF_PROCESS_APPLICATION()
m_pProcessManager->DereferenceProcessManager();
m_pProcessManager = NULL;
}
if (m_pConfig != NULL)
{
delete m_pConfig;
m_pConfig = NULL;
}
}
HRESULT
@ -49,10 +56,10 @@ OUT_OF_PROCESS_APPLICATION::GetProcess(
_Out_ SERVER_PROCESS **ppServerProcess
)
{
return m_pProcessManager->GetProcess(m_pConfig, ppServerProcess);
return m_pProcessManager->GetProcess(m_pConfig, QueryWebsocketStatus(), ppServerProcess);
}
ASPNETCORE_CONFIG*
REQUESTHANDLER_CONFIG*
OUT_OF_PROCESS_APPLICATION::QueryConfig() const
{
return m_pConfig;
@ -62,7 +69,7 @@ __override
VOID
OUT_OF_PROCESS_APPLICATION::ShutDown()
{
AcquireSRWLockExclusive(&rwlock);
AcquireSRWLockExclusive(&m_srwLock);
{
if (m_pProcessManager != NULL)
{
@ -71,7 +78,7 @@ OUT_OF_PROCESS_APPLICATION::ShutDown()
m_pProcessManager = NULL;
}
}
ReleaseSRWLockExclusive(&rwlock);
ReleaseSRWLockExclusive(&m_srwLock);
}
__override
@ -84,12 +91,18 @@ OUT_OF_PROCESS_APPLICATION::Recycle()
HRESULT
OUT_OF_PROCESS_APPLICATION::CreateHandler(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_Out_ IREQUEST_HANDLER **pRequestHandler)
_Out_ IREQUEST_HANDLER **pRequestHandler)
{
HRESULT hr = S_OK;
IREQUEST_HANDLER* pHandler = NULL;
pHandler = new FORWARDING_HANDLER(pHttpContext, pModuleId, this);
//add websocket check here
if (m_fWebSocketSupported == WEBSOCKET_STATUS::WEBSOCKET_UNKNOWN)
{
SetWebsocketStatus(pHttpContext);
}
pHandler = new FORWARDING_HANDLER(pHttpContext, this);
if (pHandler == NULL)
{
@ -99,3 +112,31 @@ OUT_OF_PROCESS_APPLICATION::CreateHandler(
*pRequestHandler = pHandler;
return hr;
}
VOID
OUT_OF_PROCESS_APPLICATION::SetWebsocketStatus(
IHttpContext* pHttpContext
)
{
// Even though the applicationhost.config file contains the websocket element,
// the websocket module may still not be enabled.
PCWSTR pszTempWebsocketValue;
DWORD cbLength;
HRESULT hr;
hr = pHttpContext->GetServerVariable("WEBSOCKET_VERSION", &pszTempWebsocketValue, &cbLength);
if (FAILED(hr))
{
m_fWebSocketSupported = WEBSOCKET_STATUS::WEBSOCKET_NOT_SUPPORTED;
}
else
{
m_fWebSocketSupported = WEBSOCKET_STATUS::WEBSOCKET_SUPPORTED;
}
}
BOOL
OUT_OF_PROCESS_APPLICATION::QueryWebsocketStatus() const
{
return m_fWebSocketSupported == WEBSOCKET_STATUS::WEBSOCKET_SUPPORTED;
}

View File

@ -1,10 +1,20 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#pragma once
class OUT_OF_PROCESS_APPLICATION : public APPLICATION
{
enum WEBSOCKET_STATUS
{
WEBSOCKET_UNKNOWN = 0,
WEBSOCKET_NOT_SUPPORTED,
WEBSOCKET_SUPPORTED,
};
public:
OUT_OF_PROCESS_APPLICATION(ASPNETCORE_CONFIG *pConfig);
OUT_OF_PROCESS_APPLICATION(
REQUESTHANDLER_CONFIG *pConfig);
__override
~OUT_OF_PROCESS_APPLICATION() override;
@ -31,18 +41,25 @@ public:
HRESULT
CreateHandler(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_Out_ IREQUEST_HANDLER **pRequestHandler)
override;
ASPNETCORE_CONFIG*
REQUESTHANDLER_CONFIG*
QueryConfig()
const;
BOOL
QueryWebsocketStatus()
const;
private:
PROCESS_MANAGER * m_pProcessManager;
SRWLOCK rwlock;
VOID SetWebsocketStatus(IHttpContext *pHttpContext);
ASPNETCORE_CONFIG* m_pConfig;
PROCESS_MANAGER * m_pProcessManager;
SRWLOCK m_srwLock;
IHttpServer *m_pHttpServer;
REQUESTHANDLER_CONFIG* m_pConfig;
WEBSOCKET_STATUS m_fWebSocketSupported;
};

View File

@ -103,8 +103,9 @@ PROCESS_MANAGER::~PROCESS_MANAGER()
HRESULT
PROCESS_MANAGER::GetProcess(
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ SERVER_PROCESS **ppServerProcess
_In_ REQUESTHANDLER_CONFIG *pConfig,
_In_ BOOL fWebsocketSupported,
_Out_ SERVER_PROCESS **ppServerProcess
)
{
HRESULT hr = S_OK;
@ -220,7 +221,7 @@ PROCESS_MANAGER::GetProcess(
pConfig->QueryAnonymousAuthEnabled(),
pConfig->QueryEnvironmentVariables(),
pConfig->QueryStdoutLogEnabled(),
pConfig->QueryWebSocketEnabled(),
fWebsocketSupported,
pConfig->QueryStdoutLogFile(),
pConfig->QueryApplicationPhysicalPath(), // physical path
pConfig->QueryApplicationPath(), // app path

View File

@ -30,8 +30,9 @@ public:
HRESULT
GetProcess(
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ SERVER_PROCESS **ppServerProcess
_In_ REQUESTHANDLER_CONFIG *pConfig,
_In_ BOOL fWebsocketEnabled,
_Out_ SERVER_PROCESS **ppServerProcess
);
HANDLE
@ -192,4 +193,4 @@ private:
volatile static BOOL sm_fWSAStartupDone;
volatile BOOL m_fServerProcessListReady;
};
};

View File

@ -41,7 +41,7 @@ Finished:
VOID
PROTOCOL_CONFIG::OverrideConfig(
ASPNETCORE_CONFIG *pAspNetCoreConfig
REQUESTHANDLER_CONFIG *pAspNetCoreConfig
)
{
m_msTimeout = pAspNetCoreConfig->QueryRequestTimeoutInMS();

View File

@ -16,7 +16,7 @@ class PROTOCOL_CONFIG
VOID
OverrideConfig(
ASPNETCORE_CONFIG *pAspNetCoreConfig
REQUESTHANDLER_CONFIG *pAspNetCoreConfig
);
BOOL

View File

@ -22,23 +22,23 @@ SERVER_PROCESS::Initialize(
BOOL fAnonymousAuthEnabled,
ENVIRONMENT_VAR_HASH *pEnvironmentVariables,
BOOL fStdoutLogEnabled,
BOOL fWebsocketsEnabled,
BOOL fWebSocketSupported,
STRU *pstruStdoutLogFile,
STRU *pszAppPhysicalPath,
STRU *pszAppPath,
STRU *pszAppVirtualPath
)
{
HRESULT hr = S_OK;
HRESULT hr = S_OK;
m_pProcessManager = pProcessManager;
m_dwStartupTimeLimitInMS = dwStartupTimeLimitInMS;
m_dwShutdownTimeLimitInMS = dwShtudownTimeLimitInMS;
m_fStdoutLogEnabled = fStdoutLogEnabled;
m_fWebSocketSupported = fWebSocketSupported;
m_fWindowsAuthEnabled = fWindowsAuthEnabled;
m_fBasicAuthEnabled = fBasicAuthEnabled;
m_fAnonymousAuthEnabled = fAnonymousAuthEnabled;
m_fWebsocketsEnabled = fWebsocketsEnabled;
m_pProcessManager->ReferenceProcessManager();
m_fDebuggerAttached = FALSE;
@ -790,7 +790,7 @@ SERVER_PROCESS::StartProcess(
if (FAILED(hr = ENVIRONMENT_VAR_HELPERS::AddWebsocketEnabledToEnvironmentVariables(
pHashTable,
m_fWebsocketsEnabled
m_fWebSocketSupported
)))
{
pStrStage = L"AddWebsocketEnabledToEnvironmentVariables";

View File

@ -33,7 +33,7 @@ public:
_In_ BOOL fAnonymousAuthEnabled,
_In_ ENVIRONMENT_VAR_HASH* pEnvironmentVariables,
_In_ BOOL fStdoutLogEnabled,
_In_ BOOL fWebsocketsEnabled,
_In_ BOOL fWebSocketSupported,
_In_ STRU *pstruStdoutLogFile,
_In_ STRU *pszAppPhysicalPath,
_In_ STRU *pszAppPath,
@ -234,10 +234,10 @@ private:
FORWARDER_CONNECTION *m_pForwarderConnection;
BOOL m_fStdoutLogEnabled;
BOOL m_fWebSocketSupported;
BOOL m_fWindowsAuthEnabled;
BOOL m_fBasicAuthEnabled;
BOOL m_fAnonymousAuthEnabled;
BOOL m_fWebsocketsEnabled;
BOOL m_fDebuggerAttached;
STTIMER m_Timer;

View File

@ -94,7 +94,7 @@ WEBSOCKET_HANDLER::StaticInitialize(
--*/
{
if (!g_fWebSocketSupported)
if (!g_fWebSocketStaticInitialize)
{
return S_OK;
}
@ -120,7 +120,7 @@ WEBSOCKET_HANDLER::StaticTerminate(
VOID
)
{
if (!g_fWebSocketSupported)
if (!g_fWebSocketStaticInitialize)
{
return;
}

View File

@ -26,14 +26,13 @@ WINHTTP_HELPER::StaticInitialize(
{
HRESULT hr = S_OK;
if (!g_fWebSocketSupported)
{
return S_OK;
}
//
// Initialize the function pointers for WinHttp Websocket API's.
//
if (!g_fWebSocketStaticInitialize)
{
return S_OK;
}
HMODULE hWinHttp = GetModuleHandleA("winhttp.dll");
if (hWinHttp == NULL)
@ -173,4 +172,4 @@ WINHTTP_HELPER::GetBufferTypeFromFlags(
}
return;
}
}

View File

@ -26,6 +26,7 @@
#include <wchar.h>
#include <io.h>
#include <stdio.h>
// This should remove our issue of compiling for win7 without header files.
// We force the Windows 8 version check logic in iiswebsocket.h to succeed even though we're compiling for Windows 7.
// Then, we set the version defines back to Windows 7 to for the remainder of the compilation.
@ -44,36 +45,41 @@
#define WINVER 0x0601
#define _WIN32_WINNT 0x0601
#include "..\IISLib\acache.h"
#include "..\IISLib\multisz.h"
#include "..\IISLib\multisza.h"
#include "..\IISLib\base64.h"
#include "..\IISLib\listentry.h"
#include "..\CommonLib\fx_ver.h"
#include "..\CommonLib\debugutil.h"
#include "..\CommonLib\requesthandler.h"
#include "..\CommonLib\aspnetcoreconfig.h"
#include "..\CommonLib\utility.h"
#include "..\CommonLib\application.h"
#include "..\CommonLib\resources.h"
// IIS Lib
#include "acache.h"
#include "multisz.h"
#include "multisza.h"
#include "base64.h"
#include "listentry.h"
#include "debugutil.h"
// Common lib
#include "hostfxr_utility.h"
#include "requesthandler.h"
#include "utility.h"
#include "application.h"
#include "resources.h"
#include "aspnetcore_event.h"
#include "aspnetcore_msg.h"
#include "disconnectcontext.h"
#include "environmentvariablehelpers.h"
#include "sttimer.h"
#include ".\requesthandler_config.h"
#include ".\inprocess\InProcessHandler.h"
#include ".\inprocess\inprocessapplication.h"
#include ".\outofprocess\websockethandler.h"
#include ".\outofprocess\responseheaderhash.h"
#include ".\outofprocess\protocolconfig.h"
#include ".\outofprocess\forwarderconnection.h"
#include ".\outofprocess\serverprocess.h"
#include ".\outofprocess\processmanager.h"
#include ".\outofprocess\websockethandler.h"
#include ".\outofprocess\forwardinghandler.h"
#include ".\outofprocess\outprocessapplication.h"
#include ".\outofprocess\winhttphelper.h"
#include ".\outofprocess\outprocessapplication.h"
#include "environmentvariablehelpers.h"
#ifdef max
#undef max
template<typename T> inline T max(T a, T b)
@ -90,7 +96,6 @@ template<typename T> inline T min(T a, T b)
}
#endif
inline bool IsSpace(char ch)
{
switch (ch)
@ -109,7 +114,7 @@ inline bool IsSpace(char ch)
extern BOOL g_fAsyncDisconnectAvailable;
extern BOOL g_fWinHttpNonBlockingCallbackAvailable;
extern BOOL g_fWebSocketSupported;
extern BOOL g_fWebSocketStaticInitialize;
extern BOOL g_fNsiApiNotSupported;
extern BOOL g_fEnableReferenceCountTracing;
extern BOOL g_fProcessDetach;

View File

@ -2,10 +2,10 @@
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
#include "aspnetcoreconfig.h"
#include "requesthandler_config.h"
#include "debugutil.h"
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
REQUESTHANDLER_CONFIG::~REQUESTHANDLER_CONFIG()
{
if (m_ppStrArguments != NULL)
{
@ -21,42 +21,21 @@ ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
}
}
VOID
ASPNETCORE_CONFIG::ReferenceConfiguration(
VOID
) const
{
InterlockedIncrement(&m_cRefs);
}
VOID
ASPNETCORE_CONFIG::DereferenceConfiguration(
VOID
) const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
delete this;
}
}
HRESULT
ASPNETCORE_CONFIG::GetConfig(
REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpContext *pHttpContext,
_In_ IHttpApplication *pHttpApplication,
_In_ PCWSTR pwzExeLocation,
_In_ HANDLE hEventLog,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
_Out_ REQUESTHANDLER_CONFIG **ppAspNetCoreConfig
)
{
HRESULT hr = S_OK;
IHttpApplication *pHttpApplication = pHttpContext->GetApplication();
ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL;
REQUESTHANDLER_CONFIG *pRequestHandlerConfig = NULL;
STRU struHostFxrDllLocation;
PWSTR* pwzArgv;
BSTR* pwzArgv;
DWORD dwArgCount;
STRU struExeLocation;
if (ppAspNetCoreConfig == NULL)
{
@ -66,105 +45,101 @@ ASPNETCORE_CONFIG::GetConfig(
*ppAspNetCoreConfig = NULL;
// potential bug if user sepcific config at virtual dir level
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
pHttpApplication->GetModuleContextContainer()->GetModuleContext(pModuleId);
if (pAspNetCoreConfig != NULL)
{
*ppAspNetCoreConfig = pAspNetCoreConfig;
pAspNetCoreConfig = NULL;
goto Finished;
}
pAspNetCoreConfig = new ASPNETCORE_CONFIG;
if (pAspNetCoreConfig == NULL)
pRequestHandlerConfig = new REQUESTHANDLER_CONFIG;
if (pRequestHandlerConfig == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAspNetCoreConfig->Populate(pHttpServer, pHttpContext);
hr = pRequestHandlerConfig->Populate(pHttpServer, pHttpApplication);
if (FAILED(hr))
{
goto Finished;
}
// Modify config for inprocess.
if (pAspNetCoreConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
if (pRequestHandlerConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
if (FAILED(hr = HOSTFXR_UTILITY::GetHostFxrParameters(
hEventLog,
pAspNetCoreConfig->QueryProcessPath()->QueryStr(),
pAspNetCoreConfig->QueryApplicationPhysicalPath()->QueryStr(),
pAspNetCoreConfig->QueryArguments()->QueryStr(),
&struHostFxrDllLocation,
&dwArgCount,
&pwzArgv)))
if (FAILED(struExeLocation.Copy(pwzExeLocation)))
{
goto Finished;
}
if (FAILED(hr = pAspNetCoreConfig->SetHostFxrFullPath(struHostFxrDllLocation.QueryStr())))
// If the exe was not provided by the shim, reobtain the hostfxr parameters (which finds dotnet).
if (struExeLocation.IsEmpty())
{
goto Finished;
if (FAILED(hr = HOSTFXR_UTILITY::GetHostFxrParameters(
hEventLog,
pRequestHandlerConfig->QueryProcessPath()->QueryStr(),
pRequestHandlerConfig->QueryApplicationPhysicalPath()->QueryStr(),
pRequestHandlerConfig->QueryArguments()->QueryStr(),
&struHostFxrDllLocation,
&struExeLocation,
&dwArgCount,
&pwzArgv)))
{
goto Finished;
}
}
pAspNetCoreConfig->SetHostFxrArguments(dwArgCount, pwzArgv);
}
hr = pHttpApplication->GetModuleContextContainer()->
SetModuleContext(pAspNetCoreConfig, pModuleId);
if (FAILED(hr))
{
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
else if (HOSTFXR_UTILITY::IsDotnetExecutable(&struExeLocation))
{
delete pAspNetCoreConfig;
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
GetModuleContextContainer()->
GetModuleContext(pModuleId);
_ASSERT(pAspNetCoreConfig != NULL);
hr = S_OK;
if (FAILED(hr = HOSTFXR_UTILITY::ParseHostfxrArguments(
pRequestHandlerConfig->QueryArguments()->QueryStr(),
pwzExeLocation,
pRequestHandlerConfig->QueryApplicationPhysicalPath()->QueryStr(),
hEventLog,
&dwArgCount,
&pwzArgv)))
{
goto Finished;
}
}
else
{
goto Finished;
}
}
else
{
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"ASPNETCORE_CONFIG::GetConfig, set config to ModuleContext");
// set appliction info here instead of inside Populate()
// as the destructor will delete the backend process
hr = pAspNetCoreConfig->QueryApplicationPath()->Copy(pHttpApplication->GetApplicationId());
if (FAILED(hr))
{
goto Finished;
if (FAILED(hr = HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
pwzExeLocation,
pRequestHandlerConfig->QueryApplicationPhysicalPath()->QueryStr(),
pRequestHandlerConfig->QueryArguments()->QueryStr(),
hEventLog,
&struHostFxrDllLocation,
&dwArgCount,
&pwzArgv)))
{
goto Finished;
}
}
pRequestHandlerConfig->SetHostFxrArguments(dwArgCount, pwzArgv);
}
*ppAspNetCoreConfig = pAspNetCoreConfig;
pAspNetCoreConfig = NULL;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"REQUESTHANDLER_CONFIG::GetConfig, set config to ModuleContext");
// set appliction info here instead of inside Populate()
// as the destructor will delete the backend process
hr = pRequestHandlerConfig->QueryApplicationPath()->Copy(pHttpApplication->GetApplicationId());
if (FAILED(hr))
{
goto Finished;
}
*ppAspNetCoreConfig = pRequestHandlerConfig;
pRequestHandlerConfig = NULL;
Finished:
if (pAspNetCoreConfig != NULL)
if (pRequestHandlerConfig != NULL)
{
delete pAspNetCoreConfig;
pAspNetCoreConfig = NULL;
delete pRequestHandlerConfig;
pRequestHandlerConfig = NULL;
}
return hr;
}
HRESULT
ASPNETCORE_CONFIG::Populate(
REQUESTHANDLER_CONFIG::Populate(
IHttpServer *pHttpServer,
IHttpContext *pHttpContext
IHttpApplication *pHttpApplication
)
{
STACK_STRU(strHostingModel, 300);
@ -206,13 +181,13 @@ ASPNETCORE_CONFIG::Populate(
}
pAdminManager = pHttpServer->GetAdminManager();
hr = m_struConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
hr = m_struConfigPath.Copy(pHttpApplication->GetAppConfigPath());
if (FAILED(hr))
{
goto Finished;
}
hr = m_struApplicationPhysicalPath.Copy(pHttpContext->GetApplication()->GetApplicationPhysicalPath());
hr = m_struApplicationPhysicalPath.Copy(pHttpApplication->GetApplicationPhysicalPath());
if (FAILED(hr))
{
goto Finished;
@ -320,20 +295,6 @@ ASPNETCORE_CONFIG::Populate(
}
}
// Even though the applicationhost.config file contains the websocket element,
// the websocket module may still not be enabled. Check if the
PCWSTR pszVariableValue;
DWORD cbLength;
hr = pHttpContext->GetServerVariable("WEBSOCKET_VERSION", &pszVariableValue, &cbLength);
if (FAILED(hr))
{
m_fWebSocketEnabled = FALSE;
}
else
{
m_fWebSocketEnabled = TRUE;
}
bstrAspNetCoreSection = SysAllocString(CS_ASPNETCORE_SECTION);
if (bstrAspNetCoreSection == NULL)
{

View File

@ -50,27 +50,21 @@ enum APP_HOSTING_MODEL
HOSTING_OUT_PROCESS
};
class ASPNETCORE_CONFIG : IHttpStoredContext
class REQUESTHANDLER_CONFIG
{
public:
virtual
~ASPNETCORE_CONFIG();
VOID
CleanupStoredContext()
{
DereferenceConfiguration();
}
~REQUESTHANDLER_CONFIG();
static
HRESULT
GetConfig(
CreateRequestHandlerConfig(
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpContext *pHttpContext,
_In_ IHttpApplication *pHttpApplication,
_In_ PCWSTR pwzExeLocation,
_In_ HANDLE hEventLog,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
_Out_ REQUESTHANDLER_CONFIG **ppAspNetCoreConfig
);
ENVIRONMENT_VAR_HASH*
@ -155,7 +149,7 @@ public:
STRU*
QueryProcessPath(
VOID
VOID
)
{
return &m_struProcessPath;
@ -175,12 +169,6 @@ public:
return m_fStdoutLogEnabled;
}
BOOL
QueryWebSocketEnabled()
{
return m_fWebSocketEnabled;
}
BOOL
QueryForwardWindowsAuthToken()
{
@ -242,22 +230,6 @@ public:
}
CONST
PCWSTR
QueryHostFxrFullPath(
VOID
)
{
return m_struHostFxrLocation.QueryStr();
}
HRESULT
SetHostFxrFullPath(
PCWSTR pStrHostFxrFullPath
)
{
return m_struHostFxrLocation.Copy(pStrHostFxrFullPath);
}
VOID
SetHostFxrArguments(
DWORD dwArgc,
@ -273,34 +245,24 @@ public:
m_ppStrArguments = ppStrArguments;
}
VOID
ReferenceConfiguration(
VOID
) const;
VOID
DereferenceConfiguration(
VOID
) const;
private:
//
// private constructor
//
ASPNETCORE_CONFIG():
m_fStdoutLogEnabled( FALSE ),
m_pEnvironmentVariables( NULL ),
m_cRefs( 1 ),
m_hostingModel( HOSTING_UNKNOWN ),
REQUESTHANDLER_CONFIG() :
m_fStdoutLogEnabled(FALSE),
m_pEnvironmentVariables(NULL),
m_cRefs(1),
m_hostingModel(HOSTING_UNKNOWN),
m_ppStrArguments(NULL)
{
}
HRESULT
Populate(
IHttpServer *pHttpServer,
IHttpContext *pHttpContext
IHttpServer *pHttpServer,
IHttpApplication *pHttpApplication
);
mutable LONG m_cRefs;
@ -323,10 +285,9 @@ private:
BOOL m_fWindowsAuthEnabled;
BOOL m_fBasicAuthEnabled;
BOOL m_fAnonymousAuthEnabled;
BOOL m_fWebSocketEnabled;
APP_HOSTING_MODEL m_hostingModel;
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
STRU m_struHostFxrLocation;
PWSTR* m_ppStrArguments;
PWSTR* m_ppStrArguments;
DWORD m_dwArgc;
};

View File

@ -47,6 +47,9 @@
<ClCompile Include="utility_tests.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\AspNetCoreModuleV2\AspNetCore\AspNetCore.vcxproj">
<Project>{ec82302f-d2f0-4727-99d1-eabc0dd9dc3b}</Project>
</ProjectReference>
<ProjectReference Include="..\..\src\AspNetCoreModuleV2\CommonLib\CommonLib.vcxproj">
<Project>{55494e58-e061-4c4c-a0a8-837008e72f85}</Project>
</ProjectReference>
@ -69,7 +72,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include;..\..\src\AspNetCoreModuleV2\AspNetCore\Inc;</AdditionalIncludeDirectories>
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
</ClCompile>
<Link>
@ -91,7 +94,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include;..\..\src\AspNetCoreModuleV2\AspNetCore\Inc;</AdditionalIncludeDirectories>
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
</ClCompile>
<Link>
@ -111,7 +114,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include;..\..\src\AspNetCoreModuleV2\AspNetCore\Inc;</AdditionalIncludeDirectories>
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
</ClCompile>
<Link>
@ -133,7 +136,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest-1.8.0\include;..\..\src\AspNetCoreModuleV2\AspNetCore\Inc;</AdditionalIncludeDirectories>
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
</ClCompile>
<Link>

View File

@ -126,6 +126,7 @@ TEST(GetHostFxrArguments, InvalidParams)
DWORD retVal = 0;
BSTR* bstrArray;
STRU struHostFxrDllLocation;
STRU struExeLocation;
HRESULT hr = HOSTFXR_UTILITY::GetHostFxrParameters(
INVALID_HANDLE_VALUE,
@ -133,8 +134,9 @@ TEST(GetHostFxrArguments, InvalidParams)
L"", // application physical path, ignored.
L"ignored", //arguments
NULL, // event log
&struExeLocation,
&retVal, // arg count
&bstrArray); // args array.
EXPECT_EQ(E_INVALIDARG, hr);
}
}

View File

@ -42,7 +42,6 @@
#include "hostfxr_utility.h"
#include "environmentvariablehash.h"
#include "aspnetcoreconfig.h"
#include "iapplication.h"
#include "utility.h"
#include "debugutil.h"