Merge branch 'merge/release/2.2-to-master'
This commit is contained in:
commit
8b822d4314
|
|
@ -4,6 +4,7 @@
|
|||
<PropertyGroup>
|
||||
<AssemblySigningCertName>Microsoft</AssemblySigningCertName>
|
||||
<AncmZipOutputPath>$(BuildDir)AspNetCoreModule.zip</AncmZipOutputPath>
|
||||
<StressTestWebSiteZipOutputPath>$(BuildDir)StressTestWebSite.zip</StressTestWebSiteZipOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<PrepareDependsOn>$(PrepareDependsOn)</PrepareDependsOn>
|
||||
<GetArtifactInfoDependsOn>$(GetArtifactInfoDependsOn);GetNativeArtifactsInfo</GetArtifactInfoDependsOn>
|
||||
<CompileDependsOn Condition="'$(OS)'=='Windows_NT'">BuildNativeAssets;$(CompileDependsOn)</CompileDependsOn>
|
||||
<PackageDependsOn Condition="'$(OS)'=='Windows_NT'">$(PackageDependsOn);PackageNativeProjects</PackageDependsOn>
|
||||
<PackageDependsOn Condition="'$(OS)'=='Windows_NT'">$(PackageDependsOn);PackageNativeProjects;PackageStressTestApp</PackageDependsOn>
|
||||
<TestDependsOn>$(TestDependsOn);RunNativeTest</TestDependsOn>
|
||||
<NuGetVerifierRuleFile Condition="'$(OS)' != 'Windows_NT'">$(RepositoryRoot)NuGetPackageVerifier.xplat.json</NuGetVerifierRuleFile>
|
||||
<SourceBase>$(RepositoryRoot)src\</SourceBase>
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
<ItemGroup>
|
||||
<Platforms Include="x86" VCPlatform="Win32" />
|
||||
<Platforms Include="x64" VCPlatform="x64" />
|
||||
</ItemGroup>
|
||||
</ItemGroup>
|
||||
<Import Project="assets.props" />
|
||||
|
||||
<Target Name="BuildNativeAssets" DependsOnTargets="Prepare;GetToolsets" >
|
||||
|
|
@ -110,4 +110,26 @@
|
|||
<Exec Command=""$(VisualStudioMSBuildx86Path)" "$(RepositoryRoot)test\CommonLibTests\CommonLibTests.vcxproj" /t:Test $(BuildArgs) -p:Platform=%(Platforms.VCPlatform)"
|
||||
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PackageStressTestApp">
|
||||
<PropertyGroup>
|
||||
<StressAppBasePath>$(MSBuildThisFileDirectory)..\test\WebSites\StressTestWebSite\</StressAppBasePath>
|
||||
<StressAppPublishPath>$(StressAppBasePath)bin\published\</StressAppPublishPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<RemoveDir Directories="$(StressAppPublishPath)" />
|
||||
<MSBuild
|
||||
Projects="$(StressAppBasePath)\StressTestWebSite.csproj"
|
||||
Targets="Publish"
|
||||
Properties="TargetFramework=netcoreapp2.2;Configuration=$(Configuration);RuntimeIdentifier=win7-%(Platforms.Identity);PublishDir=$(StressAppPublishPath)\%(Identity)" />
|
||||
|
||||
<ItemGroup>
|
||||
<StressAppFiles Include="$(StressAppPublishPath)\**\*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ZipArchive File="$(StressTestWebSiteZipOutputPath)"
|
||||
Overwrite="true"
|
||||
SourceFiles="@(StressAppFiles)"
|
||||
WorkingDirectory="$(StressAppPublishPath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
#include "AppOfflineApplication.h"
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include "HandleWrapper.h"
|
||||
#include "AppOfflineHandler.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
HRESULT AppOfflineApplication::CreateHandler(IHttpContext* pHttpContext, IREQUEST_HANDLER** pRequestHandler)
|
||||
{
|
||||
|
|
@ -57,5 +57,5 @@ HRESULT AppOfflineApplication::OnAppOfflineFound()
|
|||
|
||||
bool AppOfflineApplication::ShouldBeStarted(IHttpApplication& pApplication)
|
||||
{
|
||||
return is_regular_file(GetAppOfflineLocation(pApplication));
|
||||
return FileExists(GetAppOfflineLocation(pApplication));
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "application.h"
|
||||
#include <string>
|
||||
#include "requesthandler.h"
|
||||
|
||||
class AppOfflineHandler: public REQUEST_HANDLER
|
||||
|
|
@ -226,10 +226,13 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="applicationinfo.h" />
|
||||
<ClInclude Include="AppOfflineApplication.h" />
|
||||
<ClInclude Include="AppOfflineHandler.h" />
|
||||
<ClInclude Include="aspnetcore_shim_config.h" />
|
||||
<ClInclude Include="globalmodule.h" />
|
||||
<ClInclude Include="applicationmanager.h" />
|
||||
<ClInclude Include="HandlerResolver.h" />
|
||||
<ClInclude Include="PollingAppOfflineApplication.h" />
|
||||
<ClInclude Include="proxymodule.h" />
|
||||
<ClInclude Include="ServerErrorApplication.h" />
|
||||
<ClInclude Include="ServerErrorHandler.h" />
|
||||
|
|
@ -238,10 +241,13 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="applicationinfo.cpp" />
|
||||
<ClCompile Include="applicationmanager.cpp" />
|
||||
<ClCompile Include="AppOfflineApplication.cpp" />
|
||||
<ClCompile Include="AppOfflineHandler.cpp" />
|
||||
<ClCompile Include="aspnetcore_shim_config.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="globalmodule.cpp" />
|
||||
<ClCompile Include="HandlerResolver.cpp" />
|
||||
<ClCompile Include="PollingAppOfflineApplication.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
|
||||
#include "HandlerResolver.h"
|
||||
#include "exceptions.h"
|
||||
#include "utility.h"
|
||||
#include "SRWExclusiveLock.h"
|
||||
#include "applicationinfo.h"
|
||||
#include "EventLog.h"
|
||||
#include "hostfxr_utility.h"
|
||||
#include "GlobalVersionUtility.h"
|
||||
#include "HandleWrapper.h"
|
||||
#include "file_utility.h"
|
||||
|
||||
const PCWSTR HandlerResolver::s_pwzAspnetcoreInProcessRequestHandlerName = L"aspnetcorev2_inprocess.dll";
|
||||
const PCWSTR HandlerResolver::s_pwzAspnetcoreOutOfProcessRequestHandlerName = L"aspnetcorev2_outofprocess.dll";
|
||||
|
|
@ -26,7 +26,7 @@ HandlerResolver::HandlerResolver(HMODULE hModule, IHttpServer &pServer)
|
|||
}
|
||||
|
||||
HRESULT
|
||||
HandlerResolver::LoadRequestHandlerAssembly(STRU& location, ASPNETCORE_SHIM_CONFIG * pConfiguration)
|
||||
HandlerResolver::LoadRequestHandlerAssembly(IHttpApplication &pApplication, STRU& location, ASPNETCORE_SHIM_CONFIG * pConfiguration)
|
||||
{
|
||||
HRESULT hr;
|
||||
STACK_STRU(struFileName, MAX_PATH);
|
||||
|
|
@ -50,20 +50,18 @@ HandlerResolver::LoadRequestHandlerAssembly(STRU& location, ASPNETCORE_SHIM_CONF
|
|||
RETURN_IF_FAILED(HOSTFXR_OPTIONS::Create(
|
||||
NULL,
|
||||
pConfiguration->QueryProcessPath()->QueryStr(),
|
||||
pConfiguration->QueryApplicationPhysicalPath()->QueryStr(),
|
||||
pApplication.GetApplicationPhysicalPath(),
|
||||
pConfiguration->QueryArguments()->QueryStr(),
|
||||
g_hEventLog,
|
||||
options));
|
||||
|
||||
RETURN_IF_FAILED(location.Copy(options->GetExeLocation()));
|
||||
|
||||
if (FAILED_LOG(hr = FindNativeAssemblyFromHostfxr(options.get(), pstrHandlerDllName, &struFileName)))
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
ASPNETCORE_EVENT_INPROCESS_RH_MISSING,
|
||||
ASPNETCORE_EVENT_INPROCESS_RH_MISSING_MSG,
|
||||
struFileName.IsEmpty() ? s_pwzAspnetcoreInProcessRequestHandlerName : struFileName.QueryStr());
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_INPROCESS_RH_MISSING,
|
||||
ASPNETCORE_EVENT_INPROCESS_RH_MISSING_MSG,
|
||||
struFileName.IsEmpty() ? s_pwzAspnetcoreInProcessRequestHandlerName : struFileName.QueryStr());
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
|
@ -72,8 +70,7 @@ HandlerResolver::LoadRequestHandlerAssembly(STRU& location, ASPNETCORE_SHIM_CONF
|
|||
{
|
||||
if (FAILED_LOG(hr = FindNativeAssemblyFromGlobalLocation(pConfiguration, pstrHandlerDllName, &struFileName)))
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING,
|
||||
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG,
|
||||
struFileName.IsEmpty() ? s_pwzAspnetcoreOutOfProcessRequestHandlerName : struFileName.QueryStr());
|
||||
|
|
@ -108,15 +105,14 @@ HandlerResolver::GetApplicationFactory(IHttpApplication &pApplication, STRU& loc
|
|||
{
|
||||
m_loadedApplicationHostingModel = pConfiguration.QueryHostingModel();
|
||||
m_loadedApplicationId = pApplication.GetApplicationId();
|
||||
LOG_IF_FAILED(m_fAspnetcoreRHLoadResult = LoadRequestHandlerAssembly(location, &pConfiguration));
|
||||
LOG_IF_FAILED(m_fAspnetcoreRHLoadResult = LoadRequestHandlerAssembly(pApplication, location, &pConfiguration));
|
||||
}
|
||||
}
|
||||
|
||||
// Mixed hosting models
|
||||
if (m_loadedApplicationHostingModel != pConfiguration.QueryHostingModel())
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
|
||||
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
|
||||
pApplication.GetApplicationId(),
|
||||
|
|
@ -127,8 +123,7 @@ HandlerResolver::GetApplicationFactory(IHttpApplication &pApplication, STRU& loc
|
|||
// Multiple in-process apps
|
||||
else if (m_loadedApplicationHostingModel == HOSTING_IN_PROCESS && m_loadedApplicationId != pApplication.GetApplicationId())
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP,
|
||||
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
|
||||
pApplication.GetApplicationId());
|
||||
|
|
@ -165,8 +160,7 @@ HandlerResolver::FindNativeAssemblyFromGlobalLocation(
|
|||
STRU struEvent;
|
||||
if (SUCCEEDED(struEvent.Copy(ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG)))
|
||||
{
|
||||
UTILITY::LogEvent(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING,
|
||||
struEvent.QueryStr());
|
||||
}
|
||||
|
|
@ -251,7 +245,7 @@ HandlerResolver::FindNativeAssemblyFromHostfxr(
|
|||
|
||||
RETURN_IF_FAILED(struNativeDllLocation.Append(libraryName));
|
||||
|
||||
if (UTILITY::CheckIfFileExists(struNativeDllLocation.QueryStr()))
|
||||
if (FILE_UTILITY::CheckIfFileExists(struNativeDllLocation.QueryStr()))
|
||||
{
|
||||
RETURN_IF_FAILED(struFilename->Copy(struNativeDllLocation));
|
||||
fFound = TRUE;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public:
|
|||
HRESULT GetApplicationFactory(IHttpApplication &pApplication, STRU& location, PFN_ASPNETCORE_CREATE_APPLICATION *pfnCreateApplication);
|
||||
|
||||
private:
|
||||
HRESULT LoadRequestHandlerAssembly(STRU& location, ASPNETCORE_SHIM_CONFIG * pConfiguration);
|
||||
HRESULT LoadRequestHandlerAssembly(IHttpApplication &pApplication,STRU& location, ASPNETCORE_SHIM_CONFIG * pConfiguration);
|
||||
HRESULT FindNativeAssemblyFromGlobalLocation(ASPNETCORE_SHIM_CONFIG * pConfiguration, PCWSTR libraryName, STRU* location);
|
||||
HRESULT FindNativeAssemblyFromHostfxr(HOSTFXR_OPTIONS* hostfxrOptions, PCWSTR libraryName, STRU* location);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <filesystem>
|
||||
#include "SRWExclusiveLock.h"
|
||||
#include "HandleWrapper.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
APPLICATION_STATUS PollingAppOfflineApplication::QueryStatus()
|
||||
{
|
||||
|
|
@ -27,20 +28,12 @@ PollingAppOfflineApplication::CheckAppOffline()
|
|||
SRWExclusiveLock lock(m_statusLock);
|
||||
if (ulCurrentTime - m_ulLastCheckTime > c_appOfflineRefreshIntervalMS)
|
||||
{
|
||||
try
|
||||
m_fAppOfflineFound = FileExists(m_appOfflineLocation);
|
||||
if(m_fAppOfflineFound)
|
||||
{
|
||||
m_fAppOfflineFound = is_regular_file(m_appOfflineLocation);
|
||||
if(m_fAppOfflineFound)
|
||||
{
|
||||
LOG_IF_FAILED(OnAppOfflineFound());
|
||||
}
|
||||
m_ulLastCheckTime = ulCurrentTime;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// is_regular_file might throw in very rare cases
|
||||
OBSERVE_CAUGHT_EXCEPTION();
|
||||
LOG_IF_FAILED(OnAppOfflineFound());
|
||||
}
|
||||
m_ulLastCheckTime = ulCurrentTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,3 +48,9 @@ std::filesystem::path PollingAppOfflineApplication::GetAppOfflineLocation(IHttpA
|
|||
{
|
||||
return std::filesystem::path(pApplication.GetApplicationPhysicalPath()) / "app_offline.htm";
|
||||
}
|
||||
|
||||
bool PollingAppOfflineApplication::FileExists(const std::filesystem::path& path)
|
||||
{
|
||||
std::error_code ec;
|
||||
return is_regular_file(path, ec) || ec.value() == ERROR_SHARING_VIOLATION;
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ public:
|
|||
protected:
|
||||
std::filesystem::path m_appOfflineLocation;
|
||||
static std::filesystem::path GetAppOfflineLocation(IHttpApplication& pApplication);
|
||||
|
||||
static bool FileExists(const std::filesystem::path& path);
|
||||
private:
|
||||
static const int c_appOfflineRefreshIntervalMS = 200;
|
||||
std::string m_strAppOfflineContent;
|
||||
|
|
@ -6,11 +6,9 @@
|
|||
#include <array>
|
||||
#include "proxymodule.h"
|
||||
#include "hostfxr_utility.h"
|
||||
#include "utility.h"
|
||||
#include "debugutil.h"
|
||||
#include "resources.h"
|
||||
#include "SRWExclusiveLock.h"
|
||||
#include "GlobalVersionUtility.h"
|
||||
#include "exceptions.h"
|
||||
#include "EventLog.h"
|
||||
#include "HandleWrapper.h"
|
||||
|
|
@ -95,8 +93,7 @@ Finished:
|
|||
if (FAILED(hr))
|
||||
{
|
||||
// Log the failure and update application info to not try again
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR,
|
||||
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG,
|
||||
httpApplication.GetApplicationId(),
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include "applicationmanager.h"
|
||||
|
||||
#include "proxymodule.h"
|
||||
#include "utility.h"
|
||||
#include "resources.h"
|
||||
#include "SRWExclusiveLock.h"
|
||||
#include "exceptions.h"
|
||||
|
|
@ -217,8 +216,7 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
|
|||
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG,
|
||||
path)))
|
||||
{
|
||||
UTILITY::LogEvent(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION,
|
||||
strEventMsg.QueryStr());
|
||||
}
|
||||
|
|
@ -248,8 +246,7 @@ Finished:
|
|||
ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG,
|
||||
pszApplicationId)))
|
||||
{
|
||||
UTILITY::LogEvent(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_RECYCLE_APP_FAILURE,
|
||||
strEventMsg.QueryStr());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "EventLog.h"
|
||||
#include "config_utility.h"
|
||||
#include "hostfxr_utility.h"
|
||||
#include "ahutil.h"
|
||||
|
||||
HRESULT
|
||||
|
|
@ -16,14 +15,10 @@ ASPNETCORE_SHIM_CONFIG::Populate(
|
|||
{
|
||||
STACK_STRU(strHostingModel, 12);
|
||||
STRU strApplicationFullPath;
|
||||
IAppHostAdminManager *pAdminManager = NULL;
|
||||
CComPtr<IAppHostElement> pAspNetCoreElement;
|
||||
|
||||
pAdminManager = pHttpServer->GetAdminManager();
|
||||
RETURN_IF_FAILED(m_struApplicationPhysicalPath.Copy(pHttpApplication->GetApplicationPhysicalPath()));
|
||||
|
||||
IAppHostAdminManager *pAdminManager = pHttpServer->GetAdminManager();
|
||||
const CComBSTR bstrAspNetCoreSection = CS_ASPNETCORE_SECTION;
|
||||
|
||||
const CComBSTR applicationConfigPath = pHttpApplication->GetAppConfigPath();
|
||||
|
||||
RETURN_IF_FAILED(pAdminManager->GetAdminSection(bstrAspNetCoreSection,
|
||||
|
|
@ -51,7 +46,10 @@ ASPNETCORE_SHIM_CONFIG::Populate(
|
|||
else
|
||||
{
|
||||
// block unknown hosting value
|
||||
EVENTLOG(g_hEventLog, UNKNOWN_HOSTING_MODEL_ERROR, strHostingModel.QueryStr());
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_UNKNOWN_HOSTING_MODEL_ERROR,
|
||||
ASPNETCORE_EVENT_UNKNOWN_HOSTING_MODEL_ERROR_MSG,
|
||||
strHostingModel.QueryStr());
|
||||
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,12 +32,6 @@ public:
|
|||
IHttpApplication *pHttpApplication
|
||||
);
|
||||
|
||||
STRU*
|
||||
QueryApplicationPhysicalPath()
|
||||
{
|
||||
return &m_struApplicationPhysicalPath;
|
||||
}
|
||||
|
||||
STRU*
|
||||
QueryProcessPath()
|
||||
{
|
||||
|
|
@ -71,9 +65,7 @@ private:
|
|||
|
||||
STRU m_struArguments;
|
||||
STRU m_struProcessPath;
|
||||
STRU m_struApplicationPhysicalPath;
|
||||
APP_HOSTING_MODEL m_hostingModel;
|
||||
STRU m_struHostFxrLocation;
|
||||
STRU m_struHandlerVersion;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
#include "proxymodule.h"
|
||||
#include "globalmodule.h"
|
||||
#include "acache.h"
|
||||
#include "utility.h"
|
||||
#include "debugutil.h"
|
||||
#include "resources.h"
|
||||
#include "exceptions.h"
|
||||
#include "EventLog.h"
|
||||
|
||||
DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2.dll");
|
||||
|
||||
|
|
@ -131,15 +131,9 @@ HRESULT
|
|||
if (fDisableANCM)
|
||||
{
|
||||
// Logging
|
||||
STACK_STRU(strEventMsg, 256);
|
||||
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||
ASPNETCORE_EVENT_MODULE_DISABLED_MSG)))
|
||||
{
|
||||
UTILITY::LogEvent(g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
ASPNETCORE_EVENT_MODULE_DISABLED,
|
||||
strEventMsg.QueryStr());
|
||||
}
|
||||
EventLog::Warn(
|
||||
ASPNETCORE_EVENT_MODULE_DISABLED,
|
||||
ASPNETCORE_EVENT_MODULE_DISABLED_MSG);
|
||||
// this will return 500 error to client
|
||||
// as we did not register the module
|
||||
goto Finished;
|
||||
|
|
|
|||
|
|
@ -193,12 +193,11 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="application.h" />
|
||||
<ClInclude Include="AppOfflineApplication.h" />
|
||||
<ClInclude Include="AppOfflineHandler.h" />
|
||||
<ClInclude Include="config_utility.h" />
|
||||
<ClInclude Include="Environment.h" />
|
||||
<ClInclude Include="EventLog.h" />
|
||||
<ClInclude Include="exceptions.h" />
|
||||
<ClInclude Include="file_utility.h" />
|
||||
<ClInclude Include="GlobalVersionUtility.h" />
|
||||
<ClInclude Include="fx_ver.h" />
|
||||
<ClInclude Include="HandleWrapper.h" />
|
||||
|
|
@ -206,28 +205,24 @@
|
|||
<ClInclude Include="hostfxr_utility.h" />
|
||||
<ClInclude Include="iapplication.h" />
|
||||
<ClInclude Include="debugutil.h" />
|
||||
<ClInclude Include="disconnectcontext.h" />
|
||||
<ClInclude Include="irequesthandler.h" />
|
||||
<ClInclude Include="PollingAppOfflineApplication.h" />
|
||||
<ClInclude Include="requesthandler.h" />
|
||||
<ClInclude Include="resources.h" />
|
||||
<ClInclude Include="SRWExclusiveLock.h" />
|
||||
<ClInclude Include="SRWSharedLock.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="sttimer.h" />
|
||||
<ClInclude Include="utility.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AppOfflineApplication.cpp" />
|
||||
<ClCompile Include="AppOfflineHandler.cpp" />
|
||||
<ClCompile Include="debugutil.cpp" />
|
||||
<ClCompile Include="Environment.cpp" />
|
||||
<ClCompile Include="EventLog.cpp" />
|
||||
<ClCompile Include="file_utility.cpp" />
|
||||
<ClCompile Include="fx_ver.cpp" />
|
||||
<ClCompile Include="GlobalVersionUtility.cpp" />
|
||||
<ClCompile Include="HandleWrapper.cpp" />
|
||||
<ClCompile Include="hostfxr_utility.cpp" />
|
||||
<ClCompile Include="hostfxroptions.cpp" />
|
||||
<ClCompile Include="PollingAppOfflineApplication.cpp" />
|
||||
<ClCompile Include="SRWExclusiveLock.cpp" />
|
||||
<ClCompile Include="SRWSharedLock.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
|
@ -236,7 +231,6 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utility.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#include "EventLog.h"
|
||||
#include "debugutil.h"
|
||||
|
||||
extern HANDLE g_hEventLog;
|
||||
|
||||
VOID
|
||||
EventLog::LogEvent(
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ LPCWSTR pstrMsg
|
||||
)
|
||||
{
|
||||
if (g_hEventLog != NULL)
|
||||
{
|
||||
ReportEventW(g_hEventLog,
|
||||
dwEventInfoType,
|
||||
0, // wCategory
|
||||
dwEventId,
|
||||
NULL, // lpUserSid
|
||||
1, // wNumStrings
|
||||
0, // dwDataSize,
|
||||
&pstrMsg,
|
||||
NULL // lpRawData
|
||||
);
|
||||
}
|
||||
|
||||
DebugPrintf(dwEventInfoType == EVENTLOG_ERROR_TYPE ? ASPNETCORE_DEBUG_FLAG_ERROR : ASPNETCORE_DEBUG_FLAG_INFO, "Event Log: %S", pstrMsg);
|
||||
}
|
||||
|
||||
VOID
|
||||
EventLog::LogEventF(
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ LPCWSTR pstrMsg,
|
||||
va_list argsList
|
||||
)
|
||||
{
|
||||
STACK_STRU ( strEventMsg, 256 );
|
||||
|
||||
if (SUCCEEDED(strEventMsg.SafeVsnwprintf(
|
||||
pstrMsg,
|
||||
argsList)))
|
||||
{
|
||||
EventLog::LogEvent(
|
||||
dwEventInfoType,
|
||||
dwEventId,
|
||||
strEventMsg.QueryStr());
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,65 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Utility.h"
|
||||
#include "resources.h"
|
||||
|
||||
extern HANDLE g_hEventLog;
|
||||
class EventLog
|
||||
{
|
||||
public:
|
||||
static
|
||||
VOID
|
||||
Error(
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ PCWSTR pstrMsg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, pstrMsg);
|
||||
LogEventF(EVENTLOG_ERROR_TYPE, dwEventId, pstrMsg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#define EVENTLOG(log, name, ...) UTILITY::LogEventF(log, ASPNETCORE_EVENT_ ## name ## _LEVEL, ASPNETCORE_EVENT_ ## name, ASPNETCORE_EVENT_ ## name ## _MSG, __VA_ARGS__)
|
||||
static
|
||||
VOID
|
||||
Info(
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ PCWSTR pstrMsg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, pstrMsg);
|
||||
LogEventF(EVENTLOG_INFORMATION_TYPE, dwEventId, pstrMsg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
Warn(
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ PCWSTR pstrMsg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, pstrMsg);
|
||||
LogEventF(EVENTLOG_WARNING_TYPE, dwEventId, pstrMsg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
private:
|
||||
static
|
||||
VOID
|
||||
LogEvent(
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ LPCWSTR pstrMsg
|
||||
);
|
||||
|
||||
static
|
||||
VOID
|
||||
LogEventF(
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
__in PCWSTR pstrMsg,
|
||||
va_list argsList
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "iapplication.h"
|
||||
#include "exceptions.h"
|
||||
#include "utility.h"
|
||||
#include "ntassert.h"
|
||||
#include "SRWExclusiveLock.h"
|
||||
|
||||
|
|
@ -73,7 +71,7 @@ public:
|
|||
|
||||
protected:
|
||||
SRWLOCK m_stateLock;
|
||||
bool m_fStopCalled;
|
||||
bool m_fStopCalled;
|
||||
|
||||
private:
|
||||
mutable LONG m_cRefs;
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ PrintDebugHeader()
|
|||
RETURN_LAST_ERROR_IF(!VerQueryValue(verData.data(), _T("\\StringFileInfo\\040904b0\\FileDescription"), &pvProductName, &iProductNameLen));
|
||||
|
||||
// Major, minor are stored in dwFileVersionMS field and patch, build in dwFileVersionLS field as pair of 32 bit numbers
|
||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, "Initializing logs for %S. File Version: %d.%d.%d.%d. Description: %S",
|
||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, "Initializing logs for %S. ProcessId: %d. File Version: %d.%d.%d.%d. Description: %S",
|
||||
path,
|
||||
GetCurrentProcessId(),
|
||||
( verInfo->dwFileVersionMS >> 16 ) & 0xffff,
|
||||
( verInfo->dwFileVersionMS >> 0 ) & 0xffff,
|
||||
( verInfo->dwFileVersionLS >> 16 ) & 0xffff,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,198 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#include "file_utility.h"
|
||||
|
||||
#include <Shlwapi.h>
|
||||
#include "debugutil.h"
|
||||
|
||||
HRESULT
|
||||
FILE_UTILITY::IsPathUnc(
|
||||
__in LPCWSTR pszPath,
|
||||
__out BOOL * pfIsUnc
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU strTempPath;
|
||||
|
||||
if ( pszPath == NULL || pfIsUnc == NULL )
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
hr = MakePathCanonicalizationProof( (LPWSTR) pszPath, &strTempPath );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
//
|
||||
// MakePathCanonicalizationProof will map \\?\UNC, \\.\UNC and \\ to \\?\UNC
|
||||
//
|
||||
(*pfIsUnc) = ( _wcsnicmp( strTempPath.QueryStr(), L"\\\\?\\UNC\\", 8 /* sizeof \\?\UNC\ */) == 0 );
|
||||
|
||||
Finished:
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
FILE_UTILITY::ConvertPathToFullPath(
|
||||
_In_ LPCWSTR pszPath,
|
||||
_In_ LPCWSTR pszRootPath,
|
||||
_Out_ STRU* pStruFullPath
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU strFileFullPath;
|
||||
LPWSTR pszFullPath = NULL;
|
||||
|
||||
// if relative path, prefix with root path and then convert to absolute path.
|
||||
if ( PathIsRelative(pszPath) )
|
||||
{
|
||||
hr = strFileFullPath.Copy(pszRootPath);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
if(!strFileFullPath.EndsWith(L"\\"))
|
||||
{
|
||||
hr = strFileFullPath.Append(L"\\");
|
||||
if(FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr = strFileFullPath.Append( pszPath );
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
pszFullPath = new WCHAR[ strFileFullPath.QueryCCH() + 1];
|
||||
|
||||
if(_wfullpath( pszFullPath,
|
||||
strFileFullPath.QueryStr(),
|
||||
strFileFullPath.QueryCCH() + 1 ) == NULL )
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
// convert to canonical path
|
||||
hr = MakePathCanonicalizationProof( pszFullPath, pStruFullPath );
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
Finished:
|
||||
|
||||
if ( pszFullPath != NULL )
|
||||
{
|
||||
delete[] pszFullPath;
|
||||
pszFullPath = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
FILE_UTILITY::EnsureDirectoryPathExist(
|
||||
_In_ LPCWSTR pszPath
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU struPath;
|
||||
DWORD dwPosition = 0;
|
||||
BOOL fDone = FALSE;
|
||||
BOOL fUnc = FALSE;
|
||||
|
||||
struPath.Copy(pszPath);
|
||||
hr = IsPathUnc(pszPath, &fUnc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
if (fUnc)
|
||||
{
|
||||
// "\\?\UNC\"
|
||||
dwPosition = 8;
|
||||
}
|
||||
else if (struPath.IndexOf(L'?', 0) != -1)
|
||||
{
|
||||
// sceanrio "\\?\"
|
||||
dwPosition = 4;
|
||||
}
|
||||
while (!fDone)
|
||||
{
|
||||
dwPosition = struPath.IndexOf(L'\\', dwPosition + 1);
|
||||
if (dwPosition == -1)
|
||||
{
|
||||
// not found '/'
|
||||
fDone = TRUE;
|
||||
goto Finished;
|
||||
}
|
||||
else if (dwPosition ==0)
|
||||
{
|
||||
hr = ERROR_INTERNAL_ERROR;
|
||||
goto Finished;
|
||||
}
|
||||
else if (struPath.QueryStr()[dwPosition-1] == L':')
|
||||
{
|
||||
// skip volume case
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
struPath.QueryStr()[dwPosition] = L'\0';
|
||||
}
|
||||
|
||||
if (!CreateDirectory(struPath.QueryStr(), NULL) &&
|
||||
ERROR_ALREADY_EXISTS != GetLastError())
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
fDone = TRUE;
|
||||
goto Finished;
|
||||
}
|
||||
struPath.QueryStr()[dwPosition] = L'\\';
|
||||
}
|
||||
|
||||
Finished:
|
||||
return hr;
|
||||
}
|
||||
|
||||
BOOL
|
||||
FILE_UTILITY::CheckIfFileExists(
|
||||
_In_ PCWSTR pszFilePath
|
||||
)
|
||||
{
|
||||
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
BOOL fFileExists = FALSE;
|
||||
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
hFileHandle = CreateFile(pszFilePath,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
&saAttr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
fFileExists = hFileHandle != INVALID_HANDLE_VALUE || GetLastError() == ERROR_SHARING_VIOLATION;
|
||||
|
||||
if (fFileExists)
|
||||
{
|
||||
CloseHandle(hFileHandle);
|
||||
}
|
||||
|
||||
return fFileExists;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <httpserv.h>
|
||||
#include "stringu.h"
|
||||
|
||||
class FILE_UTILITY
|
||||
{
|
||||
public:
|
||||
|
||||
static
|
||||
HRESULT
|
||||
ConvertPathToFullPath(
|
||||
_In_ LPCWSTR pszPath,
|
||||
_In_ LPCWSTR pszRootPath,
|
||||
_Out_ STRU* pStrFullPath
|
||||
);
|
||||
|
||||
static
|
||||
HRESULT
|
||||
EnsureDirectoryPathExist(
|
||||
_In_ LPCWSTR pszPath
|
||||
);
|
||||
|
||||
static
|
||||
BOOL
|
||||
CheckIfFileExists(
|
||||
PCWSTR pszFilePath
|
||||
);
|
||||
private:
|
||||
static
|
||||
HRESULT
|
||||
IsPathUnc(
|
||||
__in LPCWSTR pszPath,
|
||||
__out BOOL * pfIsUnc
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
#include "exceptions.h"
|
||||
#include "HandleWrapper.h"
|
||||
#include "Environment.h"
|
||||
#include "file_utility.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
|
@ -32,7 +33,6 @@ HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
|
|||
PCWSTR pwzExeAbsolutePath, // includes .exe file extension.
|
||||
PCWSTR pcwzApplicationPhysicalPath,
|
||||
PCWSTR pcwzArguments,
|
||||
HANDLE hEventLog,
|
||||
_Inout_ STRU* pStruHostFxrDllLocation,
|
||||
_Out_ DWORD* pdwArgCount,
|
||||
_Out_ BSTR** ppwzArgv
|
||||
|
|
@ -65,11 +65,19 @@ HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
|
|||
LOG_INFOF("Checking runtimeconfig.json at %S", runtimeConfigLocation.c_str());
|
||||
if (!is_regular_file(runtimeConfigLocation))
|
||||
{
|
||||
EVENTLOG(hEventLog, INPROCESS_FULL_FRAMEWORK_APP, pcwzApplicationPhysicalPath, 0);
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP,
|
||||
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP_MSG,
|
||||
pcwzApplicationPhysicalPath,
|
||||
0);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
EVENTLOG(hEventLog, APPLICATION_EXE_NOT_FOUND, pcwzApplicationPhysicalPath, 0);
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND,
|
||||
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_MSG,
|
||||
pcwzApplicationPhysicalPath,
|
||||
0);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +98,6 @@ HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
|
|||
arguments.c_str(),
|
||||
pwzExeAbsolutePath,
|
||||
pcwzApplicationPhysicalPath,
|
||||
hEventLog,
|
||||
pdwArgCount,
|
||||
ppwzArgv));
|
||||
|
||||
|
|
@ -107,7 +114,6 @@ HOSTFXR_UTILITY::IsDotnetExecutable(const std::filesystem::path & dotnetPath)
|
|||
|
||||
HRESULT
|
||||
HOSTFXR_UTILITY::GetHostFxrParameters(
|
||||
_In_ HANDLE hEventLog,
|
||||
_In_ PCWSTR pcwzProcessPath,
|
||||
_In_ PCWSTR pcwzApplicationPhysicalPath,
|
||||
_In_ PCWSTR pcwzArguments,
|
||||
|
|
@ -142,13 +148,17 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
if (!fullProcessPath.has_value())
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
EVENTLOG(hEventLog, INVALID_PROCESS_PATH, processPath.c_str(), hr);
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_INVALID_PROCESS_PATH,
|
||||
ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG,
|
||||
processPath.c_str(),
|
||||
hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
processPath = fullProcessPath.value();
|
||||
|
||||
auto hostFxrPath = GetAbsolutePathToHostFxr(processPath, hEventLog);
|
||||
auto hostFxrPath = GetAbsolutePathToHostFxr(processPath);
|
||||
if (!hostFxrPath.has_value())
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
|
|
@ -159,7 +169,6 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
arguments.c_str(),
|
||||
processPath.c_str(),
|
||||
pcwzApplicationPhysicalPath,
|
||||
hEventLog,
|
||||
pdwArgCount,
|
||||
pbstrArgv));
|
||||
|
||||
|
|
@ -186,7 +195,6 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
processPath.c_str(),
|
||||
pcwzApplicationPhysicalPath,
|
||||
arguments.c_str(),
|
||||
hEventLog,
|
||||
pStruHostFxrDllLocation,
|
||||
pdwArgCount,
|
||||
pbstrArgv));
|
||||
|
|
@ -200,7 +208,11 @@ HOSTFXR_UTILITY::GetHostFxrParameters(
|
|||
// then it is an invalid argument.
|
||||
//
|
||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
EVENTLOG(hEventLog, INVALID_PROCESS_PATH, processPath.c_str(), hr);
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_INVALID_PROCESS_PATH,
|
||||
ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG,
|
||||
processPath.c_str(),
|
||||
hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
|
@ -221,13 +233,10 @@ HOSTFXR_UTILITY::ParseHostfxrArguments(
|
|||
PCWSTR pwzArgumentsFromConfig,
|
||||
PCWSTR pwzExePath,
|
||||
PCWSTR pcwzApplicationPhysicalPath,
|
||||
HANDLE hEventLog,
|
||||
_Out_ DWORD* pdwArgCount,
|
||||
_Out_ BSTR** pbstrArgv
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hEventLog); // TODO use event log to set errors.
|
||||
|
||||
DBG_ASSERT(pdwArgCount != NULL);
|
||||
DBG_ASSERT(pbstrArgv != NULL);
|
||||
DBG_ASSERT(pwzExePath != NULL);
|
||||
|
|
@ -276,7 +285,7 @@ HOSTFXR_UTILITY::ParseHostfxrArguments(
|
|||
struTempPath.Copy(pwzArgs[intArgsProcessed]);
|
||||
if (struTempPath.EndsWith(L".dll"))
|
||||
{
|
||||
if (SUCCEEDED(UTILITY::ConvertPathToFullPath(pwzArgs[intArgsProcessed], pcwzApplicationPhysicalPath, &struTempPath)))
|
||||
if (SUCCEEDED(FILE_UTILITY::ConvertPathToFullPath(pwzArgs[intArgsProcessed], pcwzApplicationPhysicalPath, &struTempPath)))
|
||||
{
|
||||
argv[intArgsProcessed + 1] = SysAllocString(struTempPath.QueryStr());
|
||||
}
|
||||
|
|
@ -398,8 +407,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
|
|||
|
||||
std::optional<fs::path>
|
||||
HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
|
||||
const fs::path & dotnetPath,
|
||||
HANDLE hEventLog
|
||||
const fs::path & dotnetPath
|
||||
)
|
||||
{
|
||||
std::vector<std::wstring> versionFolders;
|
||||
|
|
@ -409,7 +417,7 @@ HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
|
|||
|
||||
if (!is_directory(hostFxrBase))
|
||||
{
|
||||
EVENTLOG(hEventLog, HOSTFXR_DIRECTORY_NOT_FOUND, hostFxrBase.c_str(), HRESULT_FROM_WIN32(ERROR_BAD_ENVIRONMENT));
|
||||
EventLog::Error(ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND, ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG, hostFxrBase.c_str(), HRESULT_FROM_WIN32(ERROR_BAD_ENVIRONMENT));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -419,7 +427,11 @@ HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
|
|||
|
||||
if (versionFolders.empty())
|
||||
{
|
||||
EVENTLOG(hEventLog, HOSTFXR_DIRECTORY_NOT_FOUND, hostFxrBase.c_str(), HRESULT_FROM_WIN32(ERROR_BAD_ENVIRONMENT));
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND,
|
||||
ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG,
|
||||
hostFxrBase.c_str(),
|
||||
HRESULT_FROM_WIN32(ERROR_BAD_ENVIRONMENT));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -429,7 +441,11 @@ HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
|
|||
|
||||
if (!is_regular_file(hostFxrPath))
|
||||
{
|
||||
EVENTLOG(hEventLog, HOSTFXR_DLL_NOT_FOUND, hostFxrPath.c_str(), HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND,
|
||||
ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG,
|
||||
hostFxrPath.c_str(),
|
||||
HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ public:
|
|||
PCWSTR pwzExeAbsolutePath, // includes .exe file extension.
|
||||
PCWSTR pcwzApplicationPhysicalPath,
|
||||
PCWSTR pcwzArguments,
|
||||
HANDLE hEventLog,
|
||||
_Inout_ STRU* pStruHostFxrDllLocation,
|
||||
_Out_ DWORD* pdwArgCount,
|
||||
_Out_ BSTR** ppwzArgv
|
||||
|
|
@ -36,7 +35,6 @@ public:
|
|||
PCWSTR pwzArgumentsFromConfig,
|
||||
PCWSTR pwzExePath,
|
||||
PCWSTR pcwzApplicationPhysicalPath,
|
||||
HANDLE hEventLog,
|
||||
_Out_ DWORD* pdwArgCount,
|
||||
_Out_ BSTR** pbstrArgv
|
||||
);
|
||||
|
|
@ -50,7 +48,6 @@ public:
|
|||
static
|
||||
HRESULT
|
||||
GetHostFxrParameters(
|
||||
_In_ HANDLE hEventLog,
|
||||
_In_ PCWSTR pcwzProcessPath,
|
||||
_In_ PCWSTR pcwzApplicationPhysicalPath,
|
||||
_In_ PCWSTR pcwzArguments,
|
||||
|
|
@ -76,8 +73,7 @@ public:
|
|||
static
|
||||
std::optional<std::filesystem::path>
|
||||
GetAbsolutePathToHostFxr(
|
||||
_In_ const std::filesystem::path & dotnetPath,
|
||||
_In_ HANDLE hEventLog
|
||||
_In_ const std::filesystem::path & dotnetPath
|
||||
);
|
||||
|
||||
static
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ HRESULT HOSTFXR_OPTIONS::Create(
|
|||
_In_ PCWSTR pcwzProcessPath,
|
||||
_In_ PCWSTR pcwzApplicationPhysicalPath,
|
||||
_In_ PCWSTR pcwzArguments,
|
||||
_In_ HANDLE hEventLog,
|
||||
_Out_ std::unique_ptr<HOSTFXR_OPTIONS>& ppWrapper)
|
||||
{
|
||||
STRU struHostFxrDllLocation;
|
||||
|
|
@ -30,7 +29,6 @@ HRESULT HOSTFXR_OPTIONS::Create(
|
|||
if (struExeLocation.IsEmpty())
|
||||
{
|
||||
RETURN_IF_FAILED(HOSTFXR_UTILITY::GetHostFxrParameters(
|
||||
hEventLog,
|
||||
pcwzProcessPath,
|
||||
pcwzApplicationPhysicalPath,
|
||||
pcwzArguments,
|
||||
|
|
@ -45,7 +43,6 @@ HRESULT HOSTFXR_OPTIONS::Create(
|
|||
pcwzArguments,
|
||||
pcwzExeLocation,
|
||||
pcwzApplicationPhysicalPath,
|
||||
hEventLog,
|
||||
&dwArgCount,
|
||||
&pwzArgv));
|
||||
}
|
||||
|
|
@ -55,7 +52,6 @@ HRESULT HOSTFXR_OPTIONS::Create(
|
|||
pcwzExeLocation,
|
||||
pcwzApplicationPhysicalPath,
|
||||
pcwzArguments,
|
||||
hEventLog,
|
||||
&struHostFxrDllLocation,
|
||||
&dwArgCount,
|
||||
&pwzArgv));
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ public:
|
|||
_In_ PCWSTR pcwzProcessPath,
|
||||
_In_ PCWSTR pcwzApplicationPhysicalPath,
|
||||
_In_ PCWSTR pcwzArguments,
|
||||
_In_ HANDLE hEventLog,
|
||||
_Out_ std::unique_ptr<HOSTFXR_OPTIONS>& ppWrapper);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#define ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG L"Only one inprocess application is allowed per IIS application pool. Please assign the application '%s' to a different IIS application pool."
|
||||
#define ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG L"Mixed hosting model is not supported. Application '%s' configured with different hostingModel value '%d' other than the one of running application(s)."
|
||||
#define ASPNETCORE_EVENT_UNKNOWN_HOSTING_MODEL_ERROR_MSG L"Unknown hosting model '%s'. Please specify either hostingModel=\"inprocess\" or hostingModel=\"outofprocess\" in the web.config file."
|
||||
#define ASPNETCORE_EVENT_UNKNOWN_HOSTING_MODEL_ERROR_LEVEL EVENTLOG_ERROR_TYPE
|
||||
#define ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG L"Failed to start application '%s', ErrorCode '0x%x'."
|
||||
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_STDOUT_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, ErrorCode = '0x%x. Last 4KB characters of captured stdout and stderr logs:\r\n%s"
|
||||
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, ErrorCode = '0x%x. Please check the stderr logs for more information."
|
||||
|
|
@ -40,17 +39,12 @@
|
|||
#define ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG L"Application '%s' was recycled due to configuration change"
|
||||
#define ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG L"Failed to recycle application due to a configuration change at '%s'. Recycling worker process."
|
||||
#define ASPNETCORE_EVENT_MODULE_DISABLED_MSG L"AspNetCore Module is disabled"
|
||||
#define ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP_LEVEL EVENTLOG_ERROR_TYPE
|
||||
#define ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP_MSG L"Application '%s' was compiled for .NET Framework. Please compile for .NET core to run the inprocess application or change the process mode to out of process. ErrorCode = '0x%x'."
|
||||
#define ASPNETCORE_EVENT_PORTABLE_APP_DOTNET_MISSING_MSG L"Could not find dotnet.exe on the system PATH environment variable for portable application '%s'. Check that a valid path to dotnet is on the PATH and the bitness of dotnet matches the bitness of the IIS worker process. ErrorCode = '0x%x'."
|
||||
#define ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_LEVEL EVENTLOG_ERROR_TYPE
|
||||
#define ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG L"Could not find the hostfxr directory '%s' in the dotnet directory. ErrorCode = '0x%x'."
|
||||
#define ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_LEVEL EVENTLOG_ERROR_TYPE
|
||||
#define ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG L"Could not find hostfxr.dll in '%s'. ErrorCode = '0x%x'."
|
||||
#define ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_LEVEL EVENTLOG_ERROR_TYPE
|
||||
#define ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_MSG L"Could not find application executable in '%s'. ErrorCode = '0x%x'."
|
||||
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, ErrorCode = '0x%x. Please check the stderr logs for more information."
|
||||
#define ASPNETCORE_EVENT_INVALID_PROCESS_PATH_LEVEL EVENTLOG_ERROR_TYPE
|
||||
#define ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG L"Invalid or unknown processPath provided in web.config: processPath = '%s', ErrorCode = '0x%x'."
|
||||
#define ASPNETCORE_EVENT_INPROCESS_RH_MISSING_MSG L"Could not find the assembly '%s' for in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application."
|
||||
#define ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG L"Could not find the assembly '%s' for out-of-process application. Please confirm the assembly is installed correctly for IIS or IISExpress."
|
||||
|
|
|
|||
|
|
@ -1,603 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
#include <Shlwapi.h>
|
||||
#include "debugutil.h"
|
||||
|
||||
// static
|
||||
HRESULT
|
||||
UTILITY::SplitUrl(
|
||||
PCWSTR pszDestinationUrl,
|
||||
BOOL *pfSecure,
|
||||
STRU *pstrDestination,
|
||||
STRU *pstrUrl
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Split the URL specified for forwarding into its specific components
|
||||
The format of the URL looks like
|
||||
http[s]://destination[:port]/path
|
||||
when port is omitted, the default port for that specific protocol is used
|
||||
when host is omitted, it gets the same value as the destination
|
||||
|
||||
Arguments:
|
||||
|
||||
pszDestinationUrl - the url to be split up
|
||||
pfSecure - SSL to be used in forwarding?
|
||||
pstrDestination - destination
|
||||
pDestinationPort - port
|
||||
pstrUrl - URL
|
||||
|
||||
Return Value:
|
||||
|
||||
HRESULT
|
||||
|
||||
--*/
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
//
|
||||
// First determine if the target is secure
|
||||
//
|
||||
if (_wcsnicmp(pszDestinationUrl, L"http://", 7) == 0)
|
||||
{
|
||||
*pfSecure = FALSE;
|
||||
pszDestinationUrl += 7;
|
||||
}
|
||||
else if (_wcsnicmp(pszDestinationUrl, L"https://", 8) == 0)
|
||||
{
|
||||
*pfSecure = TRUE;
|
||||
pszDestinationUrl += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
if (*pszDestinationUrl == L'\0')
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
//
|
||||
// Find the 3rd slash corresponding to the url
|
||||
//
|
||||
LPCWSTR pszSlash = wcschr(pszDestinationUrl, L'/');
|
||||
if (pszSlash == NULL)
|
||||
{
|
||||
if (FAILED(hr = pstrUrl->Copy(L"/", 1)) ||
|
||||
FAILED(hr = pstrDestination->Copy(pszDestinationUrl)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FAILED(hr = pstrUrl->Copy(pszSlash)) ||
|
||||
FAILED(hr = pstrDestination->Copy(pszDestinationUrl,
|
||||
(DWORD)(pszSlash - pszDestinationUrl))))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Change a hexadecimal digit to its numerical equivalent
|
||||
#define TOHEX( ch ) \
|
||||
((ch) > L'9' ? \
|
||||
(ch) >= L'a' ? \
|
||||
(ch) - L'a' + 10 : \
|
||||
(ch) - L'A' + 10 \
|
||||
: (ch) - L'0')
|
||||
|
||||
// static
|
||||
HRESULT
|
||||
UTILITY::UnEscapeUrl(
|
||||
PCWSTR pszUrl,
|
||||
DWORD cchUrl,
|
||||
bool fCopyQuery,
|
||||
STRA * pstrResult
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
CHAR pch[2];
|
||||
pch[1] = '\0';
|
||||
DWORD cchStart = 0;
|
||||
DWORD index = 0;
|
||||
|
||||
while (index < cchUrl &&
|
||||
(fCopyQuery || pszUrl[index] != L'?'))
|
||||
{
|
||||
switch (pszUrl[index])
|
||||
{
|
||||
case L'%':
|
||||
if (iswxdigit(pszUrl[index+1]) && iswxdigit(pszUrl[index+2]))
|
||||
{
|
||||
if (index > cchStart &&
|
||||
FAILED(hr = pstrResult->AppendW(pszUrl + cchStart,
|
||||
index - cchStart)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
cchStart = index+3;
|
||||
|
||||
pch[0] = static_cast<CHAR>(TOHEX(pszUrl[index+1]) * 16 +
|
||||
TOHEX(pszUrl[index+2]));
|
||||
if (FAILED(hr = pstrResult->Append(pch, 1)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
index += 3;
|
||||
break;
|
||||
}
|
||||
|
||||
__fallthrough;
|
||||
default:
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (index > cchStart)
|
||||
{
|
||||
return pstrResult->AppendW(pszUrl + cchStart,
|
||||
index - cchStart);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
HRESULT
|
||||
UTILITY::UnEscapeUrl(
|
||||
PCWSTR pszUrl,
|
||||
DWORD cchUrl,
|
||||
STRU * pstrResult
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
WCHAR pch[2];
|
||||
pch[1] = L'\0';
|
||||
DWORD cchStart = 0;
|
||||
DWORD index = 0;
|
||||
bool fInQuery = FALSE;
|
||||
|
||||
while (index < cchUrl)
|
||||
{
|
||||
switch (pszUrl[index])
|
||||
{
|
||||
case L'%':
|
||||
if (iswxdigit(pszUrl[index+1]) && iswxdigit(pszUrl[index+2]))
|
||||
{
|
||||
if (index > cchStart &&
|
||||
FAILED(hr = pstrResult->Append(pszUrl + cchStart,
|
||||
index - cchStart)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
cchStart = index+3;
|
||||
|
||||
pch[0] = static_cast<WCHAR>(TOHEX(pszUrl[index+1]) * 16 +
|
||||
TOHEX(pszUrl[index+2]));
|
||||
if (FAILED(hr = pstrResult->Append(pch, 1)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
index += 3;
|
||||
if (pch[0] == L'?')
|
||||
{
|
||||
fInQuery = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
break;
|
||||
|
||||
case L'/':
|
||||
if (fInQuery)
|
||||
{
|
||||
if (index > cchStart &&
|
||||
FAILED(hr = pstrResult->Append(pszUrl + cchStart,
|
||||
index - cchStart)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
cchStart = index+1;
|
||||
|
||||
if (FAILED(hr = pstrResult->Append(L"\\", 1)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
index += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
__fallthrough;
|
||||
default:
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (index > cchStart)
|
||||
{
|
||||
return pstrResult->Append(pszUrl + cchStart,
|
||||
index - cchStart);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
UTILITY::EscapeAbsPath(
|
||||
IHttpRequest * pRequest,
|
||||
STRU * strEscapedUrl
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU strAbsPath;
|
||||
LPCWSTR pszAbsPath = NULL;
|
||||
LPCWSTR pszFindStr = NULL;
|
||||
|
||||
hr = strAbsPath.Copy( pRequest->GetRawHttpRequest()->CookedUrl.pAbsPath,
|
||||
pRequest->GetRawHttpRequest()->CookedUrl.AbsPathLength / sizeof(WCHAR) );
|
||||
if(FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
pszAbsPath = strAbsPath.QueryStr();
|
||||
pszFindStr = wcschr(pszAbsPath, L'?');
|
||||
|
||||
while(pszFindStr != NULL)
|
||||
{
|
||||
strEscapedUrl->Append( pszAbsPath, pszFindStr - pszAbsPath);
|
||||
strEscapedUrl->Append(L"%3F");
|
||||
pszAbsPath = pszFindStr + 1;
|
||||
pszFindStr = wcschr(pszAbsPath, L'?');
|
||||
}
|
||||
|
||||
strEscapedUrl->Append(pszAbsPath);
|
||||
strEscapedUrl->Append(pRequest->GetRawHttpRequest()->CookedUrl.pQueryString,
|
||||
pRequest->GetRawHttpRequest()->CookedUrl.QueryStringLength / sizeof(WCHAR));
|
||||
|
||||
Finished:
|
||||
return hr;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
UTILITY::IsValidAttributeNameChar(
|
||||
WCHAR ch
|
||||
)
|
||||
{
|
||||
//
|
||||
// Values based on ASP.NET rendering for cookie names. RFC 2965 is not clear
|
||||
// what the non-special characters are.
|
||||
//
|
||||
return ch == L'\t' || (ch > 31 && ch < 127);
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
UTILITY::FindInMultiString(
|
||||
PCWSTR pszMultiString,
|
||||
PCWSTR pszStringToFind
|
||||
)
|
||||
{
|
||||
while (*pszMultiString != L'\0')
|
||||
{
|
||||
if (wcscmp(pszMultiString, pszStringToFind) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
pszMultiString += wcslen(pszMultiString) + 1;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
UTILITY::IsValidQueryStringName(
|
||||
PCWSTR pszName
|
||||
)
|
||||
{
|
||||
while (*pszName != L'\0')
|
||||
{
|
||||
WCHAR c = *pszName;
|
||||
if (c != L'-' && c != L'_' && c != L'+' &&
|
||||
c != L'.' && c != L'*' && c != L'$' && c != L'%' && c != L',' &&
|
||||
!iswalnum(c))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
pszName++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
UTILITY::IsValidHeaderName(
|
||||
PCWSTR pszName
|
||||
)
|
||||
{
|
||||
while (*pszName != L'\0')
|
||||
{
|
||||
WCHAR c = *pszName;
|
||||
if (c != L'-' && c != L'_' && c != L'+' &&
|
||||
c != L'.' && c != L'*' && c != L'$' && c != L'%'
|
||||
&& !iswalnum(c))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
pszName++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
UTILITY::IsPathUnc(
|
||||
__in LPCWSTR pszPath,
|
||||
__out BOOL * pfIsUnc
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU strTempPath;
|
||||
|
||||
if ( pszPath == NULL || pfIsUnc == NULL )
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
hr = MakePathCanonicalizationProof( (LPWSTR) pszPath, &strTempPath );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
//
|
||||
// MakePathCanonicalizationProof will map \\?\UNC, \\.\UNC and \\ to \\?\UNC
|
||||
//
|
||||
(*pfIsUnc) = ( _wcsnicmp( strTempPath.QueryStr(), L"\\\\?\\UNC\\", 8 /* sizeof \\?\UNC\ */) == 0 );
|
||||
|
||||
Finished:
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
UTILITY::ConvertPathToFullPath(
|
||||
_In_ LPCWSTR pszPath,
|
||||
_In_ LPCWSTR pszRootPath,
|
||||
_Out_ STRU* pStruFullPath
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU strFileFullPath;
|
||||
LPWSTR pszFullPath = NULL;
|
||||
|
||||
// if relative path, prefix with root path and then convert to absolute path.
|
||||
if ( PathIsRelative(pszPath) )
|
||||
{
|
||||
hr = strFileFullPath.Copy(pszRootPath);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
if(!strFileFullPath.EndsWith(L"\\"))
|
||||
{
|
||||
hr = strFileFullPath.Append(L"\\");
|
||||
if(FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr = strFileFullPath.Append( pszPath );
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
pszFullPath = new WCHAR[ strFileFullPath.QueryCCH() + 1];
|
||||
|
||||
if(_wfullpath( pszFullPath,
|
||||
strFileFullPath.QueryStr(),
|
||||
strFileFullPath.QueryCCH() + 1 ) == NULL )
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
// convert to canonical path
|
||||
hr = MakePathCanonicalizationProof( pszFullPath, pStruFullPath );
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
Finished:
|
||||
|
||||
if ( pszFullPath != NULL )
|
||||
{
|
||||
delete[] pszFullPath;
|
||||
pszFullPath = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
UTILITY::EnsureDirectoryPathExist(
|
||||
_In_ LPCWSTR pszPath
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU struPath;
|
||||
DWORD dwPosition = 0;
|
||||
BOOL fDone = FALSE;
|
||||
BOOL fUnc = FALSE;
|
||||
|
||||
struPath.Copy(pszPath);
|
||||
hr = IsPathUnc(pszPath, &fUnc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
if (fUnc)
|
||||
{
|
||||
// "\\?\UNC\"
|
||||
dwPosition = 8;
|
||||
}
|
||||
else if (struPath.IndexOf(L'?', 0) != -1)
|
||||
{
|
||||
// sceanrio "\\?\"
|
||||
dwPosition = 4;
|
||||
}
|
||||
while (!fDone)
|
||||
{
|
||||
dwPosition = struPath.IndexOf(L'\\', dwPosition + 1);
|
||||
if (dwPosition == -1)
|
||||
{
|
||||
// not found '/'
|
||||
fDone = TRUE;
|
||||
goto Finished;
|
||||
}
|
||||
else if (dwPosition ==0)
|
||||
{
|
||||
hr = ERROR_INTERNAL_ERROR;
|
||||
goto Finished;
|
||||
}
|
||||
else if (struPath.QueryStr()[dwPosition-1] == L':')
|
||||
{
|
||||
// skip volume case
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
struPath.QueryStr()[dwPosition] = L'\0';
|
||||
}
|
||||
|
||||
if (!CreateDirectory(struPath.QueryStr(), NULL) &&
|
||||
ERROR_ALREADY_EXISTS != GetLastError())
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
fDone = TRUE;
|
||||
goto Finished;
|
||||
}
|
||||
struPath.QueryStr()[dwPosition] = L'\\';
|
||||
}
|
||||
|
||||
Finished:
|
||||
return hr;
|
||||
}
|
||||
|
||||
BOOL
|
||||
UTILITY::DirectoryExists(
|
||||
_In_ STRU *pstrPath
|
||||
)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
|
||||
if (pstrPath->IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
|
||||
}
|
||||
|
||||
BOOL
|
||||
UTILITY::CheckIfFileExists(
|
||||
_In_ PCWSTR pszFilePath
|
||||
)
|
||||
{
|
||||
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
BOOL fFileExists = FALSE;
|
||||
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
hFileHandle = CreateFile(pszFilePath,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
&saAttr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
fFileExists = hFileHandle != INVALID_HANDLE_VALUE || GetLastError() == ERROR_SHARING_VIOLATION;
|
||||
|
||||
if (fFileExists)
|
||||
{
|
||||
CloseHandle(hFileHandle);
|
||||
}
|
||||
|
||||
return fFileExists;
|
||||
}
|
||||
|
||||
VOID
|
||||
UTILITY::LogEvent(
|
||||
_In_ HANDLE hEventLog,
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ LPCWSTR pstrMsg
|
||||
)
|
||||
{
|
||||
if (hEventLog != NULL)
|
||||
{
|
||||
ReportEventW(hEventLog,
|
||||
dwEventInfoType,
|
||||
0, // wCategory
|
||||
dwEventId,
|
||||
NULL, // lpUserSid
|
||||
1, // wNumStrings
|
||||
0, // dwDataSize,
|
||||
&pstrMsg,
|
||||
NULL // lpRawData
|
||||
);
|
||||
}
|
||||
|
||||
DebugPrintf(dwEventInfoType == EVENTLOG_ERROR_TYPE ? ASPNETCORE_DEBUG_FLAG_ERROR : ASPNETCORE_DEBUG_FLAG_INFO, "Event Log: %S", pstrMsg);
|
||||
}
|
||||
|
||||
VOID
|
||||
UTILITY::LogEventF(
|
||||
_In_ HANDLE hEventLog,
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ LPCWSTR pstrMsg,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list argsList;
|
||||
va_start(argsList, pstrMsg);
|
||||
|
||||
STACK_STRU ( strEventMsg, 256 );
|
||||
|
||||
if (SUCCEEDED(strEventMsg.SafeVsnwprintf(
|
||||
pstrMsg,
|
||||
argsList)))
|
||||
{
|
||||
UTILITY::LogEvent(hEventLog,
|
||||
dwEventInfoType,
|
||||
dwEventId,
|
||||
strEventMsg.QueryStr());
|
||||
}
|
||||
|
||||
va_end( argsList );
|
||||
}
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <httpserv.h>
|
||||
#include "stringa.h"
|
||||
#include "stringu.h"
|
||||
|
||||
class UTILITY
|
||||
{
|
||||
public:
|
||||
|
||||
static
|
||||
HRESULT
|
||||
SplitUrl(
|
||||
PCWSTR pszDestinationUrl,
|
||||
BOOL *pfSecure,
|
||||
STRU *pstrDestination,
|
||||
STRU *pstrUrl
|
||||
);
|
||||
|
||||
static
|
||||
HRESULT
|
||||
UnEscapeUrl(
|
||||
PCWSTR pszUrl,
|
||||
DWORD cchUrl,
|
||||
bool fCopyQuery,
|
||||
STRA * pstrResult
|
||||
);
|
||||
|
||||
static
|
||||
HRESULT
|
||||
UnEscapeUrl(
|
||||
PCWSTR pszUrl,
|
||||
DWORD cchUrl,
|
||||
STRU * pstrResult
|
||||
);
|
||||
|
||||
static HRESULT
|
||||
EscapeAbsPath(
|
||||
IHttpRequest * pRequest,
|
||||
STRU * strEscapedUrl
|
||||
);
|
||||
|
||||
static
|
||||
bool
|
||||
IsValidAttributeNameChar(
|
||||
WCHAR ch
|
||||
);
|
||||
|
||||
static
|
||||
bool
|
||||
IsValidQueryStringName(
|
||||
PCWSTR pszName
|
||||
);
|
||||
|
||||
static
|
||||
bool
|
||||
IsValidHeaderName(
|
||||
PCWSTR pszName
|
||||
);
|
||||
|
||||
static
|
||||
bool
|
||||
FindInMultiString(
|
||||
PCWSTR pszMultiString,
|
||||
PCWSTR pszStringToFind
|
||||
);
|
||||
|
||||
static
|
||||
HRESULT
|
||||
IsPathUnc(
|
||||
__in LPCWSTR pszPath,
|
||||
__out BOOL * pfIsUnc
|
||||
);
|
||||
|
||||
static
|
||||
HRESULT
|
||||
ConvertPathToFullPath(
|
||||
_In_ LPCWSTR pszPath,
|
||||
_In_ LPCWSTR pszRootPath,
|
||||
_Out_ STRU* pStrFullPath
|
||||
);
|
||||
|
||||
static
|
||||
HRESULT
|
||||
EnsureDirectoryPathExist(
|
||||
_In_ LPCWSTR pszPath
|
||||
);
|
||||
|
||||
static
|
||||
BOOL
|
||||
DirectoryExists(
|
||||
_In_ STRU *pstrPath
|
||||
);
|
||||
|
||||
static
|
||||
BOOL
|
||||
CheckIfFileExists(
|
||||
PCWSTR pszFilePath
|
||||
);
|
||||
|
||||
static
|
||||
VOID
|
||||
LogEvent(
|
||||
_In_ HANDLE hEventLog,
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
_In_ LPCWSTR pstrMsg
|
||||
);
|
||||
|
||||
static
|
||||
VOID
|
||||
LogEventF(
|
||||
_In_ HANDLE hEventLog,
|
||||
_In_ WORD dwEventInfoType,
|
||||
_In_ DWORD dwEventId,
|
||||
__in PCWSTR pstrMsg,
|
||||
...
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
UTILITY() {}
|
||||
~UTILITY() {}
|
||||
};
|
||||
|
||||
|
|
@ -6,11 +6,11 @@
|
|||
#include "hostfxroptions.h"
|
||||
#include "requesthandler_config.h"
|
||||
#include "environmentvariablehelpers.h"
|
||||
#include "utility.h"
|
||||
#include "SRWExclusiveLock.h"
|
||||
#include "exceptions.h"
|
||||
#include "LoggingHelpers.h"
|
||||
#include "resources.h"
|
||||
#include "EventLog.h"
|
||||
|
||||
const LPCSTR IN_PROCESS_APPLICATION::s_exeLocationParameterName = "InProcessExeLocation";
|
||||
|
||||
|
|
@ -112,16 +112,14 @@ Finished:
|
|||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
EventLog::Warn(
|
||||
ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE,
|
||||
ASPNETCORE_EVENT_APP_SHUTDOWN_FAILURE_MSG,
|
||||
m_pConfig->QueryConfigPath()->QueryStr());
|
||||
}
|
||||
else
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_APP_SHUTDOWN_SUCCESSFUL,
|
||||
ASPNETCORE_EVENT_APP_SHUTDOWN_SUCCESSFUL_MSG,
|
||||
m_pConfig->QueryConfigPath()->QueryStr());
|
||||
|
|
@ -220,8 +218,7 @@ IN_PROCESS_APPLICATION::SetCallbackHandles(
|
|||
|
||||
// Can't check the std err handle as it isn't a critical error
|
||||
// Initialization complete
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_INPROCESS_START_SUCCESS,
|
||||
ASPNETCORE_EVENT_INPROCESS_START_SUCCESS_MSG,
|
||||
m_pConfig->QueryApplicationPhysicalPath()->QueryStr());
|
||||
|
|
@ -361,8 +358,7 @@ Finished:
|
|||
{
|
||||
m_status = MANAGED_APPLICATION_STATUS::FAIL;
|
||||
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_LOAD_CLR_FALIURE,
|
||||
ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG,
|
||||
m_pConfig->QueryApplicationPath()->QueryStr(),
|
||||
|
|
@ -463,7 +459,6 @@ IN_PROCESS_APPLICATION::ExecuteApplication(
|
|||
m_pConfig->QueryProcessPath()->QueryStr(),
|
||||
m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
||||
m_pConfig->QueryArguments()->QueryStr(),
|
||||
g_hEventLog,
|
||||
hostFxrOptions
|
||||
));
|
||||
|
||||
|
|
@ -527,8 +522,7 @@ IN_PROCESS_APPLICATION::LogErrorsOnMainExit(
|
|||
if (m_pLoggerProvider->GetStdOutContent(&straStdErrOutput))
|
||||
{
|
||||
if (SUCCEEDED(struStdMsg.CopyA(straStdErrOutput.QueryStr()))) {
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_STDOUT,
|
||||
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_STDOUT_MSG,
|
||||
m_pConfig->QueryApplicationPath()->QueryStr(),
|
||||
|
|
@ -539,8 +533,7 @@ IN_PROCESS_APPLICATION::LogErrorsOnMainExit(
|
|||
}
|
||||
else
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT,
|
||||
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG,
|
||||
m_pConfig->QueryApplicationPath()->QueryStr(),
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@
|
|||
<ClInclude Include="responseheaderhash.h" />
|
||||
<ClInclude Include="serverprocess.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="url_utility.h" />
|
||||
<ClInclude Include="websockethandler.h" />
|
||||
<ClInclude Include="winhttphelper.h" />
|
||||
<ClInclude Include="forwardinghandler.h" />
|
||||
|
|
@ -251,6 +252,7 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="url_utility.cpp" />
|
||||
<ClCompile Include="websockethandler.cpp" />
|
||||
<ClCompile Include="winhttphelper.cpp" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <IPHlpApi.h>
|
||||
#include <VersionHelpers.h>
|
||||
#include "exceptions.h"
|
||||
|
||||
DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2_outofprocess.dll");
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#include "forwardinghandler.h"
|
||||
#include "url_utility.h"
|
||||
|
||||
// Just to be aware of the FORWARDING_HANDLER object size.
|
||||
C_ASSERT(sizeof(FORWARDING_HANDLER) <= 632);
|
||||
|
|
@ -164,7 +165,7 @@ FORWARDING_HANDLER::OnExecuteRequestHandler()
|
|||
//
|
||||
// parse original url
|
||||
//
|
||||
if (FAILED(hr = UTILITY::SplitUrl(pRequest->GetRawHttpRequest()->CookedUrl.pFullUrl,
|
||||
if (FAILED(hr = URL_UTILITY::SplitUrl(pRequest->GetRawHttpRequest()->CookedUrl.pFullUrl,
|
||||
&fSecure,
|
||||
&strDestination,
|
||||
&strUrl)))
|
||||
|
|
@ -172,7 +173,7 @@ FORWARDING_HANDLER::OnExecuteRequestHandler()
|
|||
goto Failure;
|
||||
}
|
||||
|
||||
if (FAILED(hr = UTILITY::EscapeAbsPath(pRequest, &struEscapedUrl)))
|
||||
if (FAILED(hr = URL_UTILITY::EscapeAbsPath(pRequest, &struEscapedUrl)))
|
||||
{
|
||||
goto Failure;
|
||||
}
|
||||
|
|
@ -870,7 +871,7 @@ FORWARDING_HANDLER::GetHeaders(
|
|||
//
|
||||
if (!pProtocol->QueryPreserveHostHeader())
|
||||
{
|
||||
if (FAILED(hr = UTILITY::SplitUrl(pRequest->GetRawHttpRequest()->CookedUrl.pFullUrl,
|
||||
if (FAILED(hr = URL_UTILITY::SplitUrl(pRequest->GetRawHttpRequest()->CookedUrl.pFullUrl,
|
||||
&fSecure,
|
||||
&struDestination,
|
||||
&struUrl)) ||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#include "processmanager.h"
|
||||
#include "EventLog.h"
|
||||
|
||||
volatile BOOL PROCESS_MANAGER::sm_fWSAStartupDone = FALSE;
|
||||
|
||||
|
|
@ -194,8 +195,7 @@ PROCESS_MANAGER::GetProcess(
|
|||
//
|
||||
// rapid fails per minute exceeded, do not create new process.
|
||||
//
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED,
|
||||
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG,
|
||||
pConfig->QueryRapidFailsPerMinute());
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include "serverprocess.h"
|
||||
|
||||
#include <IPHlpApi.h>
|
||||
#include "EventLog.h"
|
||||
#include "file_utility.h"
|
||||
//#include <share.h>
|
||||
|
||||
//extern BOOL g_fNsiApiNotSupported;
|
||||
|
|
@ -212,8 +214,7 @@ Finished:
|
|||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_PROCESS_START_SUCCESS,
|
||||
ASPNETCORE_EVENT_PROCESS_START_PORTSETUP_ERROR_MSG,
|
||||
m_struAppFullPath.QueryStr(),
|
||||
|
|
@ -735,9 +736,7 @@ Finished:
|
|||
|
||||
if (!strEventMsg.IsEmpty())
|
||||
{
|
||||
UTILITY::LogEvent(
|
||||
g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
EventLog::Warn(
|
||||
ASPNETCORE_EVENT_PROCESS_START_ERROR,
|
||||
strEventMsg.QueryStr());
|
||||
}
|
||||
|
|
@ -900,8 +899,7 @@ SERVER_PROCESS::StartProcess(
|
|||
// Backend process starts successfully. Set retry counter to 0
|
||||
dwRetryCount = 0;
|
||||
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_PROCESS_START_SUCCESS,
|
||||
ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG,
|
||||
m_struAppFullPath.QueryStr(),
|
||||
|
|
@ -918,8 +916,7 @@ SERVER_PROCESS::StartProcess(
|
|||
dwRetryCount = 0;
|
||||
}
|
||||
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
EventLog::Warn(
|
||||
ASPNETCORE_EVENT_PROCESS_START_ERROR,
|
||||
ASPNETCORE_EVENT_PROCESS_START_ERROR_MSG,
|
||||
m_struAppFullPath.QueryStr(),
|
||||
|
|
@ -963,8 +960,7 @@ Finished:
|
|||
m_Timer.CancelTimer();
|
||||
}
|
||||
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_ERROR_TYPE,
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_PROCESS_START_FAILURE,
|
||||
ASPNETCORE_EVENT_PROCESS_START_FAILURE_MSG,
|
||||
m_struAppFullPath.QueryStr(),
|
||||
|
|
@ -1034,7 +1030,7 @@ SERVER_PROCESS::SetupStdHandles(
|
|||
m_hStdoutHandle = NULL;
|
||||
}
|
||||
|
||||
hr = UTILITY::ConvertPathToFullPath(
|
||||
hr = FILE_UTILITY::ConvertPathToFullPath(
|
||||
m_struLogFile.QueryStr(),
|
||||
m_struPhysicalPath.QueryStr(),
|
||||
&struPath);
|
||||
|
|
@ -1058,7 +1054,7 @@ SERVER_PROCESS::SetupStdHandles(
|
|||
goto Finished;
|
||||
}
|
||||
|
||||
hr = UTILITY::EnsureDirectoryPathExist(struPath.QueryStr());
|
||||
hr = FILE_UTILITY::EnsureDirectoryPathExist(struPath.QueryStr());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
|
|
@ -1100,8 +1096,7 @@ Finished:
|
|||
if (m_fStdoutLogEnabled)
|
||||
{
|
||||
// Log the error
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
EventLog::Warn(
|
||||
ASPNETCORE_EVENT_CONFIG_ERROR,
|
||||
ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG,
|
||||
m_struFullLogFile.IsEmpty()? m_struLogFile.QueryStr() : m_struFullLogFile.QueryStr(),
|
||||
|
|
@ -1900,9 +1895,7 @@ SERVER_PROCESS::HandleProcessExit( VOID )
|
|||
|
||||
if (!fReady)
|
||||
{
|
||||
UTILITY::LogEventF(
|
||||
g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_PROCESS_SHUTDOWN,
|
||||
ASPNETCORE_EVENT_PROCESS_SHUTDOWN_MSG,
|
||||
m_struAppFullPath.QueryStr(),
|
||||
|
|
@ -2032,8 +2025,7 @@ SERVER_PROCESS::SendShutdownHttpMessage( VOID )
|
|||
}
|
||||
|
||||
// log
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST,
|
||||
ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST_MSG,
|
||||
m_dwProcessId,
|
||||
|
|
@ -2150,8 +2142,7 @@ SERVER_PROCESS::TerminateBackendProcess(
|
|||
}
|
||||
|
||||
// log a warning for ungraceful shutdown
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
EventLog::Warn(
|
||||
ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE,
|
||||
ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE_MSG,
|
||||
m_dwProcessId);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@
|
|||
|
||||
// Common lib
|
||||
#include "requesthandler.h"
|
||||
#include "utility.h"
|
||||
#include "application.h"
|
||||
#include "resources.h"
|
||||
#include "aspnetcore_event.h"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#include "url_utility.h"
|
||||
|
||||
#include <Shlwapi.h>
|
||||
#include "debugutil.h"
|
||||
|
||||
// static
|
||||
HRESULT
|
||||
URL_UTILITY::SplitUrl(
|
||||
PCWSTR pszDestinationUrl,
|
||||
BOOL *pfSecure,
|
||||
STRU *pstrDestination,
|
||||
STRU *pstrUrl
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Split the URL specified for forwarding into its specific components
|
||||
The format of the URL looks like
|
||||
http[s]://destination[:port]/path
|
||||
when port is omitted, the default port for that specific protocol is used
|
||||
when host is omitted, it gets the same value as the destination
|
||||
|
||||
Arguments:
|
||||
|
||||
pszDestinationUrl - the url to be split up
|
||||
pfSecure - SSL to be used in forwarding?
|
||||
pstrDestination - destination
|
||||
pDestinationPort - port
|
||||
pstrUrl - URL
|
||||
|
||||
Return Value:
|
||||
|
||||
HRESULT
|
||||
|
||||
--*/
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
//
|
||||
// First determine if the target is secure
|
||||
//
|
||||
if (_wcsnicmp(pszDestinationUrl, L"http://", 7) == 0)
|
||||
{
|
||||
*pfSecure = FALSE;
|
||||
pszDestinationUrl += 7;
|
||||
}
|
||||
else if (_wcsnicmp(pszDestinationUrl, L"https://", 8) == 0)
|
||||
{
|
||||
*pfSecure = TRUE;
|
||||
pszDestinationUrl += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
if (*pszDestinationUrl == L'\0')
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
//
|
||||
// Find the 3rd slash corresponding to the url
|
||||
//
|
||||
LPCWSTR pszSlash = wcschr(pszDestinationUrl, L'/');
|
||||
if (pszSlash == NULL)
|
||||
{
|
||||
if (FAILED(hr = pstrUrl->Copy(L"/", 1)) ||
|
||||
FAILED(hr = pstrDestination->Copy(pszDestinationUrl)))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FAILED(hr = pstrUrl->Copy(pszSlash)) ||
|
||||
FAILED(hr = pstrDestination->Copy(pszDestinationUrl,
|
||||
(DWORD)(pszSlash - pszDestinationUrl))))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Change a hexadecimal digit to its numerical equivalent
|
||||
#define TOHEX( ch ) \
|
||||
((ch) > L'9' ? \
|
||||
(ch) >= L'a' ? \
|
||||
(ch) - L'a' + 10 : \
|
||||
(ch) - L'A' + 10 \
|
||||
: (ch) - L'0')
|
||||
|
||||
HRESULT
|
||||
URL_UTILITY::EscapeAbsPath(
|
||||
IHttpRequest * pRequest,
|
||||
STRU * strEscapedUrl
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
STRU strAbsPath;
|
||||
LPCWSTR pszAbsPath = NULL;
|
||||
LPCWSTR pszFindStr = NULL;
|
||||
|
||||
hr = strAbsPath.Copy( pRequest->GetRawHttpRequest()->CookedUrl.pAbsPath,
|
||||
pRequest->GetRawHttpRequest()->CookedUrl.AbsPathLength / sizeof(WCHAR) );
|
||||
if(FAILED(hr))
|
||||
{
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
pszAbsPath = strAbsPath.QueryStr();
|
||||
pszFindStr = wcschr(pszAbsPath, L'?');
|
||||
|
||||
while(pszFindStr != NULL)
|
||||
{
|
||||
strEscapedUrl->Append( pszAbsPath, pszFindStr - pszAbsPath);
|
||||
strEscapedUrl->Append(L"%3F");
|
||||
pszAbsPath = pszFindStr + 1;
|
||||
pszFindStr = wcschr(pszAbsPath, L'?');
|
||||
}
|
||||
|
||||
strEscapedUrl->Append(pszAbsPath);
|
||||
strEscapedUrl->Append(pRequest->GetRawHttpRequest()->CookedUrl.pQueryString,
|
||||
pRequest->GetRawHttpRequest()->CookedUrl.QueryStringLength / sizeof(WCHAR));
|
||||
|
||||
Finished:
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <httpserv.h>
|
||||
#include "stringu.h"
|
||||
|
||||
class URL_UTILITY
|
||||
{
|
||||
public:
|
||||
|
||||
static
|
||||
HRESULT
|
||||
SplitUrl(
|
||||
PCWSTR pszDestinationUrl,
|
||||
BOOL *pfSecure,
|
||||
STRU *pstrDestination,
|
||||
STRU *pstrUrl
|
||||
);
|
||||
|
||||
static HRESULT
|
||||
EscapeAbsPath(
|
||||
IHttpRequest * pRequest,
|
||||
STRU * strEscapedUrl
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -13,12 +13,11 @@ HRESULT AppOfflineTrackingApplication::StartMonitoringAppOffline()
|
|||
|
||||
if (FAILED_LOG(hr))
|
||||
{
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
ASPNETCORE_EVENT_MONITOR_APPOFFLINE_ERROR,
|
||||
ASPNETCORE_EVENT_MONITOR_APPOFFLINE_ERROR_MSG,
|
||||
m_applicationPath.c_str(),
|
||||
hr);
|
||||
EventLog::Warn(
|
||||
ASPNETCORE_EVENT_MONITOR_APPOFFLINE_ERROR,
|
||||
ASPNETCORE_EVENT_MONITOR_APPOFFLINE_ERROR_MSG,
|
||||
m_applicationPath.c_str(),
|
||||
hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
|
|
@ -58,11 +57,10 @@ void AppOfflineTrackingApplication::OnAppOffline()
|
|||
}
|
||||
|
||||
LOG_INFOF("Received app_offline notification in application %S", m_applicationPath.c_str());
|
||||
UTILITY::LogEventF(g_hEventLog,
|
||||
EVENTLOG_INFORMATION_TYPE,
|
||||
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE,
|
||||
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_MSG,
|
||||
m_applicationPath.c_str());
|
||||
EventLog::Info(
|
||||
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE,
|
||||
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_MSG,
|
||||
m_applicationPath.c_str());
|
||||
|
||||
Stop(/*fServerInitiated*/ false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
#include "stdafx.h"
|
||||
#include "FileOutputManager.h"
|
||||
#include "sttimer.h"
|
||||
#include "utility.h"
|
||||
#include "exceptions.h"
|
||||
#include "debugutil.h"
|
||||
#include "SRWExclusiveLock.h"
|
||||
#include "file_utility.h"
|
||||
|
||||
FileOutputManager::FileOutputManager() :
|
||||
m_hLogFileHandle(INVALID_HANDLE_VALUE),
|
||||
|
|
@ -82,12 +82,12 @@ FileOutputManager::Start()
|
|||
SECURITY_ATTRIBUTES saAttr = { 0 };
|
||||
STRU struPath;
|
||||
|
||||
RETURN_IF_FAILED(UTILITY::ConvertPathToFullPath(
|
||||
RETURN_IF_FAILED(FILE_UTILITY::ConvertPathToFullPath(
|
||||
m_wsStdOutLogFileName.QueryStr(),
|
||||
m_wsApplicationPath.QueryStr(),
|
||||
&struPath));
|
||||
|
||||
RETURN_IF_FAILED(UTILITY::EnsureDirectoryPathExist(struPath.QueryStr()));
|
||||
RETURN_IF_FAILED(FILE_UTILITY::EnsureDirectoryPathExist(struPath.QueryStr()));
|
||||
|
||||
GetSystemTime(&systemTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "filewatcher.h"
|
||||
#include "debugutil.h"
|
||||
#include "AppOfflineTrackingApplication.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
FILE_WATCHER::FILE_WATCHER() :
|
||||
m_hCompletionPort(NULL),
|
||||
|
|
|
|||
|
|
@ -123,47 +123,61 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
|
|||
|
||||
private void GetLogsFromFile()
|
||||
{
|
||||
// Handle cases where debug file is redirected by test
|
||||
var debugLogLocations = new List<string>();
|
||||
if (IISDeploymentParameters.HandlerSettings.ContainsKey("debugFile"))
|
||||
try
|
||||
{
|
||||
debugLogLocations.Add(IISDeploymentParameters.HandlerSettings["debugFile"]);
|
||||
}
|
||||
|
||||
if (DeploymentParameters.EnvironmentVariables.ContainsKey("ASPNETCORE_MODULE_DEBUG_FILE"))
|
||||
{
|
||||
debugLogLocations.Add(DeploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_DEBUG_FILE"]);
|
||||
}
|
||||
|
||||
// default debug file name
|
||||
debugLogLocations.Add("aspnetcore-debug.log");
|
||||
|
||||
foreach (var debugLogLocation in debugLogLocations)
|
||||
{
|
||||
if (string.IsNullOrEmpty(debugLogLocation))
|
||||
// Handle cases where debug file is redirected by test
|
||||
var debugLogLocations = new List<string>();
|
||||
if (IISDeploymentParameters.HandlerSettings.ContainsKey("debugFile"))
|
||||
{
|
||||
continue;
|
||||
debugLogLocations.Add(IISDeploymentParameters.HandlerSettings["debugFile"]);
|
||||
}
|
||||
|
||||
var file = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, debugLogLocation);
|
||||
if (File.Exists(file))
|
||||
if (DeploymentParameters.EnvironmentVariables.ContainsKey("ASPNETCORE_MODULE_DEBUG_FILE"))
|
||||
{
|
||||
var lines = File.ReadAllLines(file);
|
||||
if (!lines.Any())
|
||||
debugLogLocations.Add(DeploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_DEBUG_FILE"]);
|
||||
}
|
||||
|
||||
// default debug file name
|
||||
debugLogLocations.Add("aspnetcore-debug.log");
|
||||
|
||||
foreach (var debugLogLocation in debugLogLocations)
|
||||
{
|
||||
if (string.IsNullOrEmpty(debugLogLocation))
|
||||
{
|
||||
Logger.LogInformation("Debug log file found but was empty");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var line in lines)
|
||||
var file = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, debugLogLocation);
|
||||
if (File.Exists(file))
|
||||
{
|
||||
Logger.LogInformation(line);
|
||||
var lines = File.ReadAllLines(file);
|
||||
if (!lines.Any())
|
||||
{
|
||||
Logger.LogInformation($"Debug log file {file} found but was empty");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
Logger.LogInformation(line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ANCM V1 does not support logs
|
||||
if (DeploymentParameters.AncmVersion == AncmVersion.AspNetCoreModuleV2)
|
||||
{
|
||||
throw new InvalidOperationException($"Unable to find non-empty debug log files. Tried: {string.Join(", ", debugLogLocations)}");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(_debugLogFile))
|
||||
{
|
||||
File.Delete(_debugLogFile);
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Not able to find non-empty debug log files. Tried: {string.Join(", ", debugLogLocations)}");
|
||||
}
|
||||
|
||||
public void StartIIS(Uri uri, string contentRoot)
|
||||
|
|
@ -339,6 +353,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
|
|||
throw new InvalidOperationException("Site not stopped yet");
|
||||
}
|
||||
|
||||
if (appPool.WorkerProcesses.Any(wp => wp.State == WorkerProcessState.Running ||
|
||||
wp.State == WorkerProcessState.Stopping))
|
||||
{
|
||||
throw new InvalidOperationException("WorkerProcess not stopped yet");
|
||||
}
|
||||
|
||||
if (!HostProcess.HasExited)
|
||||
{
|
||||
throw new InvalidOperationException("Site is stopped but host process is not");
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
|||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.ShutdownToken)]
|
||||
public async Task AppOfflineDroppedWhileSiteFailedToStartInRequestHandler_SiteStops_InProcess()
|
||||
{
|
||||
var deploymentResult = await DeployApp(HostingModel.InProcess);
|
||||
|
|
@ -95,7 +94,8 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
|||
Assert.Contains("500.30", await result.Content.ReadAsStringAsync());
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
AssertStopsProcess(deploymentResult);
|
||||
|
||||
await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
|
|
@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
|||
}
|
||||
catch
|
||||
{
|
||||
AssertStopsProcess(deploymentResult);
|
||||
deploymentResult.AssertWorkerProcessStop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -139,18 +139,16 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
|||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.ShutdownToken)]
|
||||
public async Task AppOfflineDroppedWhileSiteRunning_SiteShutsDown_InProcess()
|
||||
{
|
||||
var deploymentResult = await AssertStarts(HostingModel.InProcess);
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
AssertStopsProcess(deploymentResult);
|
||||
await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.ShutdownToken)]
|
||||
public async Task AppOfflineDroppedWhileSiteRunning_SiteShutsDown_OutOfProcess()
|
||||
{
|
||||
var deploymentResult = await AssertStarts(HostingModel.OutOfProcess);
|
||||
|
|
@ -245,28 +243,10 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
|||
|
||||
private async Task AssertAppOffline(IISDeploymentResult deploymentResult, string expectedResponse = "The app is offline.")
|
||||
{
|
||||
HttpResponseMessage response = null;
|
||||
|
||||
for (var i = 0; i < 5 && response?.StatusCode != HttpStatusCode.ServiceUnavailable; i++)
|
||||
{
|
||||
// Keep retrying until app_offline is present.
|
||||
response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
await Task.Delay(RetryDelay);
|
||||
}
|
||||
|
||||
Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode);
|
||||
|
||||
var response = await deploymentResult.HttpClient.RetryRequestAsync("HelloWorld", r => r.StatusCode == HttpStatusCode.ServiceUnavailable);
|
||||
Assert.Equal(expectedResponse, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
private void AssertStopsProcess(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var hostShutdownToken = deploymentResult.HostShutdownToken;
|
||||
|
||||
Assert.True(hostShutdownToken.WaitHandle.WaitOne(TimeoutExtensions.DefaultTimeout));
|
||||
Assert.True(hostShutdownToken.IsCancellationRequested);
|
||||
}
|
||||
|
||||
private async Task<IISDeploymentResult> AssertStarts(HostingModel hostingModel)
|
||||
{
|
||||
var deploymentResult = await DeployApp(hostingModel);
|
||||
|
|
@ -278,14 +258,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
|||
|
||||
private static async Task AssertRunning(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
HttpResponseMessage response = null;
|
||||
|
||||
for (var i = 0; i < 5 && response?.IsSuccessStatusCode != true; i++)
|
||||
{
|
||||
response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
await Task.Delay(RetryDelay);
|
||||
}
|
||||
|
||||
var response = await deploymentResult.HttpClient.RetryRequestAsync("HelloWorld", r => r.IsSuccessStatusCode);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("Hello World", responseText);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class ConfigurationChangeTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public ConfigurationChangeTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ConfigurationChangeStopsInProcess()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.InProcess, publish: true);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await deploymentResult.AssertStarts();
|
||||
|
||||
// Just "touching" web.config should be enough
|
||||
deploymentResult.ModifyWebConfig(element => {});
|
||||
|
||||
await deploymentResult.AssertRecycledAsync();
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AncmVersion.AspNetCoreModule)]
|
||||
[InlineData(AncmVersion.AspNetCoreModuleV2)]
|
||||
public async Task ConfigurationChangeForcesChildProcessRestart(AncmVersion version)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
|
||||
deploymentParameters.AncmVersion = version;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
||||
|
||||
// Just "touching" web.config should be enough
|
||||
deploymentResult.ModifyWebConfig(element => {});
|
||||
|
||||
// Have to retry here to allow ANCM to receive notification and react to it
|
||||
// Verify that worker process gets restarted with new process id
|
||||
await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() != processBefore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
|
@ -18,6 +17,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
{
|
||||
public static class Helpers
|
||||
{
|
||||
private static readonly TimeSpan RetryRequestDelay = TimeSpan.FromMilliseconds(100);
|
||||
private static readonly int RetryRequestCount = 5;
|
||||
|
||||
public static string GetTestWebSitePath(string name)
|
||||
{
|
||||
return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name);
|
||||
|
|
@ -26,9 +28,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
public static string GetInProcessTestSitesPath() => GetTestWebSitePath("InProcessWebSite");
|
||||
|
||||
public static string GetOutOfProcessTestSitesPath() => GetTestWebSitePath("OutOfProcessWebSite");
|
||||
|
||||
|
||||
public static async Task AssertStarts(IISDeploymentResult deploymentResult, string path = "/HelloWorld")
|
||||
public static async Task AssertStarts(this IISDeploymentResult deploymentResult, string path = "/HelloWorld")
|
||||
{
|
||||
var response = await deploymentResult.HttpClient.GetAsync(path);
|
||||
|
||||
|
|
@ -73,5 +74,64 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
fileInfo.CopyTo(destFileName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ModifyWebConfig(this DeploymentResult deploymentResult, Action<XElement> action)
|
||||
{
|
||||
var webConfigPath = Path.Combine(deploymentResult.ContentRoot, "web.config");
|
||||
var document = XDocument.Load(webConfigPath);
|
||||
|
||||
document.Save(webConfigPath);
|
||||
}
|
||||
|
||||
public static Task<HttpResponseMessage> RetryRequestAsync(this HttpClient client, string uri, Func<HttpResponseMessage, bool> predicate)
|
||||
{
|
||||
return RetryRequestAsync(client, uri, message => Task.FromResult(predicate(message)));
|
||||
}
|
||||
|
||||
public static async Task<HttpResponseMessage> RetryRequestAsync(this HttpClient client, string uri, Func<HttpResponseMessage, Task<bool>> predicate)
|
||||
{
|
||||
HttpResponseMessage response = await client.GetAsync(uri);
|
||||
|
||||
for (var i = 0; i < RetryRequestCount && !await predicate(response); i++)
|
||||
{
|
||||
// Keep retrying until app_offline is present.
|
||||
response = await client.GetAsync(uri);
|
||||
await Task.Delay(RetryRequestDelay);
|
||||
}
|
||||
|
||||
if (!await predicate(response))
|
||||
{
|
||||
throw new InvalidOperationException($"Didn't get response that satisfies predicate after {RetryRequestCount} retries");
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public static void AssertWorkerProcessStop(this IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var hostProcess = deploymentResult.HostProcess;
|
||||
Assert.True(hostProcess.WaitForExit((int)TimeoutExtensions.DefaultTimeout.TotalMilliseconds));
|
||||
|
||||
if (deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress)
|
||||
{
|
||||
Assert.Equal(0, hostProcess.ExitCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async Task AssertRecycledAsync(this IISDeploymentResult deploymentResult, Func<Task> verificationAction = null)
|
||||
{
|
||||
if (deploymentResult.DeploymentParameters.HostingModel != HostingModel.InProcess)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
deploymentResult.AssertWorkerProcessStop();
|
||||
if (deploymentResult.DeploymentParameters.ServerType == ServerType.IIS)
|
||||
{
|
||||
verificationAction = verificationAction ?? (() => deploymentResult.AssertStarts());
|
||||
await verificationAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "file_utility.h"
|
||||
|
||||
TEST(ParseHostFxrArguments, BasicHostFxrArguments)
|
||||
{
|
||||
|
|
@ -12,7 +13,6 @@ TEST(ParseHostFxrArguments, BasicHostFxrArguments)
|
|||
L"exec \"test.dll\"", // args
|
||||
exeStr, // exe path
|
||||
L"invalid", // physical path to application
|
||||
NULL, // event log
|
||||
&retVal, // arg count
|
||||
&bstrArray); // args array.
|
||||
|
||||
|
|
@ -33,7 +33,6 @@ TEST(ParseHostFxrArguments, NoExecProvided)
|
|||
L"test.dll", // args
|
||||
exeStr, // exe path
|
||||
L"ignored", // physical path to application
|
||||
NULL, // event log
|
||||
&retVal, // arg count
|
||||
&bstrArray); // args array.
|
||||
|
||||
|
|
@ -53,7 +52,6 @@ TEST(ParseHostFxrArguments, ConvertDllToAbsolutePath)
|
|||
L"exec \"test.dll\"", // args
|
||||
exeStr, // exe path
|
||||
L"C:/test", // physical path to application
|
||||
NULL, // event log
|
||||
&retVal, // arg count
|
||||
&bstrArray); // args array.
|
||||
|
||||
|
|
@ -74,7 +72,6 @@ TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs)
|
|||
L"", // args
|
||||
exeStr, // exe path
|
||||
L"ignored", // physical path to application
|
||||
NULL, // event log
|
||||
&retVal, // arg count
|
||||
&bstrArray); // args array.
|
||||
|
||||
|
|
@ -101,11 +98,11 @@ TEST(GetAbsolutePathToDotnetFromProgramFiles, BackupWorks)
|
|||
|
||||
if (is64Bit)
|
||||
{
|
||||
fDotnetInProgramFiles = UTILITY::CheckIfFileExists(L"C:/Program Files/dotnet/dotnet.exe");
|
||||
fDotnetInProgramFiles = FILE_UTILITY::CheckIfFileExists(L"C:/Program Files/dotnet/dotnet.exe");
|
||||
}
|
||||
else
|
||||
{
|
||||
fDotnetInProgramFiles = UTILITY::CheckIfFileExists(L"C:/Program Files (x86)/dotnet/dotnet.exe");
|
||||
fDotnetInProgramFiles = FILE_UTILITY::CheckIfFileExists(L"C:/Program Files (x86)/dotnet/dotnet.exe");
|
||||
}
|
||||
|
||||
auto dotnetPath = HOSTFXR_UTILITY::GetAbsolutePathToDotnetFromProgramFiles();
|
||||
|
|
@ -127,11 +124,10 @@ TEST(GetHostFxrArguments, InvalidParams)
|
|||
STRU struExeLocation;
|
||||
|
||||
HRESULT hr = HOSTFXR_UTILITY::GetHostFxrParameters(
|
||||
INVALID_HANDLE_VALUE,
|
||||
L"bogus", // processPath
|
||||
L"", // application physical path, ignored.
|
||||
L"ignored", //arguments
|
||||
NULL, // event log
|
||||
NULL,
|
||||
&struExeLocation,
|
||||
&retVal, // arg count
|
||||
&bstrArray); // args array.
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
#include "config_utility.h"
|
||||
#include "environmentvariablehash.h"
|
||||
#include "iapplication.h"
|
||||
#include "utility.h"
|
||||
#include "debugutil.h"
|
||||
#include "requesthandler.h"
|
||||
#include "resources.h"
|
||||
|
|
|
|||
Loading…
Reference in New Issue