Merge branch 'merge/release/2.2-to-master'

This commit is contained in:
Pavel Krymets 2018-08-14 12:44:37 -07:00
commit 8b822d4314
49 changed files with 850 additions and 984 deletions

View File

@ -4,6 +4,7 @@
<PropertyGroup>
<AssemblySigningCertName>Microsoft</AssemblySigningCertName>
<AncmZipOutputPath>$(BuildDir)AspNetCoreModule.zip</AncmZipOutputPath>
<StressTestWebSiteZipOutputPath>$(BuildDir)StressTestWebSite.zip</StressTestWebSiteZipOutputPath>
</PropertyGroup>
<ItemGroup>

View File

@ -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="&quot;$(VisualStudioMSBuildx86Path)&quot; &quot;$(RepositoryRoot)test\CommonLibTests\CommonLibTests.vcxproj&quot; /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>

View File

@ -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));
}

View File

@ -3,7 +3,7 @@
#pragma once
#include "application.h"
#include <string>
#include "requesthandler.h"
class AppOfflineHandler: public REQUEST_HANDLER

View File

@ -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>

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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(),

View File

@ -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());
}

View File

@ -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));
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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">

View File

@ -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());
}
}

View File

@ -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
);
};

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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
);
};

View File

@ -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;
}

View File

@ -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

View File

@ -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));

View File

@ -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:

View File

@ -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."

View File

@ -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 );
}

View File

@ -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() {}
};

View File

@ -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(),

View File

@ -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>

View File

@ -2,6 +2,7 @@
#include <IPHlpApi.h>
#include <VersionHelpers.h>
#include "exceptions.h"
DECLARE_DEBUG_PRINT_OBJECT("aspnetcorev2_outofprocess.dll");

View File

@ -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)) ||

View File

@ -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());

View File

@ -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);

View File

@ -55,7 +55,6 @@
// Common lib
#include "requesthandler.h"
#include "utility.h"
#include "application.h"
#include "resources.h"
#include "aspnetcore_event.h"

View File

@ -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;
}

View File

@ -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
);
};

View File

@ -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);
}

View File

@ -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);

View File

@ -5,6 +5,7 @@
#include "filewatcher.h"
#include "debugutil.h"
#include "AppOfflineTrackingApplication.h"
#include "exceptions.h"
FILE_WATCHER::FILE_WATCHER() :
m_hCompletionPort(NULL),

View File

@ -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");

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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.

View File

@ -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"