* Init check in for refactoring

* clean up to make app_offline work

* update loadassembly and build

* add configpath to aspnetcore_config to make recycle work

* Adds in process component to refactor (#249)

* outprocess first checkin (still missing marjor components)

* Adds In-Process support for shimmed module. (#257)

* Init check in for refactoring

* clean up to make app_offline work

* update loadassembly and build

* add configpath to aspnetcore_config to make recycle work

* Adds in process component to refactor (#249)

* outprocess first checkin (still missing marjor components)

* Adds In-Process support for shimmed module. (#257)

* load from bin start and catch unhandled exception

* Fixes request handler vcxproj

* Adds request handler to nuget package

* build issues

* outofprocess refactoring

* adding logging support

* enforce Warning As Error for build and enable process recycle for outofprocess

* fix AV for win32 build and update build flags

* Fixed m_srwLock lock issue

* remove dealock in loadmanagedapp and remove UseMFC

* Readd lost exception catching

* nuget package issue and status code

* fixing warnings

* Adds Headers

* removing web sockets exe for now

* remove flags

* nuspec stuff

* spelling

* only look in inetsvr for now (or same folder)

* rename method

* terminte thread before closing the handle to it

* couple changes related with AV

* null check and Kill thread for in process if dotnet timed out

* fix recursive lock issue reported by appverifier

* client disconnect support AV fix

* flow 502.5 process start failure error page

* Feedback from inperson code review
This commit is contained in:
pan-wang 2017-12-18 14:19:15 -08:00 коммит произвёл GitHub
Родитель 588f0768e1
Коммит 3b6a01945e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
90 изменённых файлов: 7288 добавлений и 5597 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -32,12 +32,15 @@ project.lock.json
*.obj
*.tlog
*.CppClean.log
*msbuild.log
src/*/Debug/
src/*/x64/Debug/
src/*/Release/
src/*/x64/Release/
x64/
*vcxproj.filters
*.aps
*.pdb
*.lib

Просмотреть файл

@ -8,6 +8,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCore", "src\AspNetCor
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandler", "src\RequestHandler\RequestHandler.vcxproj", "{D57EA297-6DC2-4BC0-8C91-334863327863}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IISLib", "src\IISLib\IISLib.vcxproj", "{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{02F461DC-5166-4E88-AAD5-CF110016A647}"
@ -23,6 +25,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
NuGet.Config = NuGet.Config
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "src\CommonLib\CommonLib.vcxproj", "{55494E58-E061-4C4C-A0A8-837008E72F85}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -34,8 +38,8 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Any CPU.ActiveCfg = Debug|Win32
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Win32.ActiveCfg = Release|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Win32.Build.0 = Release|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Win32.ActiveCfg = Debug|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Win32.Build.0 = Debug|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x64.ActiveCfg = Debug|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x64.Build.0 = Debug|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|Any CPU.ActiveCfg = Release|Win32
@ -43,9 +47,19 @@ Global
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|Win32.Build.0 = Release|Win32
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.ActiveCfg = Release|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.Build.0 = Release|x64
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|Any CPU.ActiveCfg = Debug|Win32
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|Win32.ActiveCfg = Debug|x64
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|Win32.Build.0 = Debug|x64
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|x64.ActiveCfg = Debug|x64
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|x64.Build.0 = Debug|x64
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|Any CPU.ActiveCfg = Release|Win32
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|Win32.ActiveCfg = Release|Win32
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|Win32.Build.0 = Release|Win32
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x64.ActiveCfg = Release|x64
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x64.Build.0 = Release|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Any CPU.ActiveCfg = Debug|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Win32.ActiveCfg = Release|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Win32.Build.0 = Release|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Win32.ActiveCfg = Debug|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Win32.Build.0 = Debug|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|x64.ActiveCfg = Debug|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|x64.Build.0 = Debug|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|Any CPU.ActiveCfg = Release|Win32
@ -77,15 +91,31 @@ Global
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Win32.Build.0 = Release|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|x64.ActiveCfg = Release|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|x64.Build.0 = Release|Any CPU
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Any CPU.ActiveCfg = Debug|Win32
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Win32.ActiveCfg = Debug|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Win32.Build.0 = Debug|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Win32.Deploy.0 = Debug|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|x64.ActiveCfg = Debug|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|x64.Build.0 = Debug|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|x64.Deploy.0 = Debug|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Any CPU.ActiveCfg = Release|Win32
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Win32.ActiveCfg = Release|Win32
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Win32.Build.0 = Release|Win32
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Win32.Deploy.0 = Release|Win32
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|x64.ActiveCfg = Release|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|x64.Build.0 = Release|x64
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
{D57EA297-6DC2-4BC0-8C91-334863327863} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
{4DDA7560-AA29-4161-A5EA-A7E8F3997321} = {02F461DC-5166-4E88-AAD5-CF110016A647}
{030225D8-4EE8-47E5-B692-2A96B3B51A38} = {02F461DC-5166-4E88-AAD5-CF110016A647}
{55494E58-E061-4C4C-A0A8-837008E72F85} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0967E9B4-FEE7-40D7-860A-23E340E65840}

Просмотреть файл

@ -3,6 +3,7 @@
<Import Project="$(MSBuildThisFileDirectory)\Build.Settings" />
<ItemGroup>
<Projects Include="$(SolutionDir)\src\AspNetCore\AspNetCore.vcxproj" />
<Projects Include="$(SolutionDir)\src\RequestHandler\RequestHandler.vcxproj" />
</ItemGroup>
<Target Name="Build">

Просмотреть файл

@ -16,6 +16,8 @@
<Exec Command="&quot;$(VisualStudioMSBuildx86Path)&quot; &quot;$(RepositoryRoot)src\AspNetCore\AspNetCore.vcxproj&quot; %(BuildConfigurations.Identity)"
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
<Exec Command="&quot;$(VisualStudioMSBuildx86Path)&quot; &quot;$(RepositoryRoot)src\RequestHandler\RequestHandler.vcxproj&quot; %(BuildConfigurations.Identity)"
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
</Target>
<Target Name="PackageProjects">

Просмотреть файл

@ -20,6 +20,8 @@
<files>
<file src="..\artifacts\build\AspNetCore\bin\Release\Win32\aspnetcore.dll" target="contentFiles\any\any\x86\aspnetcore.dll" />
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\aspnetcore.dll" target="contentFiles\any\any\x64\aspnetcore.dll" />
<file src="..\artifacts\build\AspNetCore\bin\Release\Win32\aspnetcorerh.dll" target="contentFiles\any\any\x86\aspnetcorerh.dll" />
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\aspnetcorerh.dll" target="contentFiles\any\any\x64\aspnetcorerh.dll" />
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\*.xml"/>
<file src="..\tools\installancm.ps1"/>
<file src="..\LICENSE.txt"/>

Просмотреть файл

@ -3,6 +3,8 @@
<PropertyGroup>
<AspNetCoreModuleX64Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x64\aspnetcore.dll</AspNetCoreModuleX64Location>
<AspNetCoreModuleX86Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x86\aspnetcore.dll</AspNetCoreModuleX86Location>
<RequestHandlerX64Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x64\aspnetcorerh.dll</RequestHandlerX64Location>
<RequestHandlerX86Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x86\aspnetcorerh.dll</RequestHandlerX86Location>
</PropertyGroup>
</Project>

Просмотреть файл

@ -40,7 +40,6 @@
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@ -75,16 +74,34 @@
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -104,6 +121,17 @@
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -123,6 +151,17 @@
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -144,6 +183,17 @@
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -155,52 +205,22 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Inc\aspnetcore_event.h" />
<ClInclude Include="Inc\applicationinfo.h" />
<ClInclude Include="Inc\appoffline.h" />
<ClInclude Include="inc\globalmodule.h" />
<ClInclude Include="Inc\resource.h" />
<ClInclude Include="Inc\application.h" />
<ClInclude Include="Inc\applicationmanager.h" />
<ClInclude Include="Inc\aspnetcoreconfig.h" />
<ClInclude Include="Inc\environmentvariablehash.h" />
<ClInclude Include="Inc\debugutil.h" />
<ClInclude Include="Inc\filewatcher.h" />
<ClInclude Include="Inc\forwarderconnection.h" />
<ClInclude Include="Inc\forwardinghandler.h" />
<ClInclude Include="Inc\path.h" />
<ClInclude Include="Inc\processmanager.h" />
<ClInclude Include="Inc\protocolconfig.h" />
<ClInclude Include="Inc\proxymodule.h" />
<ClInclude Include="Inc\responseheaderhash.h" />
<ClInclude Include="Inc\serverprocess.h" />
<ClInclude Include="Inc\sttimer.h" />
<ClInclude Include="Inc\websockethandler.h" />
<ClInclude Include="Inc\winhttphelper.h" />
<ClInclude Include="Inc\fx_ver.h" />
<ClInclude Include="Inc\inprocessapplication.h" />
<ClInclude Include="Inc\outprocessapplication.h" />
<ClInclude Include="Inc\inprocessstoredcontext.h" />
<ClInclude Include="Src\precomp.hxx" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Src\inprocessstoredcontext.cxx" />
<ClCompile Include="Src\inprocessapplication.cxx" />
<ClCompile Include="Src\managedexports.cxx" />
<ClCompile Include="Src\outprocessapplication.cxx" />
<ClCompile Include="Src\application.cxx" />
<ClCompile Include="Src\applicationinfo.cpp" />
<ClCompile Include="Src\applicationmanager.cxx" />
<ClCompile Include="Src\aspnetcoreconfig.cxx" />
<ClCompile Include="Src\dllmain.cpp" />
<ClCompile Include="Src\filewatcher.cxx" />
<ClCompile Include="Src\forwarderconnection.cxx" />
<ClCompile Include="Src\forwardinghandler.cxx" />
<ClCompile Include="Src\fx_ver.cxx" />
<ClCompile Include="Src\path.cxx" />
<ClCompile Include="Src\processmanager.cxx" />
<ClCompile Include="Src\protocolconfig.cxx" />
<ClCompile Include="src\globalmodule.cpp" />
<ClCompile Include="Src\proxymodule.cxx" />
<ClCompile Include="Src\responseheaderhash.cxx" />
<ClCompile Include="Src\serverprocess.cxx" />
<ClCompile Include="Src\websockethandler.cxx" />
<ClCompile Include="Src\winhttphelper.cxx" />
</ItemGroup>
<Target Name="CreateVersionHeader" BeforeTargets="PrepareForBuild">
<PropertyGroup>
@ -221,29 +241,16 @@
</ItemGroup>
<WriteLinesToFile File="version.h" Lines="@(VersionHeaderContents)" OverWrite="true" />
</Target>
<ItemGroup>
<CustomBuild Include="Src\aspnetcore_msg.mc">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="aspnetcoremodule.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">
<Project>{55494e58-e061-4c4c-a0a8-837008e72f85}</Project>
</ProjectReference>
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
</ProjectReference>
</ItemGroup>
<ItemGroup>
@ -254,6 +261,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Xml Include="aspnetcore_schema.xml" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

Просмотреть файл

@ -1,286 +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
//
// The key used for hash-table lookups, consists of the port on which the http process is created.
//
class APPLICATION_KEY
{
public:
APPLICATION_KEY(
VOID
) : INLINE_STRU_INIT(m_struKey)
{
}
HRESULT
Initialize(
_In_ LPCWSTR pszKey
)
{
return m_struKey.Copy(pszKey);
}
BOOL
GetIsEqual(
const APPLICATION_KEY * key2
) const
{
return m_struKey.Equals(key2->m_struKey);
}
DWORD CalcKeyHash() const
{
return Hash(m_struKey.QueryStr());
}
private:
INLINE_STRU(m_struKey, 1024);
};
class APP_OFFLINE_HTM
{
public:
APP_OFFLINE_HTM(LPCWSTR pszPath) : m_cRefs(1)
{
m_Path.Copy( pszPath );
}
VOID
ReferenceAppOfflineHtm() const
{
InterlockedIncrement(&m_cRefs);
}
VOID
DereferenceAppOfflineHtm() const
{
if (InterlockedDecrement(&m_cRefs) == 0)
{
delete this;
}
}
BOOL
Load(
VOID
)
{
BOOL fResult = TRUE;
LARGE_INTEGER li = {0};
CHAR *pszBuff = NULL;
HANDLE handle = INVALID_HANDLE_VALUE;
handle = CreateFile( m_Path.QueryStr(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( handle == INVALID_HANDLE_VALUE )
{
if ( GetLastError() == ERROR_FILE_NOT_FOUND )
{
fResult = FALSE;
}
// This Load() member function is supposed be called only when the change notification event of file creation or file modification happens.
// If file is currenlty locked exclusively by other processes, we might get INVALID_HANDLE_VALUE even though the file exists. In that case, we should return TRUE here.
goto Finished;
}
if(!GetFileSizeEx( handle, &li ))
{
goto Finished;
}
if( li.HighPart != 0 )
{
// > 4gb file size not supported
// todo: log a warning at event log
goto Finished;
}
DWORD bytesRead = 0;
if(li.LowPart > 0)
{
pszBuff = new CHAR[ li.LowPart + 1 ];
if( ReadFile( handle, pszBuff, li.LowPart, &bytesRead, NULL ) )
{
m_Contents.Copy( pszBuff, bytesRead );
}
}
Finished:
if( handle != INVALID_HANDLE_VALUE )
{
CloseHandle(handle);
handle = INVALID_HANDLE_VALUE;
}
if( pszBuff != NULL )
{
delete[] pszBuff;
pszBuff = NULL;
}
return fResult;
}
mutable LONG m_cRefs;
STRA m_Contents;
STRU m_Path;
};
class APPLICATION_MANAGER;
class APPLICATION
{
public:
APPLICATION() : m_pApplicationManager(NULL), m_cRefs(1),
m_fAppOfflineFound(FALSE), m_pAppOfflineHtm(NULL),
m_pFileWatcherEntry(NULL), m_pConfiguration(NULL)
{
InitializeSRWLock(&m_srwLock);
}
APPLICATION_KEY *
QueryApplicationKey()
{
return &m_applicationKey;
}
virtual
~APPLICATION();
virtual
HRESULT
Initialize(
_In_ APPLICATION_MANAGER *pApplicationManager,
_In_ ASPNETCORE_CONFIG *pConfiguration) = 0;
VOID
ReferenceApplication() const
{
InterlockedIncrement(&m_cRefs);
}
VOID
DereferenceApplication() const
{
if (InterlockedDecrement(&m_cRefs) == 0)
{
delete this;
}
}
APP_OFFLINE_HTM* QueryAppOfflineHtm()
{
return m_pAppOfflineHtm;
}
BOOL
AppOfflineFound()
{
return m_fAppOfflineFound;
}
virtual
VOID
OnAppOfflineHandleChange() = 0;
VOID
UpdateAppOfflineFileHandle();
HRESULT
StartMonitoringAppOffline();
ASPNETCORE_CONFIG*
QueryConfig()
{
return m_pConfiguration;
}
virtual
REQUEST_NOTIFICATION_STATUS
ExecuteRequest(
_In_ IHttpContext* pHttpContext
) = 0;
protected:
mutable LONG m_cRefs;
APPLICATION_KEY m_applicationKey;
APPLICATION_MANAGER *m_pApplicationManager;
BOOL m_fAppOfflineFound;
APP_OFFLINE_HTM *m_pAppOfflineHtm;
FILE_WATCHER_ENTRY *m_pFileWatcherEntry;
ASPNETCORE_CONFIG *m_pConfiguration;
SRWLOCK m_srwLock;
};
class APPLICATION_HASH :
public HASH_TABLE<APPLICATION, APPLICATION_KEY *>
{
public:
APPLICATION_HASH()
{}
APPLICATION_KEY *
ExtractKey(
APPLICATION *pApplication
)
{
return pApplication->QueryApplicationKey();
}
DWORD
CalcKeyHash(
APPLICATION_KEY *key
)
{
return key->CalcKeyHash();
}
BOOL
EqualKeys(
APPLICATION_KEY *key1,
APPLICATION_KEY *key2
)
{
return key1->GetIsEqual(key2);
}
VOID
ReferenceRecord(
APPLICATION *pApplication
)
{
pApplication->ReferenceApplication();
}
VOID
DereferenceRecord(
APPLICATION *pApplication
)
{
pApplication->DereferenceApplication();
}
private:
APPLICATION_HASH(const APPLICATION_HASH &);
void operator=(const APPLICATION_HASH &);
};

Просмотреть файл

@ -0,0 +1,218 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
typedef
HRESULT
(WINAPI * PFN_ASPNETCORE_CREATE_APPLICATION)(
_In_ IHttpServer *pServer,
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ APPLICATION **pApplication
);
typedef
HRESULT
(WINAPI * PFN_ASPNETCORE_CREATE_REQUEST_HANDLER)(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication,
_Out_ REQUEST_HANDLER **pRequestHandler
);
//
// The key used for hash-table lookups, consists of the port on which the http process is created.
//
class APPLICATION_INFO_KEY
{
public:
APPLICATION_INFO_KEY(
VOID
) : INLINE_STRU_INIT(m_struKey)
{
}
HRESULT
Initialize(
_In_ LPCWSTR pszKey
)
{
return m_struKey.Copy(pszKey);
}
BOOL
GetIsEqual(
const APPLICATION_INFO_KEY * key2
) const
{
return m_struKey.Equals(key2->m_struKey);
}
DWORD CalcKeyHash() const
{
return Hash(m_struKey.QueryStr());
}
private:
INLINE_STRU(m_struKey, 1024);
};
class APPLICATION_INFO
{
public:
APPLICATION_INFO(IHttpServer *pServer) :
m_pServer(pServer),
m_cRefs(1), m_fAppOfflineFound(FALSE),
m_pAppOfflineHtm(NULL), m_pFileWatcherEntry(NULL),
m_pConfiguration(NULL),
m_pfnAspNetCoreCreateApplication(NULL),
m_pfnAspNetCoreCreateRequestHandler(NULL)
{
InitializeSRWLock(&m_srwLock);
}
APPLICATION_INFO_KEY *
QueryApplicationInfoKey()
{
return &m_applicationInfoKey;
}
virtual
~APPLICATION_INFO();
HRESULT
Initialize(
_In_ ASPNETCORE_CONFIG *pConfiguration,
_In_ FILE_WATCHER *pFileWatcher
);
VOID
ReferenceApplicationInfo() const
{
InterlockedIncrement(&m_cRefs);
}
VOID
DereferenceApplicationInfo() const
{
if (InterlockedDecrement(&m_cRefs) == 0)
{
delete this;
}
}
APP_OFFLINE_HTM* QueryAppOfflineHtm()
{
return m_pAppOfflineHtm;
}
BOOL
AppOfflineFound()
{
return m_fAppOfflineFound;
}
VOID
UpdateAppOfflineFileHandle();
HRESULT
StartMonitoringAppOffline();
ASPNETCORE_CONFIG*
QueryConfig()
{
return m_pConfiguration;
}
APPLICATION*
QueryApplication()
{
return m_pApplication;
}
HRESULT
EnsureApplicationCreated();
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER
QueryCreateRequestHandler()
{
return m_pfnAspNetCoreCreateRequestHandler;
}
private:
HRESULT FindRequestHandlerAssembly();
HRESULT FindNativeAssemblyFromGlobalLocation(STRU* struFilename);
HRESULT FindNativeAssemblyFromLocalBin(STRU* struFilename);
HRESULT GetRequestHandlerFromRuntimeStore(STRU* struFilename);
mutable LONG m_cRefs;
APPLICATION_INFO_KEY m_applicationInfoKey;
BOOL m_fAppOfflineFound;
APP_OFFLINE_HTM *m_pAppOfflineHtm;
FILE_WATCHER_ENTRY *m_pFileWatcherEntry;
ASPNETCORE_CONFIG *m_pConfiguration;
APPLICATION *m_pApplication;
SRWLOCK m_srwLock;
IHttpServer *m_pServer;
PFN_ASPNETCORE_CREATE_APPLICATION m_pfnAspNetCoreCreateApplication;
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER m_pfnAspNetCoreCreateRequestHandler;
};
class APPLICATION_INFO_HASH :
public HASH_TABLE<APPLICATION_INFO, APPLICATION_INFO_KEY *>
{
public:
APPLICATION_INFO_HASH()
{}
APPLICATION_INFO_KEY *
ExtractKey(
APPLICATION_INFO *pApplicationInfo
)
{
return pApplicationInfo->QueryApplicationInfoKey();
}
DWORD
CalcKeyHash(
APPLICATION_INFO_KEY *key
)
{
return key->CalcKeyHash();
}
BOOL
EqualKeys(
APPLICATION_INFO_KEY *key1,
APPLICATION_INFO_KEY *key2
)
{
return key1->GetIsEqual(key2);
}
VOID
ReferenceRecord(
APPLICATION_INFO *pApplicationInfo
)
{
pApplicationInfo->ReferenceApplicationInfo();
}
VOID
DereferenceRecord(
APPLICATION_INFO *pApplicationInfo
)
{
pApplicationInfo->DereferenceApplicationInfo();
}
private:
APPLICATION_INFO_HASH(const APPLICATION_INFO_HASH &);
void operator=(const APPLICATION_INFO_HASH &);
};

Просмотреть файл

@ -5,6 +5,11 @@
#define DEFAULT_HASH_BUCKETS 293
//
// This class will manage the lifecycle of all Asp.Net Core applciation
// It should be global singleton.
// Should always call GetInstance to get the object instance
//
class APPLICATION_MANAGER
{
public:
@ -15,12 +20,12 @@ public:
VOID
)
{
if( sm_pApplicationManager == NULL )
if ( sm_pApplicationManager == NULL )
{
sm_pApplicationManager = new APPLICATION_MANAGER();
}
return sm_pApplicationManager;
return sm_pApplicationManager;
}
static
@ -37,29 +42,27 @@ public:
}
HRESULT
GetApplication(
_In_ IHttpContext* pContext,
GetApplicationInfo(
_In_ IHttpServer* pServer,
_In_ ASPNETCORE_CONFIG* pConfig,
_Out_ APPLICATION ** ppApplication
_Out_ APPLICATION_INFO ** ppApplicationInfo
);
HRESULT
RecycleApplication(
_In_ LPCWSTR pszApplication
RecycleApplication(
_In_ LPCWSTR pszApplicationId
);
HRESULT
Get502ErrorPage(
_Out_ HTTP_DATA_CHUNK** ppErrorPage
);
VOID
ShutDown();
~APPLICATION_MANAGER()
{
if(m_pApplicationHash != NULL)
if(m_pApplicationInfoHash != NULL)
{
m_pApplicationHash->Clear();
delete m_pApplicationHash;
m_pApplicationHash = NULL;
m_pApplicationInfoHash->Clear();
delete m_pApplicationInfoHash;
m_pApplicationInfoHash = NULL;
}
if( m_pFileWatcher!= NULL )
@ -67,13 +70,6 @@ public:
delete m_pFileWatcher;
m_pFileWatcher = NULL;
}
if(m_pHttp502ErrorPage != NULL)
{
delete m_pHttp502ErrorPage;
m_pHttp502ErrorPage = NULL;
}
}
FILE_WATCHER*
@ -86,16 +82,16 @@ public:
{
HRESULT hr = S_OK;
if(m_pApplicationHash == NULL)
if(m_pApplicationInfoHash == NULL)
{
m_pApplicationHash = new APPLICATION_HASH();
if(m_pApplicationHash == NULL)
m_pApplicationInfoHash = new APPLICATION_INFO_HASH();
if(m_pApplicationInfoHash == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = m_pApplicationHash->Initialize(DEFAULT_HASH_BUCKETS);
hr = m_pApplicationInfoHash->Initialize(DEFAULT_HASH_BUCKETS);
if(FAILED(hr))
{
goto Finished;
@ -122,41 +118,18 @@ private:
//
// we currently limit the size of m_pstrErrorInfo to 5000, be careful if you want to change its payload
//
APPLICATION_MANAGER() : m_pApplicationHash(NULL), m_pFileWatcher(NULL),
m_pHttp502ErrorPage(NULL), m_hostingModel(HOSTING_UNKNOWN),
m_pstrErrorInfo(
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> \
<html xmlns=\"http://www.w3.org/1999/xhtml\"> \
<head> \
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" /> \
<title> IIS 502.5 Error </title><style type=\"text/css\"></style></head> \
<body> <div id = \"content\"> \
<div class = \"content-container\"><h3> HTTP Error 502.5 - Process Failure </h3></div> \
<div class = \"content-container\"> \
<fieldset> <h4> Common causes of this issue: </h4> \
<ul><li> The application process failed to start </li> \
<li> The application process started but then stopped </li> \
<li> The application process started but failed to listen on the configured port </li></ul></fieldset> \
</div> \
<div class = \"content-container\"> \
<fieldset><h4> Troubleshooting steps: </h4> \
<ul><li> Check the system event log for error messages </li> \
<li> Enable logging the application process' stdout messages </li> \
<li> Attach a debugger to the application process and inspect </li></ul></fieldset> \
<fieldset><h4> For more information visit: \
<a href=\"https://go.microsoft.com/fwlink/?linkid=808681\"> <cite> https://go.microsoft.com/fwlink/?LinkID=808681 </cite></a></h4> \
</fieldset> \
</div> \
</div></body></html>")
APPLICATION_MANAGER() : m_pApplicationInfoHash(NULL),
m_pFileWatcher(NULL),
m_hostingModel(HOSTING_UNKNOWN),
m_fInShutdown(FALSE)
{
InitializeSRWLock(&m_srwLock);
}
FILE_WATCHER *m_pFileWatcher;
APPLICATION_HASH *m_pApplicationHash;
APPLICATION_INFO_HASH *m_pApplicationInfoHash;
static APPLICATION_MANAGER *sm_pApplicationManager;
SRWLOCK m_srwLock;
HTTP_DATA_CHUNK *m_pHttp502ErrorPage;
LPSTR m_pstrErrorInfo;
APP_HOSTING_MODEL m_hostingModel;
bool m_fInShutdown;
};

Просмотреть файл

@ -0,0 +1,101 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
class APP_OFFLINE_HTM
{
public:
APP_OFFLINE_HTM(LPCWSTR pszPath) : m_cRefs(1)
{
m_Path.Copy(pszPath);
}
VOID
ReferenceAppOfflineHtm() const
{
InterlockedIncrement(&m_cRefs);
}
VOID
DereferenceAppOfflineHtm() const
{
if (InterlockedDecrement(&m_cRefs) == 0)
{
delete this;
}
}
BOOL
Load(
VOID
)
{
BOOL fResult = TRUE;
LARGE_INTEGER li = { 0 };
CHAR *pszBuff = NULL;
HANDLE handle = INVALID_HANDLE_VALUE;
handle = CreateFile(m_Path.QueryStr(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (handle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
fResult = FALSE;
}
// This Load() member function is supposed be called only when the change notification event of file creation or file modification happens.
// If file is currenlty locked exclusively by other processes, we might get INVALID_HANDLE_VALUE even though the file exists. In that case, we should return TRUE here.
goto Finished;
}
if (!GetFileSizeEx(handle, &li))
{
goto Finished;
}
if (li.HighPart != 0)
{
// > 4gb file size not supported
// todo: log a warning at event log
goto Finished;
}
DWORD bytesRead = 0;
if (li.LowPart > 0)
{
pszBuff = new CHAR[li.LowPart + 1];
if (ReadFile(handle, pszBuff, li.LowPart, &bytesRead, NULL))
{
m_Contents.Copy(pszBuff, bytesRead);
}
}
Finished:
if (handle != INVALID_HANDLE_VALUE)
{
CloseHandle(handle);
handle = INVALID_HANDLE_VALUE;
}
if (pszBuff != NULL)
{
delete[] pszBuff;
pszBuff = NULL;
}
return fResult;
}
mutable LONG m_cRefs;
STRA m_Contents;
STRU m_Path;
};

Просмотреть файл

@ -19,7 +19,7 @@
#define FILE_WATCHER_ENTRY_SIGNATURE ((DWORD) 'FWES')
#define FILE_WATCHER_ENTRY_SIGNATURE_FREE ((DWORD) 'sewf')
class APPLICATION;
class APPLICATION_INFO;
class FILE_WATCHER{
public:
@ -67,7 +67,7 @@ public:
Create(
_In_ PCWSTR pszDirectoryToMonitor,
_In_ PCWSTR pszFileNameToMonitor,
_In_ APPLICATION* pApplication,
_In_ APPLICATION_INFO* pApplicationInfo,
_In_ HANDLE hImpersonationToken
);
@ -116,7 +116,7 @@ private:
HANDLE _hImpersonationToken;
HANDLE _hDirectory;
FILE_WATCHER* _pFileMonitor;
APPLICATION* _pApplication;
APPLICATION_INFO* _pApplicationInfo;
STRU _strFileName;
STRU _strDirectoryName;
LONG _lStopMonitorCalled;

Просмотреть файл

@ -1,446 +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 "forwarderconnection.h"
#include "protocolconfig.h"
#include "serverprocess.h"
#include "application.h"
#include "tracelog.h"
#include "websockethandler.h"
enum FORWARDING_REQUEST_STATUS
{
FORWARDER_START,
FORWARDER_SENDING_REQUEST,
FORWARDER_RECEIVING_RESPONSE,
FORWARDER_RECEIVED_WEBSOCKET_RESPONSE,
FORWARDER_RESET_CONNECTION,
FORWARDER_DONE
};
extern HTTP_MODULE_ID g_pModuleId;
extern IHttpServer * g_pHttpServer;
extern BOOL g_fAsyncDisconnectAvailable;
extern PCWSTR g_pszModuleName;
extern HMODULE g_hModule;
extern HMODULE g_hWinHttpModule;
extern DWORD g_dwTlsIndex;
extern DWORD g_OptionalWinHttpFlags;
enum MULTI_PART_POSITION
{
MULTI_PART_IN_BOUNDARY,
MULTI_PART_IN_HEADER,
MULTI_PART_IN_CHUNK,
MULTI_PART_IN_CHUNK_END
};
class ASYNC_DISCONNECT_CONTEXT;
#define FORWARDING_HANDLER_SIGNATURE ((DWORD)'FHLR')
#define FORWARDING_HANDLER_SIGNATURE_FREE ((DWORD)'fhlr')
class FORWARDING_HANDLER
{
public:
FORWARDING_HANDLER(
__in IHttpContext * pW3Context,
__in APPLICATION * pApplication
);
static void * operator new(size_t size);
static void operator delete(void * pMemory);
VOID
ReferenceForwardingHandler(
VOID
) const;
VOID
DereferenceForwardingHandler(
VOID
) const;
REQUEST_NOTIFICATION_STATUS
OnExecuteRequestHandler();
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
DWORD cbCompletion,
HRESULT hrCompletionStatus
);
IHttpTraceContext *
QueryTraceContext()
{
return m_pW3Context->GetTraceContext();
}
IHttpContext *
QueryHttpContext(
VOID
)
{
return m_pW3Context;
}
static
VOID
CALLBACK
OnWinHttpCompletion(
HINTERNET hRequest,
DWORD_PTR dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength
)
{
FORWARDING_HANDLER * pThis = static_cast<FORWARDING_HANDLER *>(reinterpret_cast<PVOID>(dwContext));
if (pThis == NULL)
{
//error happened, nothing can be done here
return;
}
DBG_ASSERT(pThis->m_Signature == FORWARDING_HANDLER_SIGNATURE);
pThis->OnWinHttpCompletionInternal(hRequest,
dwInternetStatus,
lpvStatusInformation,
dwStatusInformationLength);
}
static
HRESULT
StaticInitialize(
BOOL fEnableReferenceCountTracing
);
static
VOID
StaticTerminate();
static
PCWSTR
QueryErrorFormat()
{
return sm_strErrorFormat.QueryStr();
}
static
HANDLE
QueryEventLog()
{
return sm_hEventLog;
}
VOID
TerminateRequest(
bool fClientInitiated
);
static HINTERNET sm_hSession;
HRESULT
SetStatusAndHeaders(
PCSTR pszHeaders,
DWORD cchHeaders
);
HRESULT
OnSharedRequestEntity(
ULONGLONG ulOffset,
LPCBYTE pvBuffer,
DWORD cbBuffer
);
VOID
SetStatus(
FORWARDING_REQUEST_STATUS status
)
{
m_RequestStatus = status;
}
private:
virtual
~FORWARDING_HANDLER(
VOID
);
//
// Begin OnMapRequestHandler phases.
//
HRESULT
CreateWinHttpRequest(
__in const IHttpRequest * pRequest,
__in const PROTOCOL_CONFIG * pProtocol,
__in HINTERNET hConnect,
__inout STRU * pstrUrl,
ASPNETCORE_CONFIG* pAspNetCoreConfig,
SERVER_PROCESS* pServerProcess
);
//
// End OnMapRequestHandler phases.
//
VOID
RemoveRequest();
HRESULT
GetHeaders(
const PROTOCOL_CONFIG * pProtocol,
PCWSTR * ppszHeaders,
DWORD * pcchHeaders,
ASPNETCORE_CONFIG* pAspNetCoreConfig,
SERVER_PROCESS* pServerProcess
);
HRESULT
DoReverseRewrite(
__in IHttpResponse *pResponse
);
BYTE *
GetNewResponseBuffer(
DWORD dwBufferSize
);
VOID
FreeResponseBuffers();
VOID
OnWinHttpCompletionInternal(
HINTERNET hRequest,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength
);
HRESULT
OnWinHttpCompletionSendRequestOrWriteComplete(
HINTERNET hRequest,
DWORD dwInternetStatus,
__out bool * pfClientError,
__out bool * pfAnotherCompletionExpected
);
HRESULT
OnWinHttpCompletionStatusHeadersAvailable(
HINTERNET hRequest,
__out bool * pfAnotherCompletionExpected
);
HRESULT
OnWinHttpCompletionStatusDataAvailable(
HINTERNET hRequest,
DWORD dwBytes,
__out bool * pfAnotherCompletionExpected
);
HRESULT
OnWinHttpCompletionStatusReadComplete(
__in IHttpResponse * pResponse,
DWORD dwStatusInformationLength,
__out bool * pfAnotherCompletionExpected
);
HRESULT
OnSendingRequest(
DWORD cbCompletion,
HRESULT hrCompletionStatus,
__out bool * pfClientError
);
HRESULT
OnReceivingResponse();
HRESULT
OnWebSocketWinHttpSendComplete(
HINTERNET hRequest,
LPVOID pvStatus,
DWORD hrCompletion,
DWORD cbCompletion,
bool * pfAnotherCompletionExpected
);
HRESULT
OnWebSocketWinHttpReceiveComplete(
HINTERNET hRequest,
LPVOID pvStatus,
DWORD hrCompletion,
DWORD cbCompletion,
bool * pfAnotherCompletionExpected
);
HRESULT
OnWebSocketIisSendComplete(
DWORD hrCompletion,
DWORD cbCompletion
);
HRESULT
OnWebSocketIisReceiveComplete(
DWORD hrCompletion,
DWORD cbCompletion
);
HRESULT
DoIisWebSocketReceive(
VOID
);
VOID
TerminateWebsocket(
VOID
);
HRESULT
SetHttpSysDisconnectCallback(
VOID
);
DWORD m_Signature;
mutable LONG m_cRefs;
IHttpContext * m_pW3Context;
IHttpContext * m_pChildRequestContext;
//
// WinHTTP request handle is protected using a read-write lock.
//
SRWLOCK m_RequestLock;
HINTERNET m_hRequest;
APP_OFFLINE_HTM *m_pAppOfflineHtm;
APPLICATION *m_pApplication;
bool m_fWebSocketEnabled;
bool m_fHandleClosedDueToClient;
bool m_fResponseHeadersReceivedAndSet;
BOOL m_fDoReverseRewriteHeaders;
BOOL m_fErrorHandled;
BOOL m_fWebSocketUpgrade;
BOOL m_fFinishRequest;
BOOL m_fClientDisconnected;
BOOL m_fHasError;
DWORD m_msStartTime;
DWORD m_BytesToReceive;
DWORD m_BytesToSend;
DWORD m_cchLastSend;
DWORD m_cEntityBuffers;
DWORD m_cBytesBuffered;
DWORD m_cMinBufferLimit;
BYTE * m_pEntityBuffer;
static const SIZE_T INLINE_ENTITY_BUFFERS = 8;
BUFFER_T<BYTE*,INLINE_ENTITY_BUFFERS> m_buffEntityBuffers;
PCSTR m_pszOriginalHostHeader;
FORWARDING_REQUEST_STATUS m_RequestStatus;
ASYNC_DISCONNECT_CONTEXT * m_pDisconnect;
PCWSTR m_pszHeaders;
DWORD m_cchHeaders;
STRU m_strFullUri;
ULONGLONG m_cContentLength;
WEBSOCKET_HANDLER * m_pWebSocket;
static PROTOCOL_CONFIG sm_ProtocolConfig;
static STRU sm_strErrorFormat;
static HANDLE sm_hEventLog;
static ALLOC_CACHE_HANDLER * sm_pAlloc;
//
// Reference cout tracing for debugging purposes.
//
static TRACE_LOG * sm_pTraceLog;
};
class ASYNC_DISCONNECT_CONTEXT : public IHttpConnectionStoredContext
{
public:
ASYNC_DISCONNECT_CONTEXT()
{
m_pHandler = NULL;
}
VOID
CleanupStoredContext()
{
DBG_ASSERT(m_pHandler == NULL);
delete this;
}
VOID
NotifyDisconnect()
{
FORWARDING_HANDLER *pInitialValue = (FORWARDING_HANDLER*)
InterlockedExchangePointer((PVOID*) &m_pHandler, NULL);
if (pInitialValue != NULL)
{
pInitialValue->TerminateRequest(TRUE);
pInitialValue->DereferenceForwardingHandler();
}
}
VOID
SetHandler(
FORWARDING_HANDLER *pHandler
)
{
//
// Take a reference on the forwarding handler.
// This reference will be released on either of two conditions:
//
// 1. When the request processing ends, in which case a ResetHandler()
// is called.
//
// 2. When a disconnect notification arrives.
//
// We need to make sure that only one of them ends up dereferencing
// the object.
//
DBG_ASSERT (pHandler != NULL);
DBG_ASSERT (m_pHandler == NULL);
pHandler->ReferenceForwardingHandler();
InterlockedExchangePointer((PVOID*)&m_pHandler, pHandler);
}
VOID
ResetHandler(
VOID
)
{
FORWARDING_HANDLER *pInitialValue = (FORWARDING_HANDLER*)
InterlockedExchangePointer( (PVOID*)&m_pHandler, NULL);
if (pInitialValue != NULL)
{
pInitialValue->DereferenceForwardingHandler();
}
}
private:
~ASYNC_DISCONNECT_CONTEXT()
{}
FORWARDING_HANDLER * m_pHandler;
};

Просмотреть файл

@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
class ASPNET_CORE_GLOBAL_MODULE : public CGlobalModule
{
public:
ASPNET_CORE_GLOBAL_MODULE(
APPLICATION_MANAGER* pApplicationManager
);
~ASPNET_CORE_GLOBAL_MODULE()
{
}
VOID Terminate()
{
// Remove the class from memory.
delete this;
}
GLOBAL_NOTIFICATION_STATUS
OnGlobalStopListening(
_In_ IGlobalStopListeningProvider * pProvider
);
GLOBAL_NOTIFICATION_STATUS
OnGlobalConfigurationChange(
_In_ IGlobalConfigurationChangeProvider * pProvider
);
private:
APPLICATION_MANAGER * m_pApplicationManager;
};

Просмотреть файл

@ -1,90 +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
class IN_PROCESS_STORED_CONTEXT : public IHttpStoredContext
{
public:
IN_PROCESS_STORED_CONTEXT(
IHttpContext* pHttpContext,
PVOID pvManagedContext
);
~IN_PROCESS_STORED_CONTEXT();
virtual
VOID
CleanupStoredContext(
VOID
)
{
delete this;
}
virtual
VOID
OnClientDisconnected(
VOID
)
{
}
virtual
VOID
OnListenerEvicted(
VOID
)
{
}
PVOID
QueryManagedHttpContext(
VOID
);
IHttpContext*
QueryHttpContext(
VOID
);
BOOL
QueryIsManagedRequestComplete(
VOID
);
VOID
IndicateManagedRequestComplete(
VOID
);
REQUEST_NOTIFICATION_STATUS
QueryAsyncCompletionStatus(
VOID
);
VOID
SetAsyncCompletionStatus(
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
);
static
HRESULT
GetInProcessStoredContext(
IHttpContext* pHttpContext,
IN_PROCESS_STORED_CONTEXT** ppInProcessStoredContext
);
static
HRESULT
SetInProcessStoredContext(
IHttpContext* pHttpContext,
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext
);
private:
PVOID m_pManagedHttpContext;
IHttpContext* m_pHttpContext;
BOOL m_fManagedRequestComplete;
REQUEST_NOTIFICATION_STATUS m_requestNotificationStatus;
};

Просмотреть файл

@ -1,40 +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 "application.h"
class OUT_OF_PROCESS_APPLICATION : public APPLICATION
{
public:
OUT_OF_PROCESS_APPLICATION();
~OUT_OF_PROCESS_APPLICATION();
__override
HRESULT Initialize(_In_ APPLICATION_MANAGER* pApplicationManager,
_In_ ASPNETCORE_CONFIG* pConfiguration);
__override
VOID OnAppOfflineHandleChange();
__override
REQUEST_NOTIFICATION_STATUS
ExecuteRequest(
_In_ IHttpContext* pHttpContext
);
HRESULT
GetProcess(
_In_ IHttpContext *context,
_Out_ SERVER_PROCESS **ppServerProcess
)
{
return m_pProcessManager->GetProcess(context, m_pConfiguration, ppServerProcess);
}
private:
PROCESS_MANAGER* m_pProcessManager;
};

Просмотреть файл

@ -1,18 +1,19 @@
// 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 "forwardinghandler.h"
extern HTTP_MODULE_ID g_pModuleId;
extern IHttpServer *g_pHttpServer;
extern HMODULE g_hAspnetCoreRH;
class CProxyModule : public CHttpModule
class ASPNET_CORE_PROXY_MODULE : public CHttpModule
{
public:
CProxyModule();
ASPNET_CORE_PROXY_MODULE();
~CProxyModule();
~ASPNET_CORE_PROXY_MODULE();
void * operator new(size_t size, IModuleAllocator * pPlacement)
{
@ -44,10 +45,12 @@ class CProxyModule : public CHttpModule
private:
FORWARDING_HANDLER * m_pHandler;
APPLICATION_INFO *m_pApplicationInfo;
APPLICATION *m_pApplication;
REQUEST_HANDLER *m_pHandler;
};
class CProxyModuleFactory : public IHttpModuleFactory
class ASPNET_CORE_PROXY_MODULE_FACTORY : public IHttpModuleFactory
{
public:
HRESULT

Просмотреть файл

@ -6,6 +6,7 @@
#define IDS_INVALID_PROPERTY 1000
#define IDS_SERVER_ERROR 1001
// TODO remove this file?
#define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and is listening on port '%d'."
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG L"Maximum rapid fail count per minute of '%d' exceeded."

Просмотреть файл

@ -1,78 +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 "precomp.hxx"
APPLICATION::~APPLICATION()
{
if (m_pAppOfflineHtm != NULL)
{
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
m_pAppOfflineHtm = NULL;
}
if (m_pFileWatcherEntry != NULL)
{
// Mark the entry as invalid,
// StopMonitor will close the file handle and trigger a FCN
// the entry will delete itself when processing this FCN
m_pFileWatcherEntry->MarkEntryInValid();
m_pFileWatcherEntry->StopMonitor();
m_pFileWatcherEntry = NULL;
}
}
HRESULT
APPLICATION::StartMonitoringAppOffline()
{
HRESULT hr = S_OK;
if (m_pFileWatcherEntry != NULL)
{
hr = m_pFileWatcherEntry->Create(m_pConfiguration->QueryApplicationFullPath()->QueryStr(), L"app_offline.htm", this, NULL);
}
return hr;
}
VOID
APPLICATION::UpdateAppOfflineFileHandle()
{
STRU strFilePath;
PATH::ConvertPathToFullPath(L".\\app_offline.htm", m_pConfiguration->QueryApplicationFullPath()->QueryStr(), &strFilePath);
APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL;
APP_OFFLINE_HTM *pNewAppOfflineHtm = NULL;
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) && GetLastError() == ERROR_FILE_NOT_FOUND)
{
m_fAppOfflineFound = FALSE;
}
else
{
m_fAppOfflineFound = TRUE;
pNewAppOfflineHtm = new APP_OFFLINE_HTM(strFilePath.QueryStr());
if ( pNewAppOfflineHtm != NULL )
{
if (pNewAppOfflineHtm->Load())
{
//
// loaded the new app_offline.htm
//
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
if (pOldAppOfflineHtm != NULL)
{
pOldAppOfflineHtm->DereferenceAppOfflineHtm();
pOldAppOfflineHtm = NULL;
}
}
else
{
// ignored the new app_offline file because the file does not exist.
pNewAppOfflineHtm->DereferenceAppOfflineHtm();
pNewAppOfflineHtm = NULL;
}
}
OnAppOfflineHandleChange();
}
}

Просмотреть файл

@ -0,0 +1,332 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
APPLICATION_INFO::~APPLICATION_INFO()
{
if (m_pAppOfflineHtm != NULL)
{
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
m_pAppOfflineHtm = NULL;
}
if (m_pFileWatcherEntry != NULL)
{
// Mark the entry as invalid,
// StopMonitor will close the file handle and trigger a FCN
// the entry will delete itself when processing this FCN
m_pFileWatcherEntry->MarkEntryInValid();
m_pFileWatcherEntry->StopMonitor();
m_pFileWatcherEntry = NULL;
}
if (m_pApplication != NULL)
{
// shutdown the application
m_pApplication->ShutDown();
m_pApplication->DereferenceApplication();
m_pApplication = NULL;
}
// configuration should be dereferenced after application shutdown
// since the former will use it during shutdown
if (m_pConfiguration != NULL)
{
// Need to dereference the configuration instance
m_pConfiguration->DereferenceConfiguration();
m_pConfiguration = NULL;
}
}
HRESULT
APPLICATION_INFO::Initialize(
_In_ ASPNETCORE_CONFIG *pConfiguration,
_In_ FILE_WATCHER *pFileWatcher
)
{
HRESULT hr = S_OK;
DBG_ASSERT(pConfiguration);
DBG_ASSERT(pFileWatcher);
m_pConfiguration = pConfiguration;
// reference the configuration instance to prevent it will be not release
// earlier in case of configuration change and shutdown
m_pConfiguration->ReferenceConfiguration();
hr = m_applicationInfoKey.Initialize(pConfiguration->QueryConfigPath()->QueryStr());
if (FAILED(hr))
{
goto Finished;
}
if (m_pFileWatcherEntry == NULL)
{
m_pFileWatcherEntry = new FILE_WATCHER_ENTRY(pFileWatcher);
if (m_pFileWatcherEntry == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
}
UpdateAppOfflineFileHandle();
Finished:
return hr;
}
HRESULT
APPLICATION_INFO::StartMonitoringAppOffline()
{
HRESULT hr = S_OK;
if (m_pFileWatcherEntry != NULL)
{
hr = m_pFileWatcherEntry->Create(m_pConfiguration->QueryApplicationPhysicalPath()->QueryStr(), L"app_offline.htm", this, NULL);
}
return hr;
}
VOID
APPLICATION_INFO::UpdateAppOfflineFileHandle()
{
STRU strFilePath;
UTILITY::ConvertPathToFullPath(L".\\app_offline.htm",
m_pConfiguration->QueryApplicationPhysicalPath()->QueryStr(),
&strFilePath);
APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL;
APP_OFFLINE_HTM *pNewAppOfflineHtm = NULL;
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) &&
GetLastError() == ERROR_FILE_NOT_FOUND)
{
m_fAppOfflineFound = FALSE;
}
else
{
m_fAppOfflineFound = TRUE;
pNewAppOfflineHtm = new APP_OFFLINE_HTM(strFilePath.QueryStr());
if (pNewAppOfflineHtm != NULL)
{
if (pNewAppOfflineHtm->Load())
{
//
// loaded the new app_offline.htm
//
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
if (pOldAppOfflineHtm != NULL)
{
pOldAppOfflineHtm->DereferenceAppOfflineHtm();
pOldAppOfflineHtm = NULL;
}
}
else
{
// ignored the new app_offline file because the file does not exist.
pNewAppOfflineHtm->DereferenceAppOfflineHtm();
pNewAppOfflineHtm = NULL;
}
}
// recycle the application
if (m_pApplication != NULL)
{
m_pApplication->ShutDown();
m_pApplication->DereferenceApplication();
m_pApplication = NULL;
}
}
}
HRESULT
APPLICATION_INFO::EnsureApplicationCreated()
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
APPLICATION* pApplication = NULL;
STACK_STRU(struFileName, 300); // >MAX_PATH
STRU hostFxrDllLocation;
if (m_pApplication != NULL)
{
goto Finished;
}
hr = FindRequestHandlerAssembly();
if (FAILED(hr))
{
goto Finished;
}
if (m_pApplication == NULL)
{
AcquireSRWLockExclusive(&m_srwLock);
fLocked = TRUE;
if (m_pApplication != NULL)
{
goto Finished;
}
if (m_pfnAspNetCoreCreateApplication == NULL)
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
goto Finished;
}
hr = m_pfnAspNetCoreCreateApplication(m_pServer, m_pConfiguration, &pApplication);
if (FAILED(hr))
{
goto Finished;
}
m_pApplication = pApplication;
}
Finished:
if (fLocked)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
return hr;
}
HRESULT
APPLICATION_INFO::FindRequestHandlerAssembly()
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
STACK_STRU(struFileName, 256);
if (g_fAspnetcoreRHLoadedError)
{
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
goto Finished;
}
else if (!g_fAspnetcoreRHAssemblyLoaded)
{
AcquireSRWLockExclusive(&g_srwLock);
fLocked = TRUE;
if (g_fAspnetcoreRHLoadedError)
{
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
goto Finished;
}
if (g_fAspnetcoreRHAssemblyLoaded)
{
goto Finished;
}
// load assembly and create the application
if (m_pConfiguration->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
// Look at inetsvr only for now. TODO add in functionality
hr = FindNativeAssemblyFromGlobalLocation(&struFileName);
if (FAILED(hr))
{
goto Finished;
}
}
else
{
hr = FindNativeAssemblyFromGlobalLocation(&struFileName);
if (FAILED(hr))
{
goto Finished;
}
}
g_hAspnetCoreRH = LoadLibraryW(struFileName.QueryStr());
if (g_hAspnetCoreRH == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_pfnAspNetCoreCreateApplication = (PFN_ASPNETCORE_CREATE_APPLICATION)
GetProcAddress(g_hAspnetCoreRH, "CreateApplication");
if (g_pfnAspNetCoreCreateApplication == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_pfnAspNetCoreCreateRequestHandler = (PFN_ASPNETCORE_CREATE_REQUEST_HANDLER)
GetProcAddress(g_hAspnetCoreRH, "CreateRequestHandler");
if (g_pfnAspNetCoreCreateRequestHandler == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_fAspnetcoreRHAssemblyLoaded = TRUE;
}
Finished:
//
// Question: we remember the load failure so that we will not try again.
// User needs to check whether the fuction pointer is NULL
//
m_pfnAspNetCoreCreateApplication = g_pfnAspNetCoreCreateApplication;
m_pfnAspNetCoreCreateRequestHandler = g_pfnAspNetCoreCreateRequestHandler;
if (!g_fAspnetcoreRHLoadedError && FAILED(hr))
{
g_fAspnetcoreRHLoadedError = TRUE;
}
if (fLocked)
{
ReleaseSRWLockExclusive(&g_srwLock);
}
return hr;
}
HRESULT
APPLICATION_INFO::FindNativeAssemblyFromGlobalLocation(STRU* struFilename)
{
HRESULT hr = S_OK;
DWORD dwSize = MAX_PATH;
BOOL fDone = FALSE;
DWORD dwPosition = 0;
// Though we could call LoadLibrary(L"aspnetcorerh.dll") relying the OS to solve
// the path (the targeted dll is the same folder of w3wp.exe/iisexpress)
// let's still load with full path to avoid security issue
while (!fDone)
{
DWORD dwReturnedSize = GetModuleFileName(NULL, struFilename->QueryStr(), dwSize);
if (dwReturnedSize == 0)
{
hr = HRESULT_FROM_WIN32(GetLastError());
fDone = TRUE;
goto Finished;
}
else if ((dwReturnedSize == dwSize) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
{
dwSize *= 2; // smaller buffer. increase the buffer and retry
struFilename->Resize(dwSize + 20); // aspnetcorerh.dll
}
else
{
fDone = TRUE;
}
}
if (FAILED(hr = struFilename->SyncWithBuffer()))
{
goto Finished;
}
dwPosition = struFilename->LastIndexOf(L'\\', 0);
struFilename->QueryStr()[dwPosition] = L'\0';
if (FAILED(hr = struFilename->SyncWithBuffer()) ||
FAILED(hr = struFilename->Append(g_pwzAspnetcoreRequestHandlerName)))
{
goto Finished;
}
Finished:
return hr;
}

Просмотреть файл

@ -6,28 +6,28 @@
APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
HRESULT
APPLICATION_MANAGER::GetApplication(
_In_ IHttpContext* pContext,
APPLICATION_MANAGER::GetApplicationInfo(
_In_ IHttpServer* pServer,
_In_ ASPNETCORE_CONFIG* pConfig,
_Out_ APPLICATION ** ppApplication
_Out_ APPLICATION_INFO ** ppApplicationInfo
)
{
HRESULT hr = S_OK;
APPLICATION *pApplication = NULL;
APPLICATION_KEY key;
BOOL fExclusiveLock = FALSE;
BOOL fMixedHostingModelError = FALSE;
BOOL fDuplicatedInProcessApp = FALSE;
PCWSTR pszApplicationId = NULL;
LPCWSTR apsz[1];
HRESULT hr = S_OK;
APPLICATION_INFO *pApplicationInfo = NULL;
APPLICATION_INFO_KEY key;
BOOL fExclusiveLock = FALSE;
BOOL fMixedHostingModelError = FALSE;
BOOL fDuplicatedInProcessApp = FALSE;
PCWSTR pszApplicationId = NULL;
LPCWSTR apsz[1];
STACK_STRU ( strEventMsg, 256 );
*ppApplication = NULL;
DBG_ASSERT(pContext != NULL);
DBG_ASSERT(pContext->GetApplication() != NULL);
*ppApplicationInfo = NULL;
pszApplicationId = pContext->GetApplication()->GetApplicationId();
DBG_ASSERT(pServer != NULL);
DBG_ASSERT(pConfig != NULL);
pszApplicationId = pConfig->QueryConfigPath()->QueryStr();
hr = key.Initialize(pszApplicationId);
if (FAILED(hr))
@ -35,33 +35,39 @@ APPLICATION_MANAGER::GetApplication(
goto Finished;
}
m_pApplicationHash->FindKey(&key, ppApplication);
AcquireSRWLockShared(&m_srwLock);
if (m_fInShutdown)
{
ReleaseSRWLockShared(&m_srwLock);
hr = HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS);
goto Finished;
}
m_pApplicationInfoHash->FindKey(&key, ppApplicationInfo);
ReleaseSRWLockShared(&m_srwLock);
if (*ppApplication == NULL)
if (*ppApplicationInfo == NULL)
{
switch (pConfig->QueryHostingModel())
{
case HOSTING_IN_PROCESS:
if (m_pApplicationHash->Count() > 0)
if (m_pApplicationInfoHash->Count() > 0)
{
// Only one inprocess app is allowed per IIS worker process
fDuplicatedInProcessApp = TRUE;
hr = HRESULT_FROM_WIN32(ERROR_APP_INIT_FAILURE);
goto Finished;
}
pApplication = new IN_PROCESS_APPLICATION();
break;
case HOSTING_OUT_PROCESS:
pApplication = new OUT_OF_PROCESS_APPLICATION();
break;
default:
hr = E_UNEXPECTED;
goto Finished;
}
if (pApplication == NULL)
pApplicationInfo = new APPLICATION_INFO(pServer);
if (pApplicationInfo == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
@ -69,13 +75,19 @@ APPLICATION_MANAGER::GetApplication(
AcquireSRWLockExclusive(&m_srwLock);
fExclusiveLock = TRUE;
m_pApplicationHash->FindKey(&key, ppApplication);
if (m_fInShutdown)
{
// Already in shuting down. No need to create the application
hr = HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS);
goto Finished;
}
m_pApplicationInfoHash->FindKey(&key, ppApplicationInfo);
if (*ppApplication != NULL)
if (*ppApplicationInfo != NULL)
{
// someone else created the application
delete pApplication;
pApplication = NULL;
delete pApplicationInfo;
pApplicationInfo = NULL;
goto Finished;
}
@ -92,13 +104,13 @@ APPLICATION_MANAGER::GetApplication(
}
}
hr = pApplication->Initialize(this, pConfig);
hr = pApplicationInfo->Initialize(pConfig, m_pFileWatcher);
if (FAILED(hr))
{
goto Finished;
}
hr = m_pApplicationHash->InsertRecord( pApplication );
hr = m_pApplicationInfoHash->InsertRecord( pApplicationInfo );
if (FAILED(hr))
{
goto Finished;
@ -112,13 +124,12 @@ APPLICATION_MANAGER::GetApplication(
m_hostingModel = pConfig->QueryHostingModel();
}
*ppApplicationInfo = pApplicationInfo;
ReleaseSRWLockExclusive(&m_srwLock);
fExclusiveLock = FALSE;
pApplication->StartMonitoringAppOffline();
*ppApplication = pApplication;
pApplication = NULL;
pApplicationInfo->StartMonitoringAppOffline();
pApplicationInfo = NULL;
}
Finished:
@ -128,21 +139,21 @@ Finished:
ReleaseSRWLockExclusive(&m_srwLock);
}
if (pApplicationInfo != NULL)
{
pApplicationInfo->DereferenceApplicationInfo();
pApplicationInfo = NULL;
}
if (FAILED(hr))
{
if (pApplication != NULL)
{
pApplication->DereferenceApplication();
pApplication = NULL;
}
if (fDuplicatedInProcessApp)
{
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
pszApplicationId)))
{
apsz[0] = strEventMsg.QueryStr();
/*apsz[0] = strEventMsg.QueryStr();
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
{
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
@ -154,30 +165,30 @@ Finished:
0,
apsz,
NULL);
}
}*/
}
}
else if (fMixedHostingModelError)
{
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
pszApplicationId,
pConfig->QueryHostingModelStr())))
{
apsz[0] = strEventMsg.QueryStr();
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
{
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
EVENTLOG_ERROR_TYPE,
0,
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
NULL,
1,
0,
apsz,
NULL);
}
}
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
// ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
// pszApplicationId,
// pConfig->QueryHostingModelStr())))
//{
// apsz[0] = strEventMsg.QueryStr();
// /*if (FORWARDING_HANDLER::QueryEventLog() != NULL)
// {
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
// EVENTLOG_ERROR_TYPE,
// 0,
// ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
// NULL,
// 1,
// 0,
// apsz,
// NULL);
// }*/
//}
}
else
{
@ -187,7 +198,7 @@ Finished:
hr)))
{
apsz[0] = strEventMsg.QueryStr();
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
/*if (FORWARDING_HANDLER::QueryEventLog() != NULL)
{
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
EVENTLOG_ERROR_TYPE,
@ -198,7 +209,7 @@ Finished:
0,
apsz,
NULL);
}
}*/
}
}
}
@ -208,23 +219,33 @@ Finished:
HRESULT
APPLICATION_MANAGER::RecycleApplication(
_In_ LPCWSTR pszApplication
_In_ LPCWSTR pszApplicationId
)
{
HRESULT hr = S_OK;
APPLICATION_KEY key;
APPLICATION_INFO_KEY key;
hr = key.Initialize(pszApplication);
hr = key.Initialize(pszApplicationId);
if (FAILED(hr))
{
goto Finished;
}
AcquireSRWLockExclusive(&m_srwLock);
m_pApplicationHash->DeleteKey(&key);
if (m_pApplicationHash->Count() == 0)
m_pApplicationInfoHash->DeleteKey(&key);
if (m_pApplicationInfoHash->Count() == 0)
{
m_hostingModel = HOSTING_UNKNOWN;
}
if (g_fAspnetcoreRHLoadedError)
{
// We had assembly loading failure
// this error blocked the start of all applications
// Let's recycle the worker process if user redeployed any application
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand due to assembly loading failure");
}
ReleaseSRWLockExclusive(&m_srwLock);
Finished:
@ -232,65 +253,17 @@ Finished:
return hr;
}
HRESULT
APPLICATION_MANAGER::Get502ErrorPage(
_Out_ HTTP_DATA_CHUNK** ppErrorPage
)
VOID
APPLICATION_MANAGER::ShutDown()
{
HRESULT hr = S_OK;
BOOL fExclusiveLock = FALSE;
HTTP_DATA_CHUNK *pHttp502ErrorPage = NULL;
DBG_ASSERT(ppErrorPage != NULL);
//on-demand create the error page
if (m_pHttp502ErrorPage != NULL)
{
*ppErrorPage = m_pHttp502ErrorPage;
}
else
m_fInShutdown = TRUE;
if (m_pApplicationInfoHash != NULL)
{
AcquireSRWLockExclusive(&m_srwLock);
fExclusiveLock = TRUE;
if (m_pHttp502ErrorPage != NULL)
{
*ppErrorPage = m_pHttp502ErrorPage;
}
else
{
size_t maxsize = 5000;
pHttp502ErrorPage = new HTTP_DATA_CHUNK();
if (pHttp502ErrorPage == NULL)
{
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
goto Finished;
}
pHttp502ErrorPage->DataChunkType = HttpDataChunkFromMemory;
pHttp502ErrorPage->FromMemory.pBuffer = (PVOID)m_pstrErrorInfo;
pHttp502ErrorPage->FromMemory.BufferLength = (ULONG)strnlen(m_pstrErrorInfo, maxsize); //(ULONG)(wcslen(m_pstrErrorInfo)); // *sizeof(WCHAR);
if(m_pHttp502ErrorPage != NULL)
{
delete m_pHttp502ErrorPage;
}
m_pHttp502ErrorPage = pHttp502ErrorPage;
*ppErrorPage = m_pHttp502ErrorPage;
}
}
Finished:
if (fExclusiveLock)
{
// clean up the hash table so that the application will be informed on shutdown
m_pApplicationInfoHash->Clear();
ReleaseSRWLockExclusive(&m_srwLock);
}
if (FAILED(hr))
{
if (pHttp502ErrorPage != NULL)
{
delete pHttp502ErrorPage;
}
}
return hr;
}
}

Просмотреть файл

@ -6,35 +6,42 @@
HTTP_MODULE_ID g_pModuleId = NULL;
IHttpServer * g_pHttpServer = NULL;
BOOL g_fAsyncDisconnectAvailable = FALSE;
BOOL g_fWinHttpNonBlockingCallbackAvailable = FALSE;
BOOL g_fRecycleProcessCalled = FALSE;
PCWSTR g_pszModuleName = NULL;
HINSTANCE g_hModule;
HINSTANCE g_hWinHttpModule;
BOOL g_fWebSocketSupported = FALSE;
DWORD g_dwTlsIndex = TLS_OUT_OF_INDEXES;
BOOL g_fEnableReferenceCountTracing = FALSE;
HMODULE g_hAspnetCoreRH = NULL;
BOOL g_fAspnetcoreRHAssemblyLoaded = FALSE;
BOOL g_fAspnetcoreRHLoadedError = FALSE;
DWORD g_dwAspNetCoreDebugFlags = 0;
BOOL g_fNsiApiNotSupported = FALSE;
DWORD g_dwActiveServerProcesses = 0;
DWORD g_OptionalWinHttpFlags = 0; //specify additional WinHTTP options when using WinHttpOpenRequest API.
SRWLOCK g_srwLock;
DWORD g_dwDebugFlags = 0;
PCSTR g_szDebugLabel = "ASPNET_CORE_MODULE";
PCWSTR g_pwzAspnetcoreRequestHandlerName = L"\\aspnetcorerh.dll";
PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
VOID
StaticCleanup()
{
APPLICATION_MANAGER::Cleanup();
}
BOOL WINAPI DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
UNREFERENCED_PARAMETER(lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
DisableThreadLibraryCalls(hModule);
break;
case DLL_PROCESS_DETACH:
StaticCleanup();
default:
break;
}
@ -42,75 +49,6 @@ BOOL WINAPI DllMain(HMODULE hModule,
return TRUE;
}
VOID
LoadGlobalConfiguration(
VOID
)
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
0,
KEY_READ,
&hKey) == NO_ERROR)
{
DWORD dwType;
DWORD dwData;
DWORD cbData;
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"OptionalWinHttpFlags",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
g_OptionalWinHttpFlags = dwData;
}
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"EnableReferenceCountTracing",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD) && (dwData == 1 || dwData == 0))
{
g_fEnableReferenceCountTracing = !!dwData;
}
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"DebugFlags",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
g_dwAspNetCoreDebugFlags = dwData;
}
RegCloseKey(hKey);
}
DWORD dwSize = 0;
DWORD dwResult = GetExtendedTcpTable(NULL,
&dwSize,
FALSE,
AF_INET,
TCP_TABLE_OWNER_PID_LISTENER,
0);
if (dwResult != NO_ERROR && dwResult != ERROR_INSUFFICIENT_BUFFER)
{
g_fNsiApiNotSupported = TRUE;
}
}
HRESULT
__stdcall
RegisterModule(
@ -138,8 +76,14 @@ HRESULT
--*/
{
HRESULT hr = S_OK;
CProxyModuleFactory * pFactory = NULL;
HRESULT hr = S_OK;
HKEY hKey;
BOOL fDisableANCM = FALSE;
ASPNET_CORE_PROXY_MODULE_FACTORY * pFactory = NULL;
ASPNET_CORE_GLOBAL_MODULE * pGlobalModule = NULL;
APPLICATION_MANAGER * pApplicationManager = NULL;
UNREFERENCED_PARAMETER(dwServerVersion);
#ifdef DEBUG
CREATE_DEBUG_PRINT_OBJECT("Asp.Net Core Module");
@ -148,63 +92,50 @@ HRESULT
CREATE_DEBUG_PRINT_OBJECT;
LoadGlobalConfiguration();
//LoadGlobalConfiguration();
//
// 7.0 is 0,7
//
if (dwServerVersion > MAKELONG(0, 7))
{
g_fAsyncDisconnectAvailable = TRUE;
}
//
// 8.0 is 0,8
//
if (dwServerVersion >= MAKELONG(0, 8))
{
// IISOOB:36641 Enable back WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS for Win8.
// g_fWinHttpNonBlockingCallbackAvailable = TRUE;
g_fWebSocketSupported = TRUE;
}
hr = WINHTTP_HELPER::StaticInitialize();
if (FAILED(hr))
{
if (hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND))
{
g_fWebSocketSupported = FALSE;
}
else
{
goto Finished;
}
}
InitializeSRWLock(&g_srwLock);
g_pModuleId = pModuleInfo->GetId();
g_pszModuleName = pModuleInfo->GetName();
g_pHttpServer = pHttpServer;
g_hWinHttpModule = GetModuleHandle(TEXT("winhttp.dll"));
//
// WinHTTP does not create enough threads, ask it to create more.
// Starting in Windows 7, this setting is ignored because WinHTTP
// uses a thread pool.
//
SYSTEM_INFO si;
GetSystemInfo(&si);
DWORD dwThreadCount = (si.dwNumberOfProcessors * 3 + 1) / 2;
WinHttpSetOption(NULL,
WINHTTP_OPTION_WORKER_THREAD_COUNT,
&dwThreadCount,
sizeof(dwThreadCount));
// check whether the feature is disabled due to security reason
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
0,
KEY_READ,
&hKey) == NO_ERROR)
{
DWORD dwType;
DWORD dwData;
DWORD cbData;
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"DisableANCM",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
fDisableANCM = (dwData != 0);
}
}
if (fDisableANCM)
{
// Logging
goto Finished;
}
//
// Create the factory before any static initialization.
// The CProxyModuleFactory::Terminate method will clean any
// The ASPNET_CORE_PROXY_MODULE_FACTORY::Terminate method will clean any
// static object initialized.
//
pFactory = new CProxyModuleFactory;
pFactory = new ASPNET_CORE_PROXY_MODULE_FACTORY;
if (pFactory == NULL)
{
@ -213,28 +144,45 @@ HRESULT
}
hr = pModuleInfo->SetRequestNotifications(
pFactory,
RQ_EXECUTE_REQUEST_HANDLER,
0);
pFactory,
RQ_EXECUTE_REQUEST_HANDLER,
0);
if (FAILED(hr))
{
goto Finished;
}
pFactory = NULL;
pApplicationManager = APPLICATION_MANAGER::GetInstance();
if(pApplicationManager == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pApplicationManager->Initialize();
if(FAILED(hr))
{
goto Finished;
}
pGlobalModule = NULL;
g_pResponseHeaderHash = new RESPONSE_HEADER_HASH;
if (g_pResponseHeaderHash == NULL)
pGlobalModule = new ASPNET_CORE_GLOBAL_MODULE(pApplicationManager);
if (pGlobalModule == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = g_pResponseHeaderHash->Initialize();
hr = pModuleInfo->SetGlobalNotifications(
pGlobalModule,
GL_CONFIGURATION_CHANGE | GL_STOP_LISTENING);
if (FAILED(hr))
{
goto Finished;
}
pGlobalModule = NULL;
hr = ALLOC_CACHE_HANDLER::StaticInitialize();
if (FAILED(hr))
@ -242,19 +190,12 @@ HRESULT
goto Finished;
}
hr = FORWARDING_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
if (FAILED(hr))
{
goto Finished;
}
hr = WEBSOCKET_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
if (FAILED(hr))
{
goto Finished;
}
Finished:
if (pGlobalModule != NULL)
{
delete pGlobalModule;
pGlobalModule = NULL;
}
if (pFactory != NULL)
{

Просмотреть файл

@ -13,9 +13,17 @@ FILE_WATCHER::~FILE_WATCHER()
{
if (m_hChangeNotificationThread != NULL)
{
PostQueuedCompletionStatus(m_hCompletionPort, 0, FILE_WATCHER_SHUTDOWN_KEY, NULL);
WaitForSingleObject(m_hChangeNotificationThread, INFINITE);
CloseHandle(m_hChangeNotificationThread);
m_hChangeNotificationThread = NULL;
}
if (NULL != m_hCompletionPort)
{
CloseHandle(m_hCompletionPort);
m_hCompletionPort = NULL;
}
}
HRESULT
@ -97,13 +105,13 @@ Win32 error
&pOverlapped,
INFINITE);
DBG_ASSERT(fSuccess);
DBG_ASSERT(fSuccess);
DebugPrint(1, "FILE_WATCHER::ChangeNotificationThread");
dwErrorStatus = fSuccess ? ERROR_SUCCESS : GetLastError();
if (completionKey == FILE_WATCHER_SHUTDOWN_KEY)
{
continue;
break;
}
DBG_ASSERT(pOverlapped != NULL);
@ -117,6 +125,8 @@ Win32 error
pOverlapped = NULL;
cbCompletion = 0;
}
return 0;
}
VOID
@ -173,7 +183,7 @@ FILE_WATCHER_ENTRY::FILE_WATCHER_ENTRY(FILE_WATCHER * pFileMonitor) :
_pFileMonitor(pFileMonitor),
_hDirectory(INVALID_HANDLE_VALUE),
_hImpersonationToken(NULL),
_pApplication(NULL),
_pApplicationInfo(NULL),
_lStopMonitorCalled(0),
_cRefs(1),
_fIsValid(TRUE)
@ -253,7 +263,7 @@ HRESULT
// Othersie we have to cache the file info
//
if (cbCompletion == 0)
{
{
fFileChanged = TRUE;
}
else
@ -266,9 +276,9 @@ HRESULT
//
// check whether the monitored file got changed
//
if (_wcsnicmp(pNotificationInfo->FileName,
_strFileName.QueryStr(),
pNotificationInfo->FileNameLength/sizeof(WCHAR)) == 0)
if (_wcsnicmp(pNotificationInfo->FileName,
_strFileName.QueryStr(),
pNotificationInfo->FileNameLength / sizeof(WCHAR)) == 0)
{
fFileChanged = TRUE;
break;
@ -284,7 +294,7 @@ HRESULT
{
pNotificationInfo = (FILE_NOTIFY_INFORMATION*)
((PBYTE)pNotificationInfo +
pNotificationInfo->NextEntryOffset);
pNotificationInfo->NextEntryOffset);
}
}
}
@ -294,7 +304,7 @@ HRESULT
//
// so far we only monitoring app_offline
//
_pApplication->UpdateAppOfflineFileHandle();
_pApplicationInfo->UpdateAppOfflineFileHandle();
}
Finished:
@ -314,7 +324,7 @@ FILE_WATCHER_ENTRY::Monitor(VOID)
ReferenceFileWatcherEntry();
ZeroMemory(&_overlapped, sizeof(_overlapped));
if(!ReadDirectoryChangesW(_hDirectory,
if (!ReadDirectoryChangesW(_hDirectory,
_buffDirectoryChanges.QueryPtr(),
_buffDirectoryChanges.QuerySize(),
FALSE, // Watching sub dirs. Set to False now as only monitoring app_offline
@ -355,7 +365,7 @@ HRESULT
FILE_WATCHER_ENTRY::Create(
_In_ PCWSTR pszDirectoryToMonitor,
_In_ PCWSTR pszFileNameToMonitor,
_In_ APPLICATION* pApplication,
_In_ APPLICATION_INFO* pApplicationInfo,
_In_ HANDLE hImpersonationToken
)
{
@ -364,7 +374,7 @@ FILE_WATCHER_ENTRY::Create(
if (pszDirectoryToMonitor == NULL ||
pszFileNameToMonitor == NULL ||
pApplication == NULL)
pApplicationInfo == NULL)
{
DBG_ASSERT(FALSE);
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
@ -374,7 +384,7 @@ FILE_WATCHER_ENTRY::Create(
//
//remember the application
//
_pApplication = pApplication;
_pApplicationInfo = pApplicationInfo;
if (FAILED(hr = _strFileName.Copy(pszFileNameToMonitor)))
{

Просмотреть файл

@ -1,195 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include <cassert>
#include <sstream>
#include "fx_ver.h"
#include "precomp.h"
fx_ver_t::fx_ver_t(int major, int minor, int patch, const std::wstring& pre, const std::wstring& build)
: m_major(major)
, m_minor(minor)
, m_patch(patch)
, m_pre(pre)
, m_build(build)
{
}
fx_ver_t::fx_ver_t(int major, int minor, int patch, const std::wstring& pre)
: fx_ver_t(major, minor, patch, pre, TEXT(""))
{
}
fx_ver_t::fx_ver_t(int major, int minor, int patch)
: fx_ver_t(major, minor, patch, TEXT(""), TEXT(""))
{
}
bool fx_ver_t::operator ==(const fx_ver_t& b) const
{
return compare(*this, b) == 0;
}
bool fx_ver_t::operator !=(const fx_ver_t& b) const
{
return !operator ==(b);
}
bool fx_ver_t::operator <(const fx_ver_t& b) const
{
return compare(*this, b) < 0;
}
bool fx_ver_t::operator >(const fx_ver_t& b) const
{
return compare(*this, b) > 0;
}
bool fx_ver_t::operator <=(const fx_ver_t& b) const
{
return compare(*this, b) <= 0;
}
bool fx_ver_t::operator >=(const fx_ver_t& b) const
{
return compare(*this, b) >= 0;
}
std::wstring fx_ver_t::as_str() const
{
std::wstringstream stream;
stream << m_major << TEXT(".") << m_minor << TEXT(".") << m_patch;
if (!m_pre.empty())
{
stream << m_pre;
}
if (!m_build.empty())
{
stream << TEXT("+") << m_build;
}
return stream.str();
}
/* static */
int fx_ver_t::compare(const fx_ver_t&a, const fx_ver_t& b)
{
// compare(u.v.w-p+b, x.y.z-q+c)
if (a.m_major != b.m_major)
{
return (a.m_major > b.m_major) ? 1 : -1;
}
if (a.m_minor != b.m_minor)
{
return (a.m_minor > b.m_minor) ? 1 : -1;
}
if (a.m_patch != b.m_patch)
{
return (a.m_patch > b.m_patch) ? 1 : -1;
}
if (a.m_pre.empty() != b.m_pre.empty())
{
// Either a is empty or b is empty
return a.m_pre.empty() ? 1 : -1;
}
// Either both are empty or both are non-empty (may be equal)
int pre_cmp = a.m_pre.compare(b.m_pre);
if (pre_cmp != 0)
{
return pre_cmp;
}
return a.m_build.compare(b.m_build);
}
bool try_stou(const std::wstring& str, unsigned* num)
{
if (str.empty())
{
return false;
}
if (str.find_first_not_of(TEXT("0123456789")) != std::wstring::npos)
{
return false;
}
*num = (unsigned)std::stoul(str);
return true;
}
bool parse_internal(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production)
{
size_t maj_start = 0;
size_t maj_sep = ver.find(TEXT('.'));
if (maj_sep == std::wstring::npos)
{
return false;
}
unsigned major = 0;
if (!try_stou(ver.substr(maj_start, maj_sep), &major))
{
return false;
}
size_t min_start = maj_sep + 1;
size_t min_sep = ver.find(TEXT('.'), min_start);
if (min_sep == std::wstring::npos)
{
return false;
}
unsigned minor = 0;
if (!try_stou(ver.substr(min_start, min_sep - min_start), &minor))
{
return false;
}
unsigned patch = 0;
size_t pat_start = min_sep + 1;
size_t pat_sep = ver.find_first_not_of(TEXT("0123456789"), pat_start);
if (pat_sep == std::wstring::npos)
{
if (!try_stou(ver.substr(pat_start), &patch))
{
return false;
}
*fx_ver = fx_ver_t(major, minor, patch);
return true;
}
if (parse_only_production)
{
// This is a prerelease or has build suffix.
return false;
}
if (!try_stou(ver.substr(pat_start, pat_sep - pat_start), &patch))
{
return false;
}
size_t pre_start = pat_sep;
size_t pre_sep = ver.find(TEXT('+'), pre_start);
if (pre_sep == std::wstring::npos)
{
*fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start));
return true;
}
else
{
size_t build_start = pre_sep + 1;
*fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start, pre_sep - pre_start), ver.substr(build_start));
return true;
}
}
/* static */
bool fx_ver_t::parse(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production)
{
bool valid = parse_internal(ver, fx_ver, parse_only_production);
assert(!valid || fx_ver->as_str() == ver);
return valid;
}

Просмотреть файл

@ -0,0 +1,59 @@
#include "precomp.hxx"
ASPNET_CORE_GLOBAL_MODULE::ASPNET_CORE_GLOBAL_MODULE(
APPLICATION_MANAGER* pApplicationManager)
{
m_pApplicationManager = pApplicationManager;
}
//
// Is called when IIS decided to terminate worker process
// Shut down all core apps
//
GLOBAL_NOTIFICATION_STATUS
ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening(
_In_ IGlobalStopListeningProvider * pProvider
)
{
UNREFERENCED_PARAMETER(pProvider);
if (m_pApplicationManager != NULL)
{
// we should let application manager to shudown all allication
// and dereference it as some requests may still reference to application manager
m_pApplicationManager->ShutDown();
m_pApplicationManager = NULL;
}
// Return processing to the pipeline.
return GL_NOTIFICATION_CONTINUE;
}
//
// Is called when configuration changed
// Recycled the corresponding core app if its configuration changed
//
GLOBAL_NOTIFICATION_STATUS
ASPNET_CORE_GLOBAL_MODULE::OnGlobalConfigurationChange(
_In_ IGlobalConfigurationChangeProvider * pProvider
)
{
UNREFERENCED_PARAMETER(pProvider);
// Retrieve the path that has changed.
PCWSTR pwszChangePath = pProvider->GetChangePath();
// Test for an error.
if (NULL != pwszChangePath &&
_wcsicmp(pwszChangePath, L"MACHINE") != 0 &&
_wcsicmp(pwszChangePath, L"MACHINE/WEBROOT") != 0)
{
if (m_pApplicationManager != NULL)
{
m_pApplicationManager->RecycleApplication(pwszChangePath);
}
}
// Return processing to the pipeline.
return GL_NOTIFICATION_CONTINUE;
}

Просмотреть файл

@ -1,686 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include "precomp.hxx"
#include <algorithm>
typedef DWORD(*hostfxr_main_fn) (CONST DWORD argc, CONST WCHAR* argv[]);
IN_PROCESS_APPLICATION* IN_PROCESS_APPLICATION::s_Application = NULL;
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION() :
m_ProcessExitCode ( 0 ),
m_fManagedAppLoaded ( FALSE ),
m_fLoadManagedAppError ( FALSE ),
m_fInitialized ( FALSE )
{
}
IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
{
Recycle();
}
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_APPLICATION::OnAsyncCompletion(
IHttpContext* pHttpContext,
DWORD cbCompletion,
HRESULT hrCompletionStatus
)
{
HRESULT hr;
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext = NULL;
REQUEST_NOTIFICATION_STATUS dwRequestNotificationStatus = RQ_NOTIFICATION_CONTINUE;
hr = IN_PROCESS_STORED_CONTEXT::GetInProcessStoredContext(pHttpContext, &pInProcessStoredContext);
if (FAILED(hr))
{
// Finish the request as we couldn't get the callback
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 19, hr);
return RQ_NOTIFICATION_FINISH_REQUEST;
}
else if (pInProcessStoredContext->QueryIsManagedRequestComplete())
{
// means PostCompletion has been called and this is the associated callback.
dwRequestNotificationStatus = pInProcessStoredContext->QueryAsyncCompletionStatus();
// TODO cleanup whatever disconnect listener there is
return dwRequestNotificationStatus;
}
else
{
// Call the managed handler for async completion.
return m_AsyncCompletionHandler(pInProcessStoredContext->QueryManagedHttpContext(), hrCompletionStatus, cbCompletion);
}
}
BOOL
IN_PROCESS_APPLICATION::DirectoryExists(
_In_ STRU *pstrPath
)
{
WIN32_FILE_ATTRIBUTE_DATA data;
if (pstrPath->IsEmpty())
{
return false;
}
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
}
BOOL
IN_PROCESS_APPLICATION::GetEnv(
_In_ PCWSTR pszEnvironmentVariable,
_Out_ STRU *pstrResult
)
{
DWORD dwLength;
PWSTR pszBuffer = NULL;
BOOL fSucceeded = FALSE;
if (pszEnvironmentVariable == NULL)
{
goto Finished;
}
pstrResult->Reset();
dwLength = GetEnvironmentVariableW(pszEnvironmentVariable, NULL, 0);
if (dwLength == 0)
{
goto Finished;
}
pszBuffer = new WCHAR[dwLength];
if (GetEnvironmentVariableW(pszEnvironmentVariable, pszBuffer, dwLength) == 0)
{
goto Finished;
}
pstrResult->Copy(pszBuffer);
fSucceeded = TRUE;
Finished:
if (pszBuffer != NULL) {
delete[] pszBuffer;
}
return fSucceeded;
}
VOID
IN_PROCESS_APPLICATION::FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
)
{
HANDLE handle = NULL;
WIN32_FIND_DATAW data = { 0 };
handle = FindFirstFileExW(pszPath, FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0);
if (handle == INVALID_HANDLE_VALUE)
{
return;
}
do
{
std::wstring folder(data.cFileName);
pvFolders->push_back(folder);
} while (FindNextFileW(handle, &data));
FindClose(handle);
}
VOID
IN_PROCESS_APPLICATION::SetCallbackHandles(
_In_ PFN_REQUEST_HANDLER request_handler,
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
_In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
_In_ VOID* pvRequstHandlerContext,
_In_ VOID* pvShutdownHandlerContext
)
{
m_RequestHandler = request_handler;
m_RequstHandlerContext = pvRequstHandlerContext;
m_ShutdownHandler = shutdown_handler;
m_ShutdownHandlerContext = pvShutdownHandlerContext;
m_AsyncCompletionHandler = async_completion_handler;
// Initialization complete
SetEvent(m_pInitalizeEvent);
}
//
// Initialize is guarded by a lock inside APPLICATION_MANAGER::GetApplication
// It ensures only one application will be initialized and singleton
// Error wuill happen if you call Initialized outside APPLICATION_MANAGER::GetApplication
//
__override
HRESULT
IN_PROCESS_APPLICATION::Initialize(
_In_ APPLICATION_MANAGER* pApplicationManager,
_In_ ASPNETCORE_CONFIG* pConfiguration
)
{
HRESULT hr = S_OK;
DBG_ASSERT(pApplicationManager != NULL);
DBG_ASSERT(pConfiguration != NULL);
m_pConfiguration = pConfiguration;
m_pApplicationManager = pApplicationManager;
hr = m_applicationKey.Initialize(pConfiguration->QueryApplicationPath()->QueryStr());
if (FAILED(hr))
{
goto Finished;
}
// check app_offline
UpdateAppOfflineFileHandle();
if (m_pFileWatcherEntry == NULL)
{
m_pFileWatcherEntry = new FILE_WATCHER_ENTRY(m_pApplicationManager->GetFileWatcher());
if (m_pFileWatcherEntry == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
}
m_pInitalizeEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual reset event
FALSE, // not set
NULL); // name
if (m_pInitalizeEvent == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
m_fInitialized = TRUE;
Finished:
return hr;
}
HRESULT
IN_PROCESS_APPLICATION::LoadManagedApplication()
{
HRESULT hr = S_OK;
DWORD dwTimeout;
DWORD dwResult;
BOOL fLocked = FALSE;
PCWSTR apsz[1];
STACK_STRU(strEventMsg, 256);
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
{
// Core CLR has already been loaded.
// Cannot load more than once even there was a failure
goto Finished;
}
AcquireSRWLockExclusive(&m_srwLock);
fLocked = TRUE;
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
{
goto Finished;
}
m_hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE)ExecuteAspNetCoreProcess,
this, // thread function arguments
0, // default creation flags
NULL); // receive thread identifier
if (m_hThread == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
// If the debugger is attached, never timeout
if (IsDebuggerPresent())
{
dwTimeout = INFINITE;
}
else
{
dwTimeout = m_pConfiguration->QueryStartupTimeLimitInMS();
}
const HANDLE pHandles[2]{ m_hThread, m_pInitalizeEvent };
// Wait on either the thread to complete or the event to be set
dwResult = WaitForMultipleObjects(2, pHandles, FALSE, dwTimeout);
// It all timed out
if (dwResult == WAIT_TIMEOUT)
{
// do we need kill the backend thread
hr = HRESULT_FROM_WIN32(dwResult);
goto Finished;
}
else if (dwResult == WAIT_FAILED)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
// The thread ended it means that something failed
if (dwResult == WAIT_OBJECT_0)
{
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
goto Finished;
}
m_fManagedAppLoaded = TRUE;
Finished:
if (fLocked)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
if (FAILED(hr))
{
// Question: in case of application loading failure, should we allow retry on
// following request or block the activation at all
m_fLoadManagedAppError = FALSE; // m_hThread != NULL ?
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG,
m_pConfiguration->QueryApplicationPath()->QueryStr(),
m_pConfiguration->QueryApplicationFullPath()->QueryStr(),
hr)))
{
apsz[0] = strEventMsg.QueryStr();
//
// not checking return code because if ReportEvent
// fails, we cannot do anything.
//
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
{
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
EVENTLOG_ERROR_TYPE,
0,
ASPNETCORE_EVENT_LOAD_CLR_FALIURE,
NULL,
1,
0,
apsz,
NULL);
}
}
}
return hr;
}
VOID
IN_PROCESS_APPLICATION::Recycle(
VOID
)
{
if (m_fInitialized)
{
DWORD dwThreadStatus = 0;
DWORD dwTimeout = m_pConfiguration->QueryShutdownTimeLimitInMS();
AcquireSRWLockExclusive(&m_srwLock);
if (!g_pHttpServer->IsCommandLineLaunch() &&
!g_fRecycleProcessCalled &&
(g_pHttpServer->GetAdminManager() != NULL))
{
// IIS scenario.
// notify IIS first so that new request will be routed to new worker process
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand");
}
g_fRecycleProcessCalled = TRUE;
// First call into the managed server and shutdown
if (m_ShutdownHandler != NULL)
{
m_ShutdownHandler(m_ShutdownHandlerContext);
m_ShutdownHandler = NULL;
}
if (m_hThread != NULL &&
GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 &&
dwThreadStatus == STILL_ACTIVE)
{
// wait for gracefullshut down, i.e., the exit of the background thread or timeout
if (WaitForSingleObject(m_hThread, dwTimeout) != WAIT_OBJECT_0)
{
// if the thread is still running, we need kill it first before exit to avoid AV
if (GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE)
{
TerminateThread(m_hThread, STATUS_CONTROL_C_EXIT);
}
}
}
CloseHandle(m_hThread);
m_hThread = NULL;
s_Application = NULL;
ReleaseSRWLockExclusive(&m_srwLock);
if (g_pHttpServer && g_pHttpServer->IsCommandLineLaunch())
{
// IISExpress scenario
// Can only call exit to terminate current process
exit(0);
}
}
}
VOID
IN_PROCESS_APPLICATION::OnAppOfflineHandleChange()
{
// only recycle the worker process after managed app was loaded
// app_offline scenario managed application has not been loaded yet
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
{
Recycle();
}
}
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_APPLICATION::ExecuteRequest(
_In_ IHttpContext* pHttpContext
)
{
if (m_RequestHandler != NULL)
{
return m_RequestHandler(pHttpContext, m_RequstHandlerContext);
}
//
// return error as the application did not register callback
//
if (ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::IsEnabled(pHttpContext->GetTraceContext()))
{
ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::RaiseEvent(pHttpContext->GetTraceContext(),
NULL,
E_APPLICATION_ACTIVATION_EXEC_FAILURE);
}
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, E_APPLICATION_ACTIVATION_EXEC_FAILURE);
return RQ_NOTIFICATION_FINISH_REQUEST;
}
HRESULT
IN_PROCESS_APPLICATION::ExecuteApplication(
VOID
)
{
HRESULT hr = S_OK;
STRU strFullPath;
STRU strDotnetExeLocation;
STRU strHostFxrSearchExpression;
STRU strDotnetFolderLocation;
STRU strHighestDotnetVersion;
STRU strApplicationFullPath;
PWSTR strDelimeterContext = NULL;
PCWSTR pszDotnetExeLocation = NULL;
PCWSTR pszDotnetExeString(L"dotnet.exe");
DWORD dwCopyLength;
HMODULE hModule;
PCWSTR argv[2];
hostfxr_main_fn pProc;
std::vector<std::wstring> vVersionFolders;
bool fFound = FALSE;
// Get the System PATH value.
if (!GetEnv(L"PATH", &strFullPath))
{
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Split on ';', checking to see if dotnet.exe exists in any folders.
pszDotnetExeLocation = wcstok_s(strFullPath.QueryStr(), L";", &strDelimeterContext);
while (pszDotnetExeLocation != NULL)
{
dwCopyLength = wcsnlen_s(pszDotnetExeLocation, 260);
if (dwCopyLength == 0)
{
continue;
}
// We store both the exe and folder locations as we eventually need to check inside of host\\fxr
// which doesn't need the dotnet.exe portion of the string
// TODO consider reducing allocations.
strDotnetExeLocation.Reset();
strDotnetFolderLocation.Reset();
hr = strDotnetExeLocation.Copy(pszDotnetExeLocation, dwCopyLength);
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Copy(pszDotnetExeLocation, dwCopyLength);
if (FAILED(hr))
{
goto Finished;
}
if (dwCopyLength > 0 && pszDotnetExeLocation[dwCopyLength - 1] != L'\\')
{
hr = strDotnetExeLocation.Append(L"\\");
if (FAILED(hr))
{
goto Finished;
}
}
hr = strDotnetExeLocation.Append(pszDotnetExeString);
if (FAILED(hr))
{
goto Finished;
}
if (PathFileExists(strDotnetExeLocation.QueryStr()))
{
// means we found the folder with a dotnet.exe inside of it.
fFound = TRUE;
break;
}
pszDotnetExeLocation = wcstok_s(NULL, L";", &strDelimeterContext);
}
if (!fFound)
{
// could not find dotnet.exe, error out
hr = ERROR_BAD_ENVIRONMENT;
}
hr = strDotnetFolderLocation.Append(L"\\host\\fxr");
if (FAILED(hr))
{
goto Finished;
}
if (!DirectoryExists(&strDotnetFolderLocation))
{
// error, not found the folder
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Find all folders under host\\fxr\\ for version numbers.
hr = strHostFxrSearchExpression.Copy(strDotnetFolderLocation);
if (FAILED(hr))
{
goto Finished;
}
hr = strHostFxrSearchExpression.Append(L"\\*");
if (FAILED(hr))
{
goto Finished;
}
// As we use the logic from core-setup, we are opting to use std here.
// TODO remove all uses of std?
FindDotNetFolders(strHostFxrSearchExpression.QueryStr(), &vVersionFolders);
if (vVersionFolders.size() == 0)
{
// no core framework was found
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
hr = FindHighestDotNetVersion(vVersionFolders, &strHighestDotnetVersion);
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Append(L"\\");
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Append(strHighestDotnetVersion.QueryStr());
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Append(L"\\hostfxr.dll");
if (FAILED(hr))
{
goto Finished;
}
hModule = LoadLibraryW(strDotnetFolderLocation.QueryStr());
if (hModule == NULL)
{
// .NET Core not installed (we can log a more detailed error message here)
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Get the entry point for main
pProc = (hostfxr_main_fn)GetProcAddress(hModule, "hostfxr_main");
if (pProc == NULL)
{
hr = ERROR_BAD_ENVIRONMENT; // better hrresult?
goto Finished;
}
// The first argument is mostly ignored
argv[0] = strDotnetExeLocation.QueryStr();
PATH::ConvertPathToFullPath(m_pConfiguration->QueryArguments()->QueryStr(),
m_pConfiguration->QueryApplicationFullPath()->QueryStr(),
&strApplicationFullPath);
argv[1] = strApplicationFullPath.QueryStr();
// There can only ever be a single instance of .NET Core
// loaded in the process but we need to get config information to boot it up in the
// first place. This is happening in an execute request handler and everyone waits
// until this initialization is done.
// We set a static so that managed code can call back into this instance and
// set the callbacks
s_Application = this;
m_ProcessExitCode = pProc(2, argv);
if (m_ProcessExitCode != 0)
{
}
Finished:
//
// this method is called by the background thread and should never exit unless shutdown
//
if (!g_fRecycleProcessCalled)
{
STRU strEventMsg;
LPCWSTR apsz[1];
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG,
m_pConfiguration->QueryApplicationPath()->QueryStr(),
m_pConfiguration->QueryApplicationFullPath()->QueryStr(),
m_ProcessExitCode
)))
{
apsz[0] = strEventMsg.QueryStr();
//
// not checking return code because if ReportEvent
// fails, we cannot do anything.
//
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
{
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
EVENTLOG_ERROR_TYPE,
0,
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT,
NULL,
1,
0,
apsz,
NULL);
}
// error. the thread exits after application started
// Question: should we shutdown current worker process or keep the application in failure state?
// for now, we reccylce to keep the same behavior as that of out-of-process
if (m_fManagedAppLoaded)
{
Recycle();
}
}
}
return hr;
}
// static
VOID
IN_PROCESS_APPLICATION::ExecuteAspNetCoreProcess(
_In_ LPVOID pContext
)
{
IN_PROCESS_APPLICATION *pApplication = (IN_PROCESS_APPLICATION*)pContext;
DBG_ASSERT(pApplication != NULL);
pApplication->ExecuteApplication();
//
// no need to log the error here as if error happened, the thread will exit
// the error will ba catched by caller LoadManagedApplication which will log an error
//
}
HRESULT
IN_PROCESS_APPLICATION::FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
)
{
HRESULT hr = S_OK;
fx_ver_t max_ver(-1, -1, -1);
for (const auto& dir : vFolders)
{
fx_ver_t fx_ver(-1, -1, -1);
if (fx_ver_t::parse(dir, &fx_ver, false))
{
max_ver = std::max(max_ver, fx_ver);
}
}
hr = pstrResult->Copy(max_ver.as_str().c_str());
// we check FAILED(hr) outside of function
return hr;
}

Просмотреть файл

@ -1,113 +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 "precomp.hxx"
IN_PROCESS_STORED_CONTEXT::IN_PROCESS_STORED_CONTEXT(
IHttpContext* pHttpContext,
PVOID pMangedHttpContext
)
{
// TODO if we want to go by IIS patterns, we should have these in a separate initialize function
m_pManagedHttpContext = pMangedHttpContext;
m_pHttpContext = pHttpContext;
m_fManagedRequestComplete = FALSE;
}
IN_PROCESS_STORED_CONTEXT::~IN_PROCESS_STORED_CONTEXT()
{
}
PVOID
IN_PROCESS_STORED_CONTEXT::QueryManagedHttpContext(
VOID
)
{
return m_pManagedHttpContext;
}
IHttpContext*
IN_PROCESS_STORED_CONTEXT::QueryHttpContext(
VOID
)
{
return m_pHttpContext;
}
BOOL
IN_PROCESS_STORED_CONTEXT::QueryIsManagedRequestComplete(
VOID
)
{
return m_fManagedRequestComplete;
}
VOID
IN_PROCESS_STORED_CONTEXT::IndicateManagedRequestComplete(
VOID
)
{
m_fManagedRequestComplete = TRUE;
}
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_STORED_CONTEXT::QueryAsyncCompletionStatus(
VOID
)
{
return m_requestNotificationStatus;
}
VOID
IN_PROCESS_STORED_CONTEXT::SetAsyncCompletionStatus(
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
)
{
m_requestNotificationStatus = requestNotificationStatus;
}
HRESULT
IN_PROCESS_STORED_CONTEXT::GetInProcessStoredContext(
IHttpContext* pHttpContext,
IN_PROCESS_STORED_CONTEXT** ppInProcessStoredContext
)
{
if (pHttpContext == NULL)
{
return E_FAIL;
}
if (ppInProcessStoredContext == NULL)
{
return E_FAIL;
}
*ppInProcessStoredContext = (IN_PROCESS_STORED_CONTEXT*)pHttpContext->GetModuleContextContainer()->GetModuleContext(g_pModuleId);
if (*ppInProcessStoredContext == NULL)
{
return E_FAIL;
}
return S_OK;
}
HRESULT
IN_PROCESS_STORED_CONTEXT::SetInProcessStoredContext(
IHttpContext* pHttpContext,
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext
)
{
if (pHttpContext == NULL)
{
return E_FAIL;
}
if (pInProcessStoredContext == NULL)
{
return E_FAIL;
}
return pHttpContext->GetModuleContextContainer()->SetModuleContext(
pInProcessStoredContext,
g_pModuleId
);
}

Просмотреть файл

@ -1,121 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include "precomp.hxx"
OUT_OF_PROCESS_APPLICATION::OUT_OF_PROCESS_APPLICATION()
: m_pProcessManager(NULL)
{
}
OUT_OF_PROCESS_APPLICATION::~OUT_OF_PROCESS_APPLICATION()
{
if (m_pProcessManager != NULL)
{
m_pProcessManager->ShutdownAllProcesses();
m_pProcessManager->DereferenceProcessManager();
m_pProcessManager = NULL;
}
}
//
// Initialize is guarded by a lock inside APPLICATION_MANAGER::GetApplication
// It ensures only one application will be initialized and singleton
// Error will happen if you call Initialized outside APPLICATION_MANAGER::GetApplication
//
__override
HRESULT
OUT_OF_PROCESS_APPLICATION::Initialize(
_In_ APPLICATION_MANAGER* pApplicationManager,
_In_ ASPNETCORE_CONFIG* pConfiguration
)
{
HRESULT hr = S_OK;
DBG_ASSERT(pApplicationManager != NULL);
DBG_ASSERT(pConfiguration != NULL);
m_pApplicationManager = pApplicationManager;
m_pConfiguration = pConfiguration;
hr = m_applicationKey.Initialize(pConfiguration->QueryApplicationPath()->QueryStr());
if (FAILED(hr))
{
goto Finished;
}
if (m_pProcessManager == NULL)
{
m_pProcessManager = new PROCESS_MANAGER;
if (m_pProcessManager == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = m_pProcessManager->Initialize();
if (FAILED(hr))
{
goto Finished;
}
}
if (m_pFileWatcherEntry == NULL)
{
m_pFileWatcherEntry = new FILE_WATCHER_ENTRY(pApplicationManager->GetFileWatcher());
if (m_pFileWatcherEntry == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
}
UpdateAppOfflineFileHandle();
Finished:
if (FAILED(hr))
{
if (m_pFileWatcherEntry != NULL)
{
m_pFileWatcherEntry->DereferenceFileWatcherEntry();
m_pFileWatcherEntry = NULL;
}
if (m_pProcessManager != NULL)
{
m_pProcessManager->DereferenceProcessManager();
m_pProcessManager = NULL;
}
}
return hr;
}
__override
VOID
OUT_OF_PROCESS_APPLICATION::OnAppOfflineHandleChange()
{
//
// Sending signal to backend process for shutdown
//
if (m_pProcessManager != NULL)
{
m_pProcessManager->SendShutdownSignal();
}
}
__override
REQUEST_NOTIFICATION_STATUS
OUT_OF_PROCESS_APPLICATION::ExecuteRequest(
_In_ IHttpContext* pHttpContext
)
{
//
// TODO:
// Ideally we should wrap the fowaring logic inside FORWARDING_HANDLER inside this function
// To achieve better abstraction. It is too risky to do it now
//
return RQ_NOTIFICATION_FINISH_REQUEST;
}

Просмотреть файл

@ -54,13 +54,6 @@
#define WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS 111
#endif
#define ASPNETCORE_EVENT_PROVIDER L"IIS AspNetCore Module"
#define ASPNETCORE_IISEXPRESS_EVENT_PROVIDER L"IIS Express AspNetCore Module"
#define TIMESPAN_IN_MILLISECONDS(x) ((x)/((LONGLONG)(10000)))
#define TIMESPAN_IN_SECONDS(x) ((TIMESPAN_IN_MILLISECONDS(x))/((LONGLONG)(1000)))
#define TIMESPAN_IN_MINUTES(x) ((TIMESPAN_IN_SECONDS(x))/((LONGLONG)(60)))
#ifdef max
#undef max
template<typename T> inline T max(T a, T b)
@ -97,43 +90,33 @@ inline bool IsSpace(char ch)
#include <hashtable.h>
#include "stringa.h"
#include "stringu.h"
//#include "treehash.h"
#include "dbgutil.h"
#include "ahutil.h"
#include "multisz.h"
#include "multisza.h"
#include "base64.h"
#include "sttimer.h"
#include <listentry.h>
#include <datetime.h>
#include <reftrace.h>
#include <acache.h>
#include <time.h>
#include "environmentvariablehash.h"
#include "..\aspnetcore_msg.h"
#include "aspnetcore_event.h"
#include "aspnetcoreconfig.h"
#include "serverprocess.h"
#include "processmanager.h"
#include "..\..\CommonLib\environmentvariablehash.h"
#include "..\..\CommonLib\aspnetcoreconfig.h"
#include "..\..\CommonLib\application.h"
#include "..\..\CommonLib\utility.h"
#include "..\..\CommonLib\debugutil.h"
#include "..\..\CommonLib\requesthandler.h"
//#include "..\aspnetcore_msg.h"
//#include "aspnetcore_event.h"
#include "appoffline.h"
#include "filewatcher.h"
#include "application.h"
#include "applicationinfo.h"
#include "applicationmanager.h"
#include "inprocessstoredcontext.h"
#include "inprocessapplication.h"
#include "outprocessapplication.h"
#include "globalmodule.h"
#include "resource.h"
#include "path.h"
#include "debugutil.h"
#include "protocolconfig.h"
#include "responseheaderhash.h"
#include "forwarderconnection.h"
#include "winhttphelper.h"
#include "websockethandler.h"
#include "forwardinghandler.h"
#include "proxymodule.h"
#include "fx_ver.h"
FORCEINLINE
DWORD
@ -158,11 +141,15 @@ HRESULT_FROM_GETLASTERROR()
: E_FAIL;
}
extern BOOL g_fAsyncDisconnectAvailable;
extern BOOL g_fWinHttpNonBlockingCallbackAvailable;
extern PVOID g_pModuleId;
extern BOOL g_fWebSocketSupported;
extern BOOL g_fAspnetcoreRHAssemblyLoaded;
extern BOOL g_fAspnetcoreRHLoadedError;
extern BOOL g_fEnableReferenceCountTracing;
extern DWORD g_dwActiveServerProcesses;
extern DWORD g_OptionalWinHttpFlags;
extern HMODULE g_hAspnetCoreRH;
extern SRWLOCK g_srwLock;
extern PCWSTR g_pwzAspnetcoreRequestHandlerName;
extern PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
extern PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
#pragma warning( error : 4091)

Просмотреть файл

@ -1,294 +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 "precomp.hxx"
volatile BOOL PROCESS_MANAGER::sm_fWSAStartupDone = FALSE;
HRESULT
PROCESS_MANAGER::Initialize(
VOID
)
{
HRESULT hr = S_OK;
WSADATA wsaData;
int result;
BOOL fLocked = FALSE;
if( !sm_fWSAStartupDone )
{
AcquireSRWLockExclusive( &m_srwLock );
fLocked = TRUE;
if( !sm_fWSAStartupDone )
{
if( (result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0 )
{
hr = HRESULT_FROM_WIN32( result );
goto Finished;
}
sm_fWSAStartupDone = TRUE;
}
ReleaseSRWLockExclusive( &m_srwLock );
fLocked = FALSE;
}
m_dwRapidFailTickStart = GetTickCount();
if( m_hNULHandle == NULL )
{
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
m_hNULHandle = CreateFileW( L"NUL",
FILE_WRITE_DATA,
FILE_SHARE_READ,
&saAttr,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( m_hNULHandle == INVALID_HANDLE_VALUE )
{
hr = HRESULT_FROM_GETLASTERROR();
goto Finished;
}
}
Finished:
if(fLocked)
{
ReleaseSRWLockExclusive( &m_srwLock );
}
return hr;
}
PROCESS_MANAGER::~PROCESS_MANAGER()
{
AcquireSRWLockExclusive(&m_srwLock);
if( m_ppServerProcessList != NULL )
{
for( DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
{
if( m_ppServerProcessList[i] != NULL )
{
m_ppServerProcessList[i]->DereferenceServerProcess();
m_ppServerProcessList[i] = NULL;
}
}
delete[] m_ppServerProcessList;
m_ppServerProcessList = NULL;
}
if( m_hNULHandle != NULL )
{
CloseHandle( m_hNULHandle );
m_hNULHandle = NULL;
}
if( sm_fWSAStartupDone )
{
WSACleanup();
sm_fWSAStartupDone = FALSE;
}
ReleaseSRWLockExclusive(&m_srwLock);
}
HRESULT
PROCESS_MANAGER::GetProcess(
_In_ IHttpContext *context,
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ SERVER_PROCESS **ppServerProcess
)
{
HRESULT hr = S_OK;
BOOL fSharedLock = FALSE;
BOOL fExclusiveLock = FALSE;
PCWSTR apsz[1];
STACK_STRU( strEventMsg, 256 );
DWORD dwProcessIndex = 0;
SERVER_PROCESS **ppSelectedServerProcess = NULL;
if (!m_fServerProcessListReady)
{
AcquireSRWLockExclusive( &m_srwLock );
fExclusiveLock = TRUE;
if (!m_fServerProcessListReady)
{
m_dwProcessesPerApplication = pConfig->QueryProcessesPerApplication();
m_ppServerProcessList = new SERVER_PROCESS*[m_dwProcessesPerApplication];
if(m_ppServerProcessList == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
for(DWORD i=0;i<m_dwProcessesPerApplication;++i)
{
m_ppServerProcessList[i] = NULL;
}
}
m_fServerProcessListReady = TRUE;
ReleaseSRWLockExclusive( &m_srwLock );
fExclusiveLock = FALSE;
}
AcquireSRWLockShared( &m_srwLock );
fSharedLock = TRUE;
//
// round robin through to the next available process.
//
dwProcessIndex = (DWORD) InterlockedIncrement64( (LONGLONG*) &m_dwRouteToProcessIndex );
dwProcessIndex = dwProcessIndex % m_dwProcessesPerApplication;
ppSelectedServerProcess = &m_ppServerProcessList[dwProcessIndex];
if( *ppSelectedServerProcess != NULL &&
m_ppServerProcessList[dwProcessIndex]->IsReady() )
{
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
goto Finished;
}
ReleaseSRWLockShared( &m_srwLock );
fSharedLock = FALSE;
// should make the lock per process so that we can start processes simultaneously ?
if(m_ppServerProcessList[dwProcessIndex] == NULL || !m_ppServerProcessList[dwProcessIndex]->IsReady())
{
AcquireSRWLockExclusive( &m_srwLock );
fExclusiveLock = TRUE;
if( m_ppServerProcessList[dwProcessIndex] != NULL )
{
if( !m_ppServerProcessList[dwProcessIndex]->IsReady() )
{
//
// terminate existing process that is not ready
// before creating new one.
//
ShutdownProcessNoLock( m_ppServerProcessList[dwProcessIndex] );
}
else
{
// server is already up and ready to serve requests.
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
goto Finished;
}
}
if( RapidFailsPerMinuteExceeded(pConfig->QueryRapidFailsPerMinute()) )
{
//
// rapid fails per minute exceeded, do not create new process.
//
if( SUCCEEDED( strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG,
pConfig->QueryRapidFailsPerMinute() ) ) )
{
apsz[0] = strEventMsg.QueryStr();
//
// not checking return code because if ReportEvent
// fails, we cannot do anything.
//
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
{
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
EVENTLOG_INFORMATION_TYPE,
0,
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED,
NULL,
1,
0,
apsz,
NULL);
}
}
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
goto Finished;
}
if( m_ppServerProcessList[dwProcessIndex] == NULL )
{
m_ppServerProcessList[dwProcessIndex] = new SERVER_PROCESS();
if( m_ppServerProcessList[dwProcessIndex] == NULL )
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = m_ppServerProcessList[dwProcessIndex]->Initialize(
this,
pConfig->QueryProcessPath(),
pConfig->QueryArguments(),
pConfig->QueryStartupTimeLimitInMS(),
pConfig->QueryShutdownTimeLimitInMS(),
pConfig->QueryWindowsAuthEnabled(),
pConfig->QueryBasicAuthEnabled(),
pConfig->QueryAnonymousAuthEnabled(),
pConfig->QueryEnvironmentVariables(),
pConfig->QueryStdoutLogEnabled(),
pConfig->QueryStdoutLogFile()
);
if( FAILED( hr ) )
{
goto Finished;
}
hr = m_ppServerProcessList[dwProcessIndex]->StartProcess(context);
if( FAILED( hr ) )
{
goto Finished;
}
}
if( !m_ppServerProcessList[dwProcessIndex]->IsReady() )
{
hr = HRESULT_FROM_WIN32( ERROR_CREATE_FAILED );
goto Finished;
}
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
}
Finished:
if( FAILED(hr) )
{
if(m_ppServerProcessList[dwProcessIndex] != NULL )
{
m_ppServerProcessList[dwProcessIndex]->DereferenceServerProcess();
m_ppServerProcessList[dwProcessIndex] = NULL;
}
}
if( fSharedLock )
{
ReleaseSRWLockShared( &m_srwLock );
fSharedLock = FALSE;
}
if( fExclusiveLock )
{
ReleaseSRWLockExclusive( &m_srwLock );
fExclusiveLock = FALSE;
}
return hr;
}

Просмотреть файл

@ -5,12 +5,12 @@
__override
HRESULT
CProxyModuleFactory::GetHttpModule(
ASPNET_CORE_PROXY_MODULE_FACTORY::GetHttpModule(
CHttpModule ** ppModule,
IModuleAllocator * pAllocator
)
{
CProxyModule *pModule = new (pAllocator) CProxyModule();
ASPNET_CORE_PROXY_MODULE *pModule = new (pAllocator) ASPNET_CORE_PROXY_MODULE();
if (pModule == NULL)
{
return E_OUTOFMEMORY;
@ -22,7 +22,7 @@ CProxyModuleFactory::GetHttpModule(
__override
VOID
CProxyModuleFactory::Terminate(
ASPNET_CORE_PROXY_MODULE_FACTORY::Terminate(
VOID
)
/*++
@ -41,39 +41,38 @@ Return value:
--*/
{
FORWARDING_HANDLER::StaticTerminate();
/* FORWARDING_HANDLER::StaticTerminate();
WEBSOCKET_HANDLER::StaticTerminate();
if (g_pResponseHeaderHash != NULL)
{
g_pResponseHeaderHash->Clear();
delete g_pResponseHeaderHash;
g_pResponseHeaderHash = NULL;
}
WEBSOCKET_HANDLER::StaticTerminate();*/
ALLOC_CACHE_HANDLER::StaticTerminate();
delete this;
}
CProxyModule::CProxyModule(
) : m_pHandler(NULL)
ASPNET_CORE_PROXY_MODULE::ASPNET_CORE_PROXY_MODULE(
) : m_pApplicationInfo(NULL), m_pHandler(NULL)
{
}
CProxyModule::~CProxyModule()
ASPNET_CORE_PROXY_MODULE::~ASPNET_CORE_PROXY_MODULE()
{
if (m_pApplicationInfo != NULL)
{
m_pApplicationInfo->DereferenceApplicationInfo();
m_pApplicationInfo = NULL;
}
if (m_pHandler != NULL)
{
m_pHandler->DereferenceForwardingHandler();
m_pHandler->DereferenceRequestHandler();
m_pHandler = NULL;
}
}
__override
REQUEST_NOTIFICATION_STATUS
CProxyModule::OnExecuteRequestHandler(
ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
IHttpContext * pHttpContext,
IHttpEventProvider *
)
@ -81,47 +80,105 @@ CProxyModule::OnExecuteRequestHandler(
HRESULT hr = S_OK;
ASPNETCORE_CONFIG *pConfig = NULL;
APPLICATION_MANAGER *pApplicationManager = NULL;
APPLICATION *pApplication = NULL;
hr = ASPNETCORE_CONFIG::GetConfig(pHttpContext, &pConfig);
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
APPLICATION* pApplication = NULL;
STACK_STRU(struFileName, 256);
hr = ASPNETCORE_CONFIG::GetConfig(g_pHttpServer, g_pModuleId, pHttpContext, &pConfig);
if (FAILED(hr))
{
goto Failed;
goto Finished;
}
pApplicationManager = APPLICATION_MANAGER::GetInstance();
if (pApplicationManager == NULL)
{
hr = E_OUTOFMEMORY;
goto Failed;
goto Finished;
}
hr = pApplicationManager->GetApplication(
pHttpContext,
pConfig,
&pApplication);
hr = pApplicationManager->GetApplicationInfo(
g_pHttpServer,
pConfig,
&m_pApplicationInfo);
if (FAILED(hr))
{
goto Failed;
goto Finished;
}
m_pHandler = new FORWARDING_HANDLER(pHttpContext, pApplication);
if (m_pHandler == NULL)
// app_offline check to avoid loading aspnetcorerh.dll unnecessarily
if (m_pApplicationInfo->AppOfflineFound())
{
hr = E_OUTOFMEMORY;
goto Failed;
// servicing app_offline
HTTP_DATA_CHUNK DataChunk;
IHttpResponse *pResponse = NULL;
APP_OFFLINE_HTM *pAppOfflineHtm = NULL;
pResponse = pHttpContext->GetResponse();
pAppOfflineHtm = m_pApplicationInfo->QueryAppOfflineHtm();
DBG_ASSERT(pAppOfflineHtm);
DBG_ASSERT(pResponse);
// Ignore failure hresults as nothing we can do
// Set fTrySkipCustomErrors to true as we want client see the offline content
pResponse->SetStatus(503, "Service Unavailable", 0, hr, NULL, TRUE);
pResponse->SetHeader("Content-Type",
"text/html",
(USHORT)strlen("text/html"),
FALSE
);
DataChunk.DataChunkType = HttpDataChunkFromMemory;
DataChunk.FromMemory.pBuffer = (PVOID)pAppOfflineHtm->m_Contents.QueryStr();
DataChunk.FromMemory.BufferLength = pAppOfflineHtm->m_Contents.QueryCB();
pResponse->WriteEntityChunkByReference(&DataChunk);
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
goto Finished;
}
return m_pHandler->OnExecuteRequestHandler();
// make sure assmebly is loaded and application is created
Failed:
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
hr = m_pApplicationInfo->EnsureApplicationCreated();
if (FAILED(hr))
{
goto Finished;
}
pApplication = m_pApplicationInfo->QueryApplication();
DBG_ASSERT(pApplication);
// make sure application is in running state
// cannot recreate the application as we cannot reload clr for inprocess
if (pApplication->QueryStatus() != APPLICATION_STATUS::RUNNING)
{
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
goto Finished;
}
// Create RequestHandler and process the request
hr = m_pApplicationInfo->QueryCreateRequestHandler()(pHttpContext,
(HTTP_MODULE_ID*) &g_pModuleId,
pApplication,
&m_pHandler);
if (FAILED(hr))
{
goto Finished;
}
retVal = m_pHandler->OnExecuteRequestHandler();
Finished:
if (FAILED(hr))
{
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
}
return retVal;
}
__override
REQUEST_NOTIFICATION_STATUS
CProxyModule::OnAsyncCompletion(
ASPNET_CORE_PROXY_MODULE::OnAsyncCompletion(
IHttpContext *,
DWORD,
BOOL,

Просмотреть файл

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{55494E58-E061-4C4C-A0A8-837008E72F85}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>NewCommon</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>C:\AspNetCoreModule\src\IISLib;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalLibraryDirectories>..\iislib</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="application.h" />
<ClInclude Include="aspnetcoreconfig.h" />
<ClInclude Include="debugutil.h" />
<ClInclude Include="environmentvariablehash.h" />
<ClInclude Include="fx_ver.h" />
<ClInclude Include="hostfxr_utility.h" />
<ClInclude Include="requesthandler.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="utility.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="application.cpp" />
<ClCompile Include="aspnetcoreconfig.cxx" />
<ClCompile Include="fx_ver.cxx" />
<ClCompile Include="hostfxr_utility.cpp" />
<ClCompile Include="requesthandler.cxx" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="utility.cxx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Просмотреть файл

@ -0,0 +1,50 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
APPLICATION::APPLICATION(
_In_ IHttpServer* pHttpServer,
_In_ ASPNETCORE_CONFIG* pConfig) :
m_cRefs(1),
m_pHttpServer(pHttpServer),
m_pConfig(pConfig),
m_status(APPLICATION_STATUS::UNKNOWN)
{
}
APPLICATION::~APPLICATION()
{
}
APPLICATION_STATUS
APPLICATION::QueryStatus()
{
return m_status;
}
ASPNETCORE_CONFIG*
APPLICATION::QueryConfig()
{
return m_pConfig;
}
VOID
APPLICATION::ReferenceApplication()
const
{
InterlockedIncrement(&m_cRefs);
}
VOID
APPLICATION::DereferenceApplication()
const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
delete this;
}
}

Просмотреть файл

@ -0,0 +1,48 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
enum APPLICATION_STATUS
{
UNKNOWN = 0,
RUNNING,
FAUL
};
class ASPNETCORE_CONFIG;
class APPLICATION
{
public:
APPLICATION(
_In_ IHttpServer* pHttpServer,
_In_ ASPNETCORE_CONFIG* pConfig);
virtual
VOID
ShutDown() = 0;
virtual
~APPLICATION();
APPLICATION_STATUS
QueryStatus();
ASPNETCORE_CONFIG*
QueryConfig();
VOID
ReferenceApplication()
const;
VOID
DereferenceApplication()
const;
protected:
mutable LONG m_cRefs;
APPLICATION_STATUS m_status;
IHttpServer* m_pHttpServer;
ASPNETCORE_CONFIG* m_pConfig;
};

Просмотреть файл

@ -1,56 +1,47 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
#include "stdafx.h"
#include "aspnetcoreconfig.h"
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
{
if (QueryHostingModel() == HOSTING_IN_PROCESS &&
!g_fRecycleProcessCalled &&
(g_pHttpServer->GetAdminManager() != NULL))
{
// There is a bug in IHttpServer::RecycleProcess. It will hit AV when worker process
// has already been in recycling state.
// To workaround, do null check on GetAdminManager(). If it is NULL, worker process is in recycling
// Do not call RecycleProcess again
// RecycleProcess can olny be called once
// In case of configuration change for in-process app
// We want notify IIS first to let new request routed to new worker process
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Configuration Change");
}
// It's safe for us to set this g_fRecycleProcessCalled
// as in_process scenario will always recycle the worker process for configuration change
g_fRecycleProcessCalled = TRUE;
m_struApplicationFullPath.Reset();
if (m_pEnvironmentVariables != NULL)
{
m_pEnvironmentVariables->Clear();
delete m_pEnvironmentVariables;
m_pEnvironmentVariables = NULL;
}
}
if (!m_struApplication.IsEmpty())
{
APPLICATION_MANAGER::GetInstance()->RecycleApplication(m_struApplication.QueryStr());
}
VOID
ASPNETCORE_CONFIG::ReferenceConfiguration(
VOID
) const
{
InterlockedIncrement(&m_cRefs);
}
if (QueryHostingModel() == HOSTING_IN_PROCESS &&
g_pHttpServer->IsCommandLineLaunch())
VOID
ASPNETCORE_CONFIG::DereferenceConfiguration(
VOID
) const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
// IISExpress scenario, only option is to call exit in case configuration change
// as CLR or application may change
exit(0);
delete this;
}
}
HRESULT
ASPNETCORE_CONFIG::GetConfig(
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpContext *pHttpContext,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
)
{
HRESULT hr = S_OK;
@ -67,7 +58,7 @@ ASPNETCORE_CONFIG::GetConfig(
// potential bug if user sepcific config at virtual dir level
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
pHttpApplication->GetModuleContextContainer()->GetModuleContext(g_pModuleId);
pHttpApplication->GetModuleContextContainer()->GetModuleContext(pModuleId);
if (pAspNetCoreConfig != NULL)
{
@ -83,14 +74,14 @@ ASPNETCORE_CONFIG::GetConfig(
goto Finished;
}
hr = pAspNetCoreConfig->Populate(pHttpContext);
hr = pAspNetCoreConfig->Populate(pHttpServer, pHttpContext);
if (FAILED(hr))
{
goto Finished;
}
hr = pHttpApplication->GetModuleContextContainer()->
SetModuleContext(pAspNetCoreConfig, g_pModuleId);
SetModuleContext(pAspNetCoreConfig, pModuleId);
if (FAILED(hr))
{
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
@ -99,7 +90,7 @@ ASPNETCORE_CONFIG::GetConfig(
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
GetModuleContextContainer()->
GetModuleContext(g_pModuleId);
GetModuleContext(pModuleId);
_ASSERT(pAspNetCoreConfig != NULL);
@ -137,11 +128,11 @@ Finished:
HRESULT
ASPNETCORE_CONFIG::Populate(
IHttpServer *pHttpServer,
IHttpContext *pHttpContext
)
{
HRESULT hr = S_OK;
STACK_STRU(strSiteConfigPath, 256);
STRU strEnvName;
STRU strEnvValue;
STRU strExpandedEnvValue;
@ -160,6 +151,10 @@ ASPNETCORE_CONFIG::Populate(
DWORD dwCounter = 0;
DWORD dwPosition = 0;
WCHAR* pszPath = NULL;
BSTR bstrWindowAuthSection = NULL;
BSTR bstrBasicAuthSection = NULL;
BSTR bstrAnonymousAuthSection = NULL;
BSTR bstrAspNetCoreSection = NULL;
m_pEnvironmentVariables = new ENVIRONMENT_VAR_HASH();
if (m_pEnvironmentVariables == NULL)
@ -174,20 +169,20 @@ ASPNETCORE_CONFIG::Populate(
goto Finished;
}
pAdminManager = g_pHttpServer->GetAdminManager();
hr = strSiteConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
pAdminManager = pHttpServer->GetAdminManager();
hr = m_struConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
if (FAILED(hr))
{
goto Finished;
}
hr = m_struApplicationFullPath.Copy(pHttpContext->GetApplication()->GetApplicationPhysicalPath());
hr = m_struApplicationPhysicalPath.Copy(pHttpContext->GetApplication()->GetApplicationPhysicalPath());
if (FAILED(hr))
{
goto Finished;
}
pszPath = strSiteConfigPath.QueryStr();
pszPath = m_struConfigPath.QueryStr();
while (pszPath[dwPosition] != NULL)
{
if (pszPath[dwPosition] == '/')
@ -214,8 +209,15 @@ ASPNETCORE_CONFIG::Populate(
goto Finished;
}
hr = pAdminManager->GetAdminSection(CS_WINDOWS_AUTHENTICATION_SECTION,
strSiteConfigPath.QueryStr(),
bstrWindowAuthSection = SysAllocString(CS_WINDOWS_AUTHENTICATION_SECTION);
if (bstrWindowAuthSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrWindowAuthSection,
m_struConfigPath.QueryStr(),
&pWindowsAuthenticationElement);
if (FAILED(hr))
{
@ -235,8 +237,14 @@ ASPNETCORE_CONFIG::Populate(
}
}
hr = pAdminManager->GetAdminSection(CS_BASIC_AUTHENTICATION_SECTION,
strSiteConfigPath.QueryStr(),
bstrBasicAuthSection = SysAllocString(CS_BASIC_AUTHENTICATION_SECTION);
if (bstrBasicAuthSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrBasicAuthSection,
m_struConfigPath.QueryStr(),
&pBasicAuthenticationElement);
if (FAILED(hr))
{
@ -252,9 +260,14 @@ ASPNETCORE_CONFIG::Populate(
goto Finished;
}
}
hr = pAdminManager->GetAdminSection(CS_ANONYMOUS_AUTHENTICATION_SECTION,
strSiteConfigPath.QueryStr(),
bstrAnonymousAuthSection = SysAllocString(CS_ANONYMOUS_AUTHENTICATION_SECTION);
if (bstrAnonymousAuthSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrAnonymousAuthSection,
m_struConfigPath.QueryStr(),
&pAnonymousAuthenticationElement);
if (FAILED(hr))
{
@ -271,8 +284,14 @@ ASPNETCORE_CONFIG::Populate(
}
}
hr = pAdminManager->GetAdminSection(CS_ASPNETCORE_SECTION,
strSiteConfigPath.QueryStr(),
bstrAspNetCoreSection = SysAllocString(CS_ASPNETCORE_SECTION);
if (bstrAspNetCoreSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrAspNetCoreSection,
m_struConfigPath.QueryStr(),
&pAspNetCoreElement);
if (FAILED(hr))
{
@ -402,13 +421,13 @@ ASPNETCORE_CONFIG::Populate(
{
goto Finished;
}
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_FILE,
&m_struStdoutLogFile);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_FILE,
&m_struStdoutLogFile);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementChildByName(pAspNetCoreElement,
CS_ASPNETCORE_ENVIRONMENT_VARIABLES,

Просмотреть файл

@ -34,11 +34,13 @@
#define MIN_PORT 1025
#define MAX_PORT 48000
#define HEX_TO_ASCII(c) ((CHAR)(((c) < 10) ? ((c) + '0') : ((c) + 'a' - 10)))
#define TIMESPAN_IN_MILLISECONDS(x) ((x)/((LONGLONG)(10000)))
#define TIMESPAN_IN_SECONDS(x) ((TIMESPAN_IN_MILLISECONDS(x))/((LONGLONG)(1000)))
#define TIMESPAN_IN_MINUTES(x) ((TIMESPAN_IN_SECONDS(x))/((LONGLONG)(60)))
extern HTTP_MODULE_ID g_pModuleId;
extern IHttpServer * g_pHttpServer;
extern BOOL g_fRecycleProcessCalled;
//#define HEX_TO_ASCII(c) ((CHAR)(((c) < 10) ? ((c) + '0') : ((c) + 'a' - 10)))
#include "stdafx.h"
enum APP_HOSTING_MODEL
{
@ -57,14 +59,16 @@ public:
VOID
CleanupStoredContext()
{
delete this;
DereferenceConfiguration();
}
static
HRESULT
GetConfig(
_In_ IHttpContext *pHttpContext,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpContext *pHttpContext,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
);
ENVIRONMENT_VAR_HASH*
@ -132,11 +136,11 @@ public:
}
STRU*
QueryApplicationFullPath(
QueryApplicationPhysicalPath(
VOID
)
{
return &m_struApplicationFullPath;
return &m_struApplicationPhysicalPath;
}
STRU*
@ -149,30 +153,22 @@ public:
STRU*
QueryProcessPath(
VOID
)
VOID
)
{
return &m_struProcessPath;
}
APP_HOSTING_MODEL
QueryHostingModel(
VOID
VOID
)
{
return m_hostingModel;
}
STRU*
QueryHostingModelStr(
VOID
)
{
return &m_strHostingModel;
}
BOOL
QueryStdoutLogEnabled()
QueryStdoutLogEnabled()
{
return m_fStdoutLogEnabled;
}
@ -213,6 +209,36 @@ public:
return &m_struStdoutLogFile;
}
STRU*
QueryConfigPath()
{
return &m_struConfigPath;
}
STRU*
QueryHostfxrPath()
{
return &m_struHostFxrPath;
}
BOOL
QueryIsStandAloneApplication(
VOID
)
{
return m_fIsStandAloneApplication;
}
VOID
ReferenceConfiguration(
VOID
) const;
VOID
DereferenceConfiguration(
VOID
) const;
private:
//
@ -221,33 +247,40 @@ private:
ASPNETCORE_CONFIG():
m_fStdoutLogEnabled( FALSE ),
m_pEnvironmentVariables( NULL ),
m_cRefs( 1 ),
m_hostingModel( HOSTING_UNKNOWN )
{
}
HRESULT
Populate(
IHttpServer *pHttpServer,
IHttpContext *pHttpContext
);
mutable LONG m_cRefs;
DWORD m_dwRequestTimeoutInMS;
DWORD m_dwStartupTimeLimitInMS;
DWORD m_dwShutdownTimeLimitInMS;
DWORD m_dwRapidFailsPerMinute;
DWORD m_dwProcessesPerApplication;
STRU m_struApplication;
STRU m_struArguments;
STRU m_struProcessPath;
STRU m_struStdoutLogFile;
STRU m_struApplicationFullPath;
STRU m_strHostingModel;
STRU m_struApplication;
STRU m_struApplicationPhysicalPath;
STRU m_struApplicationVirtualPath;
STRU m_struConfigPath;
STRU m_strHostingModel;
STRU m_struHostFxrPath;
BOOL m_fStdoutLogEnabled;
BOOL m_fForwardWindowsAuthToken;
BOOL m_fDisableStartUpErrorPage;
BOOL m_fWindowsAuthEnabled;
BOOL m_fBasicAuthEnabled;
BOOL m_fAnonymousAuthEnabled;
BOOL m_fIsStandAloneApplication;
APP_HOSTING_MODEL m_hostingModel;
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
};

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#define ASPNETCORE_DEBUG_FLAG_INFO 0x00000001
#define ASPNETCORE_DEBUG_FLAG_WARNING 0x00000002
#define ASPNETCORE_DEBUG_FLAG_ERROR 0x00000004

192
src/CommonLib/fx_ver.cxx Normal file
Просмотреть файл

@ -0,0 +1,192 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include "stdafx.h"
fx_ver_t::fx_ver_t(int major, int minor, int patch, const std::wstring& pre, const std::wstring& build)
: m_major(major)
, m_minor(minor)
, m_patch(patch)
, m_pre(pre)
, m_build(build)
{
}
fx_ver_t::fx_ver_t(int major, int minor, int patch, const std::wstring& pre)
: fx_ver_t(major, minor, patch, pre, TEXT(""))
{
}
fx_ver_t::fx_ver_t(int major, int minor, int patch)
: fx_ver_t(major, minor, patch, TEXT(""), TEXT(""))
{
}
bool fx_ver_t::operator ==(const fx_ver_t& b) const
{
return compare(*this, b) == 0;
}
bool fx_ver_t::operator !=(const fx_ver_t& b) const
{
return !operator ==(b);
}
bool fx_ver_t::operator <(const fx_ver_t& b) const
{
return compare(*this, b) < 0;
}
bool fx_ver_t::operator >(const fx_ver_t& b) const
{
return compare(*this, b) > 0;
}
bool fx_ver_t::operator <=(const fx_ver_t& b) const
{
return compare(*this, b) <= 0;
}
bool fx_ver_t::operator >=(const fx_ver_t& b) const
{
return compare(*this, b) >= 0;
}
std::wstring fx_ver_t::as_str() const
{
std::wstringstream stream;
stream << m_major << TEXT(".") << m_minor << TEXT(".") << m_patch;
if (!m_pre.empty())
{
stream << m_pre;
}
if (!m_build.empty())
{
stream << TEXT("+") << m_build;
}
return stream.str();
}
/* static */
int fx_ver_t::compare(const fx_ver_t&a, const fx_ver_t& b)
{
// compare(u.v.w-p+b, x.y.z-q+c)
if (a.m_major != b.m_major)
{
return (a.m_major > b.m_major) ? 1 : -1;
}
if (a.m_minor != b.m_minor)
{
return (a.m_minor > b.m_minor) ? 1 : -1;
}
if (a.m_patch != b.m_patch)
{
return (a.m_patch > b.m_patch) ? 1 : -1;
}
if (a.m_pre.empty() != b.m_pre.empty())
{
// Either a is empty or b is empty
return a.m_pre.empty() ? 1 : -1;
}
// Either both are empty or both are non-empty (may be equal)
int pre_cmp = a.m_pre.compare(b.m_pre);
if (pre_cmp != 0)
{
return pre_cmp;
}
return a.m_build.compare(b.m_build);
}
bool try_stou(const std::wstring& str, unsigned* num)
{
if (str.empty())
{
return false;
}
if (str.find_first_not_of(TEXT("0123456789")) != std::wstring::npos)
{
return false;
}
*num = (unsigned)std::stoul(str);
return true;
}
bool parse_internal(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production)
{
size_t maj_start = 0;
size_t maj_sep = ver.find(TEXT('.'));
if (maj_sep == std::wstring::npos)
{
return false;
}
unsigned major = 0;
if (!try_stou(ver.substr(maj_start, maj_sep), &major))
{
return false;
}
size_t min_start = maj_sep + 1;
size_t min_sep = ver.find(TEXT('.'), min_start);
if (min_sep == std::wstring::npos)
{
return false;
}
unsigned minor = 0;
if (!try_stou(ver.substr(min_start, min_sep - min_start), &minor))
{
return false;
}
unsigned patch = 0;
size_t pat_start = min_sep + 1;
size_t pat_sep = ver.find_first_not_of(TEXT("0123456789"), pat_start);
if (pat_sep == std::wstring::npos)
{
if (!try_stou(ver.substr(pat_start), &patch))
{
return false;
}
*fx_ver = fx_ver_t(major, minor, patch);
return true;
}
if (parse_only_production)
{
// This is a prerelease or has build suffix.
return false;
}
if (!try_stou(ver.substr(pat_start, pat_sep - pat_start), &patch))
{
return false;
}
size_t pre_start = pat_sep;
size_t pre_sep = ver.find(TEXT('+'), pre_start);
if (pre_sep == std::wstring::npos)
{
*fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start));
return true;
}
else
{
size_t build_start = pre_sep + 1;
*fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start, pre_sep - pre_start), ver.substr(build_start));
return true;
}
}
/* static */
bool fx_ver_t::parse(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production)
{
bool valid = parse_internal(ver, fx_ver, parse_only_production);
assert(!valid || fx_ver->as_str() == ver);
return valid;
}

46
src/CommonLib/fx_ver.h Normal file
Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,259 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
HOSTFXR_UTILITY::HOSTFXR_UTILITY()
{
}
HOSTFXR_UTILITY::~HOSTFXR_UTILITY()
{
}
HRESULT
HOSTFXR_UTILITY::FindHostFxrDll(
ASPNETCORE_CONFIG *pConfig,
STRU* struHostFxrDllLocation,
BOOL* fStandAlone
)
{
HRESULT hr = S_OK;
// If the process path isn't dotnet, assume we are a standalone appliction.
// TODO: this should be a path equivalent check
if (!(pConfig->QueryProcessPath()->Equals(L".\\dotnet")
|| pConfig->QueryProcessPath()->Equals(L"dotnet")
|| pConfig->QueryProcessPath()->Equals(L".\\dotnet.exe")
|| pConfig->QueryProcessPath()->Equals(L"dotnet.exe")))
{
// hostfxr is in the same folder, parse and use it.
hr = GetStandaloneHostfxrLocation(struHostFxrDllLocation, pConfig);
*fStandAlone = TRUE;
}
else
{
hr = GetPortableHostfxrLocation(struHostFxrDllLocation);
fStandAlone = FALSE;
}
return hr;
}
//
// Runs a standalone appliction.
// The folder structure looks like this:
// Application/
// hostfxr.dll
// Application.exe
// Application.dll
// etc.
// We get the full path to hostfxr.dll and Application.dll and run hostfxr_main,
// passing in Application.dll.
// Assuming we don't need Application.exe as the dll is the actual application.
//
HRESULT
HOSTFXR_UTILITY::GetStandaloneHostfxrLocation(
STRU* struHostfxrPath,
ASPNETCORE_CONFIG *pConfig
)
{
HRESULT hr = S_OK;
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
SECURITY_ATTRIBUTES saAttr;
// Get the full path to the exe and check if it exists
if (FAILED(hr = UTILITY::ConvertPathToFullPath(L"\\hostfxr.dll",
pConfig->QueryApplicationPhysicalPath()->QueryStr(),
struHostfxrPath)))
{
goto Finished;
}
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
hFileHandle = CreateFile(struHostfxrPath->QueryStr(),
GENERIC_READ,
FILE_SHARE_READ,
&saAttr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
// Treat access isseu as File not found
hr = ERROR_FILE_NOT_FOUND;
goto Finished;
}
else
{
CloseHandle(hFileHandle);
}
Finished:
return hr;
}
HRESULT
HOSTFXR_UTILITY::GetPortableHostfxrLocation(
STRU* struHostfxrPath
)
{
HRESULT hr = S_OK;
STRU struSystemPathVariable;
STRU strDotnetExeLocation;
STRU strHostFxrSearchExpression;
STRU strHighestDotnetVersion;
PWSTR pwzDelimeterContext = NULL;
PCWSTR pszDotnetLocation = NULL;
PCWSTR pszDotnetExeString(L"dotnet.exe");
DWORD dwCopyLength;
BOOL fFound = FALSE;
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
SECURITY_ATTRIBUTES saAttr;
std::vector<std::wstring> vVersionFolders;
if (FAILED(hr))
{
goto Finished;
}
// Get the System PATH value.
if (!UTILITY::GetSystemPathVariable(L"PATH", &struSystemPathVariable))
{
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Split on ';', checking to see if dotnet.exe exists in any folders.
pszDotnetLocation = wcstok_s(struSystemPathVariable.QueryStr(), L";", &pwzDelimeterContext);
while (pszDotnetLocation != NULL)
{
dwCopyLength = (DWORD) wcsnlen_s(pszDotnetLocation, 260);
// We store both the exe and folder locations as we eventually need to check inside of host\\fxr
// which doesn't need the dotnet.exe portion of the string
hr = strDotnetExeLocation.Copy(pszDotnetLocation, dwCopyLength);
if (FAILED(hr))
{
goto Finished;
}
if (dwCopyLength > 0 && pszDotnetLocation[dwCopyLength - 1] != L'\\')
{
hr = strDotnetExeLocation.Append(L"\\");
if (FAILED(hr))
{
goto Finished;
}
}
hr = struHostfxrPath->Copy(strDotnetExeLocation);
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetExeLocation.Append(pszDotnetExeString);
if (FAILED(hr))
{
goto Finished;
}
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
hFileHandle = CreateFile(strDotnetExeLocation.QueryStr(),
GENERIC_READ,
FILE_SHARE_READ,
&saAttr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFileHandle != INVALID_HANDLE_VALUE)
{
// means we found the folder with a dotnet.exe inside of it.
fFound = TRUE;
CloseHandle(hFileHandle);
break;
}
pszDotnetLocation = wcstok_s(NULL, L";", &pwzDelimeterContext);
}
if (!fFound)
{
// could not find dotnet.exe, error out
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
hr = struHostfxrPath->Append(L"host\\fxr");
if (FAILED(hr))
{
goto Finished;
}
if (!UTILITY::DirectoryExists(struHostfxrPath))
{
// error, not found the folder
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Find all folders under host\\fxr\\ for version numbers.
hr = strHostFxrSearchExpression.Copy(struHostfxrPath);
if (FAILED(hr))
{
goto Finished;
}
hr = strHostFxrSearchExpression.Append(L"\\*");
if (FAILED(hr))
{
goto Finished;
}
// As we use the logic from core-setup, we are opting to use std here.
// TODO remove all uses of std?
UTILITY::FindDotNetFolders(strHostFxrSearchExpression.QueryStr(), &vVersionFolders);
if (vVersionFolders.size() == 0)
{
// no core framework was found
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
hr = UTILITY::FindHighestDotNetVersion(vVersionFolders, &strHighestDotnetVersion);
if (FAILED(hr))
{
goto Finished;
}
hr = struHostfxrPath->Append(L"\\");
if (FAILED(hr))
{
goto Finished;
}
hr = struHostfxrPath->Append(strHighestDotnetVersion.QueryStr());
if (FAILED(hr))
{
goto Finished;
}
hr = struHostfxrPath->Append(L"\\hostfxr.dll");
if (FAILED(hr))
{
goto Finished;
}
Finished:
return hr;
}

Просмотреть файл

@ -0,0 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
class HOSTFXR_UTILITY
{
public:
HOSTFXR_UTILITY();
~HOSTFXR_UTILITY();
static
HRESULT
FindHostFxrDll(
ASPNETCORE_CONFIG *pConfig,
STRU* struHostFxrDllLocation,
BOOL* fStandAlone
);
static
HRESULT
GetStandaloneHostfxrLocation(
STRU* struHostfxrPath,
ASPNETCORE_CONFIG *pConfig
);
static
HRESULT
GetPortableHostfxrLocation(
STRU* struHostfxrPath
);
};

Просмотреть файл

@ -0,0 +1,44 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
REQUEST_HANDLER::REQUEST_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication)
: m_cRefs(1)
{
m_pW3Context = pW3Context;
m_pApplication = pApplication;
m_pModuleId = *pModuleId;
}
REQUEST_HANDLER::~REQUEST_HANDLER()
{
}
VOID
REQUEST_HANDLER::ReferenceRequestHandler(
VOID
) const
{
InterlockedIncrement(&m_cRefs);
}
VOID
REQUEST_HANDLER::DereferenceRequestHandler(
VOID
) const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
delete this;
}
}

Просмотреть файл

@ -0,0 +1,59 @@
// 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 "application.h"
//
// Abstract class
//
class REQUEST_HANDLER
{
public:
REQUEST_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication
);
virtual
REQUEST_NOTIFICATION_STATUS
OnExecuteRequestHandler() = 0;
virtual
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
DWORD cbCompletion,
HRESULT hrCompletionStatus
) = 0;
virtual
VOID
TerminateRequest(
bool fClientInitiated
) = 0;
virtual
~REQUEST_HANDLER(
VOID
);
VOID
ReferenceRequestHandler(
VOID
) const;
virtual
VOID
DereferenceRequestHandler(
VOID
) const;
protected:
mutable LONG m_cRefs;
IHttpContext* m_pW3Context;
APPLICATION* m_pApplication;
HTTP_MODULE_ID m_pModuleId;
};

Двоичные данные
src/CommonLib/stdafx.cpp Normal file

Двоичный файл не отображается.

Двоичные данные
src/CommonLib/stdafx.h Normal file

Двоичный файл не отображается.

Двоичные данные
src/CommonLib/targetver.h Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -1,11 +1,11 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
#include"stdafx.h"
// static
HRESULT
PATH::SplitUrl(
UTILITY::SplitUrl(
PCWSTR pszDestinationUrl,
BOOL *pfSecure,
STRU *pstrDestination,
@ -95,7 +95,7 @@ Return Value:
// static
HRESULT
PATH::UnEscapeUrl(
UTILITY::UnEscapeUrl(
PCWSTR pszUrl,
DWORD cchUrl,
bool fCopyQuery,
@ -151,7 +151,7 @@ PATH::UnEscapeUrl(
// static
HRESULT
PATH::UnEscapeUrl(
UTILITY::UnEscapeUrl(
PCWSTR pszUrl,
DWORD cchUrl,
STRU * pstrResult
@ -231,7 +231,7 @@ PATH::UnEscapeUrl(
}
HRESULT
PATH::EscapeAbsPath(
UTILITY::EscapeAbsPath(
IHttpRequest * pRequest,
STRU * strEscapedUrl
)
@ -269,7 +269,7 @@ Finished:
// static
bool
PATH::IsValidAttributeNameChar(
UTILITY::IsValidAttributeNameChar(
WCHAR ch
)
{
@ -282,7 +282,7 @@ PATH::IsValidAttributeNameChar(
// static
bool
PATH::FindInMultiString(
UTILITY::FindInMultiString(
PCWSTR pszMultiString,
PCWSTR pszStringToFind
)
@ -301,7 +301,7 @@ PATH::FindInMultiString(
// static
bool
PATH::IsValidQueryStringName(
UTILITY::IsValidQueryStringName(
PCWSTR pszName
)
{
@ -322,7 +322,7 @@ PATH::IsValidQueryStringName(
// static
bool
PATH::IsValidHeaderName(
UTILITY::IsValidHeaderName(
PCWSTR pszName
)
{
@ -342,7 +342,7 @@ PATH::IsValidHeaderName(
}
HRESULT
PATH::IsPathUnc(
UTILITY::IsPathUnc(
__in LPCWSTR pszPath,
__out BOOL * pfIsUnc
)
@ -373,7 +373,7 @@ Finished:
}
HRESULT
PATH::ConvertPathToFullPath(
UTILITY::ConvertPathToFullPath(
_In_ LPCWSTR pszPath,
_In_ LPCWSTR pszRootPath,
_Out_ STRU* pStruFullPath
@ -384,7 +384,7 @@ PATH::ConvertPathToFullPath(
LPWSTR pszFullPath = NULL;
// if relative path, prefix with root path and then convert to absolute path.
if( pszPath[0] == L'.' )
if ( pszPath[0] == L'.' )
{
hr = strFileFullPath.Copy(pszRootPath);
if(FAILED(hr))
@ -403,13 +403,13 @@ PATH::ConvertPathToFullPath(
}
hr = strFileFullPath.Append( pszPath );
if(FAILED(hr))
if (FAILED(hr))
{
goto Finished;
}
pszFullPath = new WCHAR[ strFileFullPath.QueryCCH() + 1];
if( pszFullPath == NULL )
if ( pszFullPath == NULL )
{
hr = E_OUTOFMEMORY;
goto Finished;
@ -425,18 +425,185 @@ PATH::ConvertPathToFullPath(
// convert to canonical path
hr = MakePathCanonicalizationProof( pszFullPath, pStruFullPath );
if(FAILED(hr))
if (FAILED(hr))
{
goto Finished;
}
Finished:
if( pszFullPath != NULL )
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;
}
HRESULT
UTILITY::FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
)
{
HRESULT hr = S_OK;
fx_ver_t max_ver(-1, -1, -1);
for (const auto& dir : vFolders)
{
fx_ver_t fx_ver(-1, -1, -1);
if (fx_ver_t::parse(dir, &fx_ver, false))
{
// TODO using max instead of std::max works
max_ver = max(max_ver, fx_ver);
}
}
hr = pstrResult->Copy(max_ver.as_str().c_str());
// we check FAILED(hr) outside of function
return hr;
}
BOOL
UTILITY::DirectoryExists(
_In_ STRU *pstrPath
)
{
WIN32_FILE_ATTRIBUTE_DATA data;
if (pstrPath->IsEmpty())
{
return false;
}
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
}
BOOL
UTILITY::GetSystemPathVariable(
_In_ PCWSTR pszEnvironmentVariable,
_Out_ STRU *pstrResult
)
{
DWORD dwLength;
PWSTR pszBuffer = NULL;
BOOL fSucceeded = FALSE;
if (pszEnvironmentVariable == NULL)
{
goto Finished;
}
pstrResult->Reset();
dwLength = GetEnvironmentVariableW(pszEnvironmentVariable, NULL, 0);
if (dwLength == 0)
{
goto Finished;
}
pszBuffer = new WCHAR[dwLength];
if (GetEnvironmentVariableW(pszEnvironmentVariable, pszBuffer, dwLength) == 0)
{
goto Finished;
}
pstrResult->Copy(pszBuffer);
fSucceeded = TRUE;
Finished:
if (pszBuffer != NULL) {
delete[] pszBuffer;
}
return fSucceeded;
}
VOID
UTILITY::FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
)
{
HANDLE handle = NULL;
WIN32_FIND_DATAW data = { 0 };
handle = FindFirstFileExW(pszPath, FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0);
if (handle == INVALID_HANDLE_VALUE)
{
return;
}
do
{
std::wstring folder(data.cFileName);
pvFolders->push_back(folder);
} while (FindNextFileW(handle, &data));
FindClose(handle);
}

Просмотреть файл

@ -3,7 +3,7 @@
#pragma once
class PATH
class UTILITY
{
public:
@ -79,17 +79,41 @@ public:
_Out_ STRU* pStrFullPath
);
private:
PATH() {}
~PATH() {}
static
HRESULT
EnsureDirectoryPathExist(
_In_ LPCWSTR pszPath
);
static
CHAR
ToHexDigit(
UINT nDigit
)
{
return static_cast<CHAR>(nDigit > 9 ? nDigit - 10 + 'A' : nDigit + '0');
}
BOOL
DirectoryExists(
_In_ STRU *pstrPath
);
static
BOOL
GetSystemPathVariable(
_In_ PCWSTR pszEnvironmentVariable,
_Out_ STRU *pstrResult
);
static
VOID
FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
);
static
HRESULT
FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
);
private:
UTILITY() {}
~UTILITY() {}
};

Просмотреть файл

@ -23,7 +23,7 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>IISLib</RootNamespace>
<ProjectName>IISLib</ProjectName>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -78,6 +78,8 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -94,6 +96,7 @@
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -111,6 +114,7 @@
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -130,6 +134,7 @@
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

Просмотреть файл

@ -4,6 +4,9 @@
#include <windows.h>
#include <ahadmin.h>
#pragma warning( disable:4127 )
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <atlcomcli.h>
#include <strsafe.h>
#include <intsafe.h>
@ -16,3 +19,4 @@
#include "ahutil.h"
#include "acache.h"
//#include "base64.hxx"

Двоичные данные
src/RequestHandler/RequestHandler.rc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\Build\Build.Settings" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{D57EA297-6DC2-4BC0-8C91-334863327863}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>RequestHandler</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
<ProjectName>RequestHandler</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetName>aspnetcorerh</TargetName>
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetName>aspnetcorerh</TargetName>
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>aspnetcorerh</TargetName>
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>aspnetcorerh</TargetName>
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ahadmin.lib;rpcrt4.lib;winhttp.lib;pdh.lib;ws2_32.lib;wbemuuid.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ahadmin.lib;rpcrt4.lib;winhttp.lib;pdh.lib;ws2_32.lib;wbemuuid.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;winhttp.lib;odbc32.lib;ws2_32.lib;odbccp32.lib;wbemuuid.lib;iphlpapi.lib;pdh.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessKeepComments>false</PreprocessKeepComments>
<ExceptionHandling>SyncCThrow</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OmitDefaultLibName>true</OmitDefaultLibName>
<CompileAs>CompileAsCpp</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;rpcrt4.lib;winhttp.lib;pdh.lib;ws2_32.lib;wbemuuid.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="aspnetcore_event.h" />
<ClInclude Include="aspnetcore_msg.h" />
<ClInclude Include="disconnectcontext.h" />
<ClInclude Include="sttimer.h" />
<ClInclude Include="outofprocess\forwarderconnection.h" />
<ClInclude Include="outofprocess\processmanager.h" />
<ClInclude Include="outofprocess\protocolconfig.h" />
<ClInclude Include="outofprocess\responseheaderhash.h" />
<ClInclude Include="outofprocess\serverprocess.h" />
<ClInclude Include="outofprocess\websockethandler.h" />
<ClInclude Include="outofprocess\winhttphelper.h" />
<ClInclude Include="precomp.hxx" />
<ClInclude Include="resource.h" />
<ClInclude Include=".\inprocess\inprocessapplication.h" />
<ClInclude Include=".\inprocess\inprocesshandler.h" />
<ClInclude Include=".\outofprocess\forwardinghandler.h" />
<ClInclude Include=".\outofprocess\outprocessapplication.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cxx" />
<ClCompile Include=".\inprocess\inprocessapplication.cpp" />
<ClCompile Include=".\inprocess\inprocesshandler.cpp" />
<ClCompile Include=".\outofprocess\forwardinghandler.cpp" />
<ClCompile Include=".\outofprocess\outprocessapplication.cpp" />
<ClCompile Include="managedexports.cxx" />
<ClCompile Include="outofprocess\forwarderconnection.cxx" />
<ClCompile Include="outofprocess\processmanager.cxx" />
<ClCompile Include="outofprocess\protocolconfig.cxx" />
<ClCompile Include="outofprocess\responseheaderhash.cxx" />
<ClCompile Include="outofprocess\serverprocess.cxx" />
<ClCompile Include="outofprocess\websockethandler.cxx" />
<ClCompile Include="outofprocess\winhttphelper.cxx" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="aspnetcore_msg.mc">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">
<Project>{55494e58-e061-4c4c-a0a8-837008e72f85}</Project>
</ProjectReference>
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RequestHandler.rc" />
</ItemGroup>
<ItemGroup>
<None Include="Source.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Просмотреть файл

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="dllmain.cxx" />
<ClCompile Include=".\inprocess\inprocessapplication.cpp">
<Filter>InProcess</Filter>
</ClCompile>
<ClCompile Include=".\inprocess\inprocesshandler.cpp">
<Filter>InProcess</Filter>
</ClCompile>
<ClCompile Include="managedexports.cxx">
<Filter>InProcess</Filter>
</ClCompile>
<ClCompile Include=".\outofprocess\forwardinghandler.cpp">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include=".\outofprocess\outprocessapplication.cpp">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include="outofprocess\processmanager.cxx">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include="outofprocess\protocolconfig.cxx">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include="outofprocess\serverprocess.cxx">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include="outofprocess\forwarderconnection.cxx">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include="outofprocess\responseheaderhash.cxx">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include="outofprocess\websockethandler.cxx">
<Filter>OutOfProcess</Filter>
</ClCompile>
<ClCompile Include="outofprocess\winhttphelper.cxx">
<Filter>OutOfProcess</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="precomp.hxx" />
<ClInclude Include="resource.h" />
<ClInclude Include=".\inprocess\inprocessapplication.h">
<Filter>InProcess</Filter>
</ClInclude>
<ClInclude Include=".\inprocess\inprocesshandler.h">
<Filter>InProcess</Filter>
</ClInclude>
<ClInclude Include=".\outofprocess\forwardinghandler.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\forwarderconnection.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\responseheaderhash.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include=".\outofprocess\outprocessapplication.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\processmanager.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\protocolconfig.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\serverprocess.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\responseheaderhash.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\websockethandler.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="outofprocess\winhttphelper.h">
<Filter>OutOfProcess</Filter>
</ClInclude>
<ClInclude Include="disconnectcontext.h" />
<ClInclude Include="aspnetcore_event.h" />
<ClInclude Include="sttimer.h" />
<ClInclude Include="aspnetcore_msg.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RequestHandler.rc" />
</ItemGroup>
<ItemGroup>
<None Include="Source.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RequestHandler.rc" />
</ItemGroup>
<ItemGroup>
<None Include="Source.def" />
</ItemGroup>
<ItemGroup>
<Filter Include="InProcess">
<UniqueIdentifier>{e567abb5-bac5-4f05-a320-5e25dcfc0000}</UniqueIdentifier>
</Filter>
<Filter Include="OutOfProcess">
<UniqueIdentifier>{5568209f-269e-4d0a-bbb7-ba14f874ccb7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="aspnetcore_msg.mc" />
</ItemGroup>
</Project>

Двоичные данные
src/RequestHandler/Resource.rc Normal file

Двоичный файл не отображается.

Просмотреть файл

Просмотреть файл

@ -0,0 +1,6 @@
LIBRARY aspnetcorerh
EXPORTS
CreateApplication
CreateRequestHandler

Просмотреть файл

@ -0,0 +1,165 @@
/*++
Copyright (c) .NET Foundation. All rights reserved.
Licensed under the MIT License. See License.txt in the project root for license information.
Module Name:
aspnetcore_msg.mc
Abstract:
Asp.Net Core Module localizable messages.
--*/
#ifndef _ASPNETCORE_MSG_H_
#define _ASPNETCORE_MSG_H_
//
// Values are 32 bit values laid out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+-+-+-----------------------+-------------------------------+
// |Sev|C|R| Facility | Code |
// +---+-+-+-----------------------+-------------------------------+
//
// where
//
// Sev - is the severity code
//
// 00 - Success
// 01 - Informational
// 10 - Warning
// 11 - Error
//
// C - is the Customer code flag
//
// R - is a reserved bit
//
// Facility - is the facility code
//
// Code - is the facility's status code
//
//
// Define the facility codes
//
//
// Define the severity codes
//
//
// MessageId: ASPNETCORE_EVENT_PROCESS_START_ERROR
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_PROCESS_START_ERROR ((DWORD)0x000003E8L)
//
// MessageId: ASPNETCORE_EVENT_PROCESS_START_SUCCESS
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS ((DWORD)0x000003E9L)
//
// MessageId: ASPNETCORE_EVENT_PROCESS_CRASH
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_PROCESS_CRASH ((DWORD)0x000003EAL)
//
// MessageId: ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED ((DWORD)0x000003EBL)
//
// MessageId: ASPNETCORE_EVENT_CONFIG_ERROR
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_CONFIG_ERROR ((DWORD)0x000003ECL)
//
// MessageId: ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE ((DWORD)0x000003EDL)
//
// MessageId: ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST ((DWORD)0x000003EEL)
//
// MessageId: ASPNETCORE_EVENT_LOAD_CLR_FALIURE
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_LOAD_CLR_FALIURE ((DWORD)0x000003EFL)
//
// MessageId: ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP ((DWORD)0x000003F0L)
//
// MessageId: ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR ((DWORD)0x000003F1L)
//
// MessageId: ASPNETCORE_EVENT_ADD_APPLICATION_ERROR
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_ADD_APPLICATION_ERROR ((DWORD)0x000003F2L)
//
// MessageId: ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT
//
// MessageText:
//
// %1
//
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT ((DWORD)0x000003F3L)
#endif // _ASPNETCORE_MODULE_MSG_H_

Просмотреть файл

@ -0,0 +1,2 @@
LANGUAGE 0x9,0x1
1 11 "MSG00001.bin"

Просмотреть файл

@ -0,0 +1,78 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
class ASYNC_DISCONNECT_CONTEXT : public IHttpConnectionStoredContext
{
public:
ASYNC_DISCONNECT_CONTEXT()
{
m_pHandler = NULL;
}
VOID
CleanupStoredContext()
{
DBG_ASSERT(m_pHandler == NULL);
delete this;
}
VOID
NotifyDisconnect()
{
REQUEST_HANDLER *pInitialValue = (REQUEST_HANDLER*)
InterlockedExchangePointer((PVOID*)&m_pHandler, NULL);
if (pInitialValue != NULL)
{
pInitialValue->TerminateRequest(TRUE);
pInitialValue->DereferenceRequestHandler();
}
}
VOID
SetHandler(
REQUEST_HANDLER *pHandler
)
{
//
// Take a reference on the forwarding handler.
// This reference will be released on either of two conditions:
//
// 1. When the request processing ends, in which case a ResetHandler()
// is called.
//
// 2. When a disconnect notification arrives.
//
// We need to make sure that only one of them ends up dereferencing
// the object.
//
DBG_ASSERT(pHandler != NULL);
DBG_ASSERT(m_pHandler == NULL);
pHandler->ReferenceRequestHandler();
InterlockedExchangePointer((PVOID*)&m_pHandler, pHandler);
}
VOID
ResetHandler(
VOID
)
{
REQUEST_HANDLER *pInitialValue = (REQUEST_HANDLER*)
InterlockedExchangePointer((PVOID*)&m_pHandler, NULL);
if (pInitialValue != NULL)
{
pInitialValue->DereferenceRequestHandler();
}
}
private:
~ASYNC_DISCONNECT_CONTEXT()
{}
REQUEST_HANDLER * m_pHandler;
};

Просмотреть файл

@ -0,0 +1,340 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "precomp.hxx"
#include <IPHlpApi.h>
#include <VersionHelpers.h>
BOOL g_fNsiApiNotSupported = FALSE;
BOOL g_fWebSocketSupported = FALSE;
BOOL g_fEnableReferenceCountTracing = FALSE;
BOOL g_fOutOfProcessInitialize = FALSE;
BOOL g_fOutOfProcessInitializeError = FALSE;
BOOL g_fWinHttpNonBlockingCallbackAvailable = FALSE;
DWORD g_OptionalWinHttpFlags = 0;
DWORD g_dwAspNetCoreDebugFlags = 0;
DWORD g_dwDebugFlags = 0;
DWORD g_dwTlsIndex = TLS_OUT_OF_INDEXES;
SRWLOCK g_srwLockRH;
HINTERNET g_hWinhttpSession = NULL;
IHttpServer * g_pHttpServer = NULL;
HINSTANCE g_hWinHttpModule;
VOID
InitializeGlobalConfiguration(
VOID
)
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
0,
KEY_READ,
&hKey) == NO_ERROR)
{
DWORD dwType;
DWORD dwData;
DWORD cbData;
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"OptionalWinHttpFlags",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
g_OptionalWinHttpFlags = dwData;
}
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"EnableReferenceCountTracing",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD) && (dwData == 1 || dwData == 0))
{
g_fEnableReferenceCountTracing = !!dwData;
}
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"DebugFlags",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
g_dwAspNetCoreDebugFlags = dwData;
}
RegCloseKey(hKey);
}
DWORD dwSize = 0;
DWORD dwResult = GetExtendedTcpTable(NULL,
&dwSize,
FALSE,
AF_INET,
TCP_TABLE_OWNER_PID_LISTENER,
0);
if (dwResult != NO_ERROR && dwResult != ERROR_INSUFFICIENT_BUFFER)
{
g_fNsiApiNotSupported = TRUE;
}
// WebSocket is supported on Win8 and above only
// todo: test on win7
g_fWebSocketSupported = IsWindows8OrGreater();
}
//
// Global initialization routine for OutOfProcess
//
HRESULT
EnsureOutOfProcessInitializtion( IHttpServer* pServer)
{
DBG_ASSERT(pServer);
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
g_pHttpServer = pServer;
if (g_fOutOfProcessInitializeError)
{
hr = E_NOT_VALID_STATE;
goto Finished;
}
if (!g_fOutOfProcessInitialize)
{
AcquireSRWLockExclusive(&g_srwLockRH);
fLocked = TRUE;
if (g_fOutOfProcessInitializeError)
{
hr = E_NOT_VALID_STATE;
goto Finished;
}
if (g_fOutOfProcessInitialize)
{
// Done by another thread
goto Finished;
}
// Initialze some global variables here
InitializeGlobalConfiguration();
g_hWinHttpModule = GetModuleHandle(TEXT("winhttp.dll"));
hr = WINHTTP_HELPER::StaticInitialize();
if (FAILED(hr))
{
if (hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND))
{
g_fWebSocketSupported = FALSE;
}
else
{
goto Finished;
}
}
g_hWinhttpSession = WinHttpOpen(L"",
WINHTTP_ACCESS_TYPE_NO_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
WINHTTP_FLAG_ASYNC);
if (g_hWinhttpSession == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
//
// Don't set non-blocking callbacks WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS,
// as we will call WinHttpQueryDataAvailable to get response on the same thread
// that we received callback from Winhttp on completing sending/forwarding the request
//
//
// Setup the callback function
//
if (WinHttpSetStatusCallback(g_hWinhttpSession,
FORWARDING_HANDLER::OnWinHttpCompletion,
(WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS |
WINHTTP_CALLBACK_STATUS_SENDING_REQUEST),
NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
//
// Make sure we see the redirects (rather than winhttp doing it
// automatically)
//
DWORD dwRedirectOption = WINHTTP_OPTION_REDIRECT_POLICY_NEVER;
if (!WinHttpSetOption(g_hWinhttpSession,
WINHTTP_OPTION_REDIRECT_POLICY,
&dwRedirectOption,
sizeof(dwRedirectOption)))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_dwTlsIndex = TlsAlloc();
if (g_dwTlsIndex == TLS_OUT_OF_INDEXES)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
hr = FORWARDING_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
if (FAILED(hr))
{
goto Finished;
}
hr = WEBSOCKET_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
if (FAILED(hr))
{
goto Finished;
}
}
Finished:
if (FAILED(hr))
{
g_fOutOfProcessInitializeError = TRUE;
}
if (fLocked)
{
ReleaseSRWLockExclusive(&g_srwLockRH);
}
return hr;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
UNREFERENCED_PARAMETER(lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
InitializeSRWLock(&g_srwLockRH);
// Initialze some global variables here
InitializeGlobalConfiguration();
break;
default:
break;
}
return TRUE;
}
HRESULT
__stdcall
CreateApplication(
_In_ IHttpServer *pServer,
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ APPLICATION **ppApplication
)
{
HRESULT hr = S_OK;
APPLICATION *pApplication = NULL;
//REQUEST_HANDLER::StaticInitialize(pServer);
if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
pApplication = new IN_PROCESS_APPLICATION(pServer, pConfig);
if (pApplication == NULL)
{
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
goto Finished;
}
}
else if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_OUT_PROCESS)
{
hr = EnsureOutOfProcessInitializtion(pServer);
if (FAILED(hr))
{
goto Finished;
}
pApplication = new OUT_OF_PROCESS_APPLICATION(pServer, pConfig);
if (pApplication == NULL)
{
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
goto Finished;
}
hr = ((OUT_OF_PROCESS_APPLICATION*)pApplication)->Initialize();
if (FAILED(hr))
{
delete pApplication;
pApplication = NULL;
goto Finished;
}
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
goto Finished;
}
*ppApplication = pApplication;
Finished:
return hr;
}
HRESULT
__stdcall
CreateRequestHandler(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication,
_Out_ REQUEST_HANDLER **pRequestHandler
)
{
HRESULT hr = S_OK;
REQUEST_HANDLER* pHandler = NULL;
ASPNETCORE_CONFIG* pConfig = pApplication->QueryConfig();
DBG_ASSERT(pConfig);
if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
pHandler = new IN_PROCESS_HANDLER(pHttpContext, pModuleId, pApplication);
}
else if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_OUT_PROCESS)
{
pHandler = new FORWARDING_HANDLER(pHttpContext, pModuleId, pApplication);
}
else
{
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
if (pHandler == NULL)
{
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
}
else
{
*pRequestHandler = pHandler;
}
return hr;
}

Просмотреть файл

@ -0,0 +1,889 @@
#include "..\precomp.hxx"
typedef DWORD(*hostfxr_main_fn) (CONST DWORD argc, CONST WCHAR* argv[]);
IN_PROCESS_APPLICATION* IN_PROCESS_APPLICATION::s_Application = NULL;
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
IHttpServer* pHttpServer,
ASPNETCORE_CONFIG* pConfig) :
APPLICATION(pHttpServer, pConfig),
m_ProcessExitCode(0),
m_fManagedAppLoaded(FALSE),
m_fLoadManagedAppError(FALSE),
m_fInitialized(FALSE),
m_fRecycleProcessCalled(FALSE),
m_hLogFileHandle(INVALID_HANDLE_VALUE),
m_fDoneStdRedirect(FALSE)
{
// is it guaranteed that we have already checked app offline at this point?
// If so, I don't think there is much to do here.
DBG_ASSERT(pHttpServer != NULL);
DBG_ASSERT(pConfig != NULL);
InitializeSRWLock(&m_srwLock);
// TODO we can probably initialized as I believe we are the only ones calling recycle.
m_fInitialized = TRUE;
m_status = APPLICATION_STATUS::RUNNING;
}
IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
{
Recycle();
}
__override
VOID
IN_PROCESS_APPLICATION::ShutDown()
{
//todo
}
// This is the same function as before, TODO configrm if we need to change anything for configuration.
VOID
IN_PROCESS_APPLICATION::Recycle(
VOID
)
{
if (m_fInitialized)
{
DWORD dwThreadStatus = 0;
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
HANDLE handle = NULL;
WIN32_FIND_DATA fileData;
if (m_pStdFile != NULL)
{
fflush(stdout);
fflush(stderr);
fclose(m_pStdFile);
}
if (m_hLogFileHandle != INVALID_HANDLE_VALUE)
{
m_Timer.CancelTimer();
CloseHandle(m_hLogFileHandle);
m_hLogFileHandle = INVALID_HANDLE_VALUE;
}
// delete empty log file, if logging is not enabled
handle = FindFirstFile(m_struLogFilePath.QueryStr(), &fileData);
if (handle != INVALID_HANDLE_VALUE &&
fileData.nFileSizeHigh &&
fileData.nFileSizeLow == 0) // skip check of nFileSizeHigh
{
FindClose(handle);
// no need to check whether the deletion succeeds
// as nothing can be done
DeleteFile(m_struLogFilePath.QueryStr());
}
AcquireSRWLockExclusive(&m_srwLock);
if (!m_pHttpServer->IsCommandLineLaunch() &&
!m_fRecycleProcessCalled &&
(m_pHttpServer->GetAdminManager() != NULL))
{
// IIS scenario.
// notify IIS first so that new request will be routed to new worker process
m_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand");
}
m_fRecycleProcessCalled = TRUE;
// First call into the managed server and shutdown
if (m_ShutdownHandler != NULL)
{
m_ShutdownHandler(m_ShutdownHandlerContext);
m_ShutdownHandler = NULL;
}
if (m_hThread != NULL &&
GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 &&
dwThreadStatus == STILL_ACTIVE)
{
// wait for gracefullshut down, i.e., the exit of the background thread or timeout
if (WaitForSingleObject(m_hThread, dwTimeout) != WAIT_OBJECT_0)
{
// if the thread is still running, we need kill it first before exit to avoid AV
if (GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE)
{
TerminateThread(m_hThread, STATUS_CONTROL_C_EXIT);
}
}
}
CloseHandle(m_hThread);
m_hThread = NULL;
s_Application = NULL;
ReleaseSRWLockExclusive(&m_srwLock);
if (m_pHttpServer && m_pHttpServer->IsCommandLineLaunch())
{
// IISExpress scenario
// Can only call exit to terminate current process
exit(0);
}
}
}
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_APPLICATION::OnAsyncCompletion(
DWORD cbCompletion,
HRESULT hrCompletionStatus,
IN_PROCESS_HANDLER* pInProcessHandler
)
{
REQUEST_NOTIFICATION_STATUS dwRequestNotificationStatus = RQ_NOTIFICATION_CONTINUE;
if (pInProcessHandler->QueryIsManagedRequestComplete())
{
// means PostCompletion has been called and this is the associated callback.
dwRequestNotificationStatus = pInProcessHandler->QueryAsyncCompletionStatus();
// TODO cleanup whatever disconnect listener there is
return dwRequestNotificationStatus;
}
else
{
// Call the managed handler for async completion.
return m_AsyncCompletionHandler(pInProcessHandler->QueryManagedHttpContext(), hrCompletionStatus, cbCompletion);
}
}
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_APPLICATION::OnExecuteRequest(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler
)
{
if (m_RequestHandler != NULL)
{
return m_RequestHandler(pInProcessHandler, m_RequestHandlerContext);
}
//
// return error as the application did not register callback
//
if (ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::IsEnabled(pHttpContext->GetTraceContext()))
{
ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::RaiseEvent(pHttpContext->GetTraceContext(),
NULL,
(ULONG)E_APPLICATION_ACTIVATION_EXEC_FAILURE);
}
pHttpContext->GetResponse()->SetStatus(500,
"Internal Server Error",
0,
(ULONG)E_APPLICATION_ACTIVATION_EXEC_FAILURE);
return RQ_NOTIFICATION_FINISH_REQUEST;
}
BOOL
IN_PROCESS_APPLICATION::DirectoryExists(
_In_ STRU *pstrPath
)
{
WIN32_FILE_ATTRIBUTE_DATA data;
if (pstrPath->IsEmpty())
{
return false;
}
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
}
BOOL
IN_PROCESS_APPLICATION::GetEnv(
_In_ PCWSTR pszEnvironmentVariable,
_Out_ STRU *pstrResult
)
{
DWORD dwLength;
PWSTR pszBuffer = NULL;
BOOL fSucceeded = FALSE;
if (pszEnvironmentVariable == NULL)
{
goto Finished;
}
pstrResult->Reset();
dwLength = GetEnvironmentVariableW(pszEnvironmentVariable, NULL, 0);
if (dwLength == 0)
{
goto Finished;
}
pszBuffer = new WCHAR[dwLength];
if (GetEnvironmentVariableW(pszEnvironmentVariable, pszBuffer, dwLength) == 0)
{
goto Finished;
}
pstrResult->Copy(pszBuffer);
fSucceeded = TRUE;
Finished:
if (pszBuffer != NULL) {
delete[] pszBuffer;
}
return fSucceeded;
}
VOID
IN_PROCESS_APPLICATION::FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
)
{
HANDLE handle = NULL;
WIN32_FIND_DATAW data = { 0 };
handle = FindFirstFileExW(pszPath, FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0);
if (handle == INVALID_HANDLE_VALUE)
{
return;
}
do
{
std::wstring folder(data.cFileName);
pvFolders->push_back(folder);
} while (FindNextFileW(handle, &data));
FindClose(handle);
}
VOID
IN_PROCESS_APPLICATION::SetCallbackHandles(
_In_ PFN_REQUEST_HANDLER request_handler,
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
_In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
_In_ VOID* pvRequstHandlerContext,
_In_ VOID* pvShutdownHandlerContext
)
{
m_RequestHandler = request_handler;
m_RequestHandlerContext = pvRequstHandlerContext;
m_ShutdownHandler = shutdown_handler;
m_ShutdownHandlerContext = pvShutdownHandlerContext;
m_AsyncCompletionHandler = async_completion_handler;
// Initialization complete
SetEvent(m_pInitalizeEvent);
}
HRESULT
IN_PROCESS_APPLICATION::FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
)
{
HRESULT hr = S_OK;
fx_ver_t max_ver(-1, -1, -1);
for (const auto& dir : vFolders)
{
fx_ver_t fx_ver(-1, -1, -1);
if (fx_ver_t::parse(dir, &fx_ver, false))
{
// TODO using max instead of std::max works
max_ver = max(max_ver, fx_ver);
}
}
hr = pstrResult->Copy(max_ver.as_str().c_str());
// we check FAILED(hr) outside of function
return hr;
}
VOID
IN_PROCESS_APPLICATION::SetStdOut(
VOID
)
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
STRU struPath;
SYSTEMTIME systemTime;
SECURITY_ATTRIBUTES saAttr = { 0 };
if (!m_fDoneStdRedirect)
{
// Have not set stdout yet, redirect stdout to log file
AcquireSRWLockExclusive(&m_srwLock);
fLocked = TRUE;
if (!m_fDoneStdRedirect)
{
hr = UTILITY::ConvertPathToFullPath(
m_pConfig->QueryStdoutLogFile()->QueryStr(),
m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
&struPath);
if (FAILED(hr))
{
goto Finished;
}
hr = UTILITY::EnsureDirectoryPathExist(struPath.QueryStr());
if (FAILED(hr))
{
goto Finished;
}
GetSystemTime(&systemTime);
hr = m_struLogFilePath.SafeSnwprintf(L"%s_%d%02d%02d%02d%02d%02d_%d.log",
struPath.QueryStr(),
systemTime.wYear,
systemTime.wMonth,
systemTime.wDay,
systemTime.wHour,
systemTime.wMinute,
systemTime.wSecond,
GetCurrentProcessId());
if (FAILED(hr))
{
goto Finished;
}
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
m_hLogFileHandle = CreateFileW(m_struLogFilePath.QueryStr(),
FILE_WRITE_DATA,
FILE_SHARE_READ,
&saAttr,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (m_hLogFileHandle == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
//
// best effort
// no need to capture the error code as nothing we can do here
// in case mamanged layer exits abnormally, may not be able to capture the log content as it is buffered.
//
if (!GetConsoleWindow())
{
//
// SetStdHandle works as w3wp does not have Console
// Current process does not have a console
//
SetStdHandle(STD_ERROR_HANDLE, m_hLogFileHandle);
if (m_pConfig->QueryStdoutLogEnabled())
{
SetStdHandle(STD_OUTPUT_HANDLE, m_hLogFileHandle);
// not work
// AllocConsole() does not help
// *stdout = *m_pStdFile;
// *stderr = *m_pStdFile;
// _dup2(_fileno(m_pStdFile), _fileno(stdout));
// _dup2(_fileno(m_pStdFile), _fileno(stderr));
// this one cannot capture the process start failure
// _wfreopen_s(&m_pStdFile, struLogFileName.QueryStr(), L"w", stdout);
// Periodically flush the log content to file
m_Timer.InitializeTimer(STTIMER::TimerCallback, &m_struLogFilePath, 3000, 3000);
}
}
else
{
// The process has console, e.g., IIS Express scenario
CloseHandle(m_hLogFileHandle);
m_hLogFileHandle = INVALID_HANDLE_VALUE;
if (m_pConfig->QueryStdoutLogEnabled())
{
if (_wfopen_s(&m_pStdFile, m_struLogFilePath.QueryStr(), L"w") == 0)
{
// known issue: error info may not be capture when process crashes during buffering
// even we disabled FILE buffering
setvbuf(m_pStdFile, NULL, _IONBF, 0);
_dup2(_fileno(m_pStdFile), _fileno(stdout));
_dup2(_fileno(m_pStdFile), _fileno(stderr));
}
// not work for console scenario
// close and AllocConsole does not help
//_wfreopen_s(&m_pStdFile, struLogFileName.QueryStr(), L"w", stdout);
// SetStdHandle(STD_ERROR_HANDLE, m_hLogFileHandle);
// SetStdHandle(STD_OUTPUT_HANDLE, m_hLogFileHandle);
//*stdout = *m_pStdFile;
//*stderr = *m_pStdFile;
}
else
{
// delete the file as log is disabled
WIN32_FIND_DATA fileData;
HANDLE handle = FindFirstFile(m_struLogFilePath.QueryStr(), &fileData);
if (handle != INVALID_HANDLE_VALUE &&
fileData.nFileSizeHigh == 0 &&
fileData.nFileSizeLow == 0)
{
FindClose(handle);
// no need to check whether the deletion succeeds
// as nothing can be done
DeleteFile(m_struLogFilePath.QueryStr());
}
}
}
}
}
Finished:
m_fDoneStdRedirect = TRUE;
if (fLocked)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
if (FAILED(hr) && m_pConfig->QueryStdoutLogEnabled())
{
//todo log an warning
//STRU strEventMsg;
//LPCWSTR apsz[1];
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
// ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG,
// m_struLogFilePath.QueryStr(),
// HRESULT_FROM_GETLASTERROR())))
//{
// apsz[0] = strEventMsg.QueryStr();
// //
// // not checking return code because if ReportEvent
// // fails, we cannot do anything.
// //
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
// {
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
// EVENTLOG_WARNING_TYPE,
// 0,
// ASPNETCORE_EVENT_CONFIG_ERROR,
// NULL,
// 1,
// 0,
// apsz,
// NULL);
// }
//}
}
}
// Will be called by the inprocesshandler
HRESULT
IN_PROCESS_APPLICATION::LoadManagedApplication
(
VOID
)
{
HRESULT hr = S_OK;
DWORD dwTimeout;
DWORD dwResult;
BOOL fLocked = FALSE;
//PCWSTR apsz[1];
//STACK_STRU(strEventMsg, 256);
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
{
// Core CLR has already been loaded.
// Cannot load more than once even there was a failure
goto Finished;
}
// Set up stdout redirect
SetStdOut();
AcquireSRWLockExclusive(&m_srwLock);
fLocked = TRUE;
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
{
goto Finished;
}
m_hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE)ExecuteAspNetCoreProcess,
this, // thread function arguments
0, // default creation flags
NULL); // receive thread identifier
if (m_hThread == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
m_pInitalizeEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual reset event
FALSE, // not set
NULL); // name
if (m_pInitalizeEvent == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
// If the debugger is attached, never timeout
if (IsDebuggerPresent())
{
dwTimeout = INFINITE;
}
else
{
dwTimeout = m_pConfig->QueryStartupTimeLimitInMS();
}
const HANDLE pHandles[2]{ m_hThread, m_pInitalizeEvent };
// Wait on either the thread to complete or the event to be set
dwResult = WaitForMultipleObjects(2, pHandles, FALSE, dwTimeout);
// It all timed out
if (dwResult == WAIT_TIMEOUT)
{
// kill the backend thread as loading dotnet timedout
TerminateThread(m_hThread, 0);
hr = HRESULT_FROM_WIN32(dwResult);
goto Finished;
}
else if (dwResult == WAIT_FAILED)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
// The thread ended it means that something failed
if (dwResult == WAIT_OBJECT_0)
{
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
goto Finished;
}
m_fManagedAppLoaded = TRUE;
Finished:
if (fLocked)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
if (FAILED(hr))
{
// Question: in case of application loading failure, should we allow retry on
// following request or block the activation at all
m_fLoadManagedAppError = FALSE; // m_hThread != NULL ?
// TODO
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
// ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG,
// m_pConfiguration->QueryApplicationPath()->QueryStr(),
// m_pConfiguration->QueryApplicationPhysicalPath()->QueryStr(),
// hr)))
//{
// apsz[0] = strEventMsg.QueryStr();
// //
// // not checking return code because if ReportEvent
// // fails, we cannot do anything.
// //
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
// {
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
// EVENTLOG_ERROR_TYPE,
// 0,
// ASPNETCORE_EVENT_LOAD_CLR_FALIURE,
// NULL,
// 1,
// 0,
// apsz,
// NULL);
// }
//}
}
return hr;
}
// static
VOID
IN_PROCESS_APPLICATION::ExecuteAspNetCoreProcess(
_In_ LPVOID pContext
)
{
IN_PROCESS_APPLICATION *pApplication = (IN_PROCESS_APPLICATION*)pContext;
DBG_ASSERT(pApplication != NULL);
pApplication->ExecuteApplication();
//
// no need to log the error here as if error happened, the thread will exit
// the error will ba catched by caller LoadManagedApplication which will log an error
//
}
HRESULT
IN_PROCESS_APPLICATION::ExecuteApplication(
VOID
)
{
HRESULT hr = S_OK;
STRU strFullPath;
STRU strDotnetExeLocation;
STRU strHostFxrSearchExpression;
STRU strDotnetFolderLocation;
STRU strHighestDotnetVersion;
STRU strApplicationFullPath;
PWSTR strDelimeterContext = NULL;
PCWSTR pszDotnetExeLocation = NULL;
PCWSTR pszDotnetExeString(L"dotnet.exe");
DWORD dwCopyLength;
HMODULE hModule;
PCWSTR argv[2];
hostfxr_main_fn pProc;
std::vector<std::wstring> vVersionFolders;
bool fFound = FALSE;
// Get the System PATH value.
if (!GetEnv(L"PATH", &strFullPath))
{
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Split on ';', checking to see if dotnet.exe exists in any folders.
pszDotnetExeLocation = wcstok_s(strFullPath.QueryStr(), L";", &strDelimeterContext);
while (pszDotnetExeLocation != NULL)
{
dwCopyLength = (DWORD) wcsnlen_s(pszDotnetExeLocation, 260);
if (dwCopyLength == 0)
{
continue;
}
// We store both the exe and folder locations as we eventually need to check inside of host\\fxr
// which doesn't need the dotnet.exe portion of the string
// TODO consider reducing allocations.
strDotnetExeLocation.Reset();
strDotnetFolderLocation.Reset();
hr = strDotnetExeLocation.Copy(pszDotnetExeLocation, dwCopyLength);
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Copy(pszDotnetExeLocation, dwCopyLength);
if (FAILED(hr))
{
goto Finished;
}
if (dwCopyLength > 0 && pszDotnetExeLocation[dwCopyLength - 1] != L'\\')
{
hr = strDotnetExeLocation.Append(L"\\");
if (FAILED(hr))
{
goto Finished;
}
}
hr = strDotnetExeLocation.Append(pszDotnetExeString);
if (FAILED(hr))
{
goto Finished;
}
if (PathFileExists(strDotnetExeLocation.QueryStr()))
{
// means we found the folder with a dotnet.exe inside of it.
fFound = TRUE;
break;
}
pszDotnetExeLocation = wcstok_s(NULL, L";", &strDelimeterContext);
}
if (!fFound)
{
// could not find dotnet.exe, error out
hr = ERROR_BAD_ENVIRONMENT;
}
hr = strDotnetFolderLocation.Append(L"\\host\\fxr");
if (FAILED(hr))
{
goto Finished;
}
if (!DirectoryExists(&strDotnetFolderLocation))
{
// error, not found the folder
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Find all folders under host\\fxr\\ for version numbers.
hr = strHostFxrSearchExpression.Copy(strDotnetFolderLocation);
if (FAILED(hr))
{
goto Finished;
}
hr = strHostFxrSearchExpression.Append(L"\\*");
if (FAILED(hr))
{
goto Finished;
}
// As we use the logic from core-setup, we are opting to use std here.
// TODO remove all uses of std?
FindDotNetFolders(strHostFxrSearchExpression.QueryStr(), &vVersionFolders);
if (vVersionFolders.size() == 0)
{
// no core framework was found
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
hr = FindHighestDotNetVersion(vVersionFolders, &strHighestDotnetVersion);
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Append(L"\\");
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Append(strHighestDotnetVersion.QueryStr());
if (FAILED(hr))
{
goto Finished;
}
hr = strDotnetFolderLocation.Append(L"\\hostfxr.dll");
if (FAILED(hr))
{
goto Finished;
}
hModule = LoadLibraryW(strDotnetFolderLocation.QueryStr());
if (hModule == NULL)
{
// .NET Core not installed (we can log a more detailed error message here)
hr = ERROR_BAD_ENVIRONMENT;
goto Finished;
}
// Get the entry point for main
pProc = (hostfxr_main_fn)GetProcAddress(hModule, "hostfxr_main");
if (pProc == NULL)
{
hr = ERROR_BAD_ENVIRONMENT; // better hrresult?
goto Finished;
}
// The first argument is mostly ignored
argv[0] = strDotnetExeLocation.QueryStr();
UTILITY::ConvertPathToFullPath(m_pConfig->QueryArguments()->QueryStr(),
m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
&strApplicationFullPath);
argv[1] = strApplicationFullPath.QueryStr();
// There can only ever be a single instance of .NET Core
// loaded in the process but we need to get config information to boot it up in the
// first place. This is happening in an execute request handler and everyone waits
// until this initialization is done.
// We set a static so that managed code can call back into this instance and
// set the callbacks
s_Application = this;
RunDotnetApplication(argv, pProc);
Finished:
//
// this method is called by the background thread and should never exit unless shutdown
//
if (!m_fRecycleProcessCalled)
{
//STRU strEventMsg;
//LPCWSTR apsz[1];
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
// ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG,
// m_pConfig->QueryApplicationPath()->QueryStr(),
// m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
// m_ProcessExitCode
//)))
//{
// apsz[0] = strEventMsg.QueryStr();
// //
// // not checking return code because if ReportEvent
// // fails, we cannot do anything.
// //
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
// {
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
// EVENTLOG_ERROR_TYPE,
// 0,
// ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT,
// NULL,
// 1,
// 0,
// apsz,
// NULL);
// }
// // error. the thread exits after application started
// // Question: should we shutdown current worker process or keep the application in failure state?
// // for now, we reccylce to keep the same behavior as that of out-of-process
//}
if (m_fManagedAppLoaded)
{
Recycle();
}
}
return hr;
}
//
// Calls hostfxr_main with the hostfxr and application as arguments.
// Method should be called with only
// Need to have __try / __except in methods that require unwinding.
//
HRESULT
IN_PROCESS_APPLICATION::RunDotnetApplication(PCWSTR* argv, hostfxr_main_fn pProc)
{
HRESULT hr = S_OK;
__try
{
m_ProcessExitCode = pProc(2, argv);
}
__except (FilterException(GetExceptionCode(), GetExceptionInformation()))
{
// TODO Log error message here.
hr = E_FAIL;
}
return hr;
}
// static
INT
IN_PROCESS_APPLICATION::FilterException(unsigned int, struct _EXCEPTION_POINTERS*)
{
// We assume that any exception is a failure as the applicaiton didn't start or there was a startup error.
// TODO, log error based on exception code.
return EXCEPTION_EXECUTE_HANDLER;
}

Просмотреть файл

@ -4,37 +4,21 @@
#pragma once
typedef void(*request_handler_cb) (int error, IHttpContext* pHttpContext, void* pvCompletionContext);
typedef REQUEST_NOTIFICATION_STATUS(*PFN_REQUEST_HANDLER) (IHttpContext* pHttpContext, void* pvRequstHandlerContext);
typedef REQUEST_NOTIFICATION_STATUS(*PFN_REQUEST_HANDLER) (IN_PROCESS_HANDLER* pInProcessHandler, void* pvRequestHandlerContext);
typedef BOOL(*PFN_SHUTDOWN_HANDLER) (void* pvShutdownHandlerContext);
typedef REQUEST_NOTIFICATION_STATUS(*PFN_MANAGED_CONTEXT_HANDLER)(void *pvManagedHttpContext, HRESULT hrCompletionStatus, DWORD cbCompletion);
#include "application.h"
typedef DWORD(*hostfxr_main_fn) (CONST DWORD argc, CONST WCHAR* argv[]);
class IN_PROCESS_APPLICATION : public APPLICATION
{
public:
IN_PROCESS_APPLICATION();
IN_PROCESS_APPLICATION(IHttpServer* pHttpServer, ASPNETCORE_CONFIG *pConfig);
~IN_PROCESS_APPLICATION();
__override
HRESULT
Initialize(_In_ APPLICATION_MANAGER* pApplicationManager,
_In_ ASPNETCORE_CONFIG* pConfiguration);
VOID
Recycle(
VOID
);
__override
VOID OnAppOfflineHandleChange();
__override
REQUEST_NOTIFICATION_STATUS
ExecuteRequest(
_In_ IHttpContext* pHttpContext
);
ShutDown();
VOID
SetCallbackHandles(
@ -45,6 +29,11 @@ public:
_In_ VOID* pvShutdownHandlerContext
);
VOID
Recycle(
VOID
);
// Executes the .NET Core process
HRESULT
ExecuteApplication(
@ -53,14 +42,31 @@ public:
HRESULT
LoadManagedApplication(
VOID
);
VOID
);
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
IHttpContext* pHttpContext,
DWORD cbCompletion,
HRESULT hrCompletionStatus
HRESULT hrCompletionStatus,
IN_PROCESS_HANDLER* pInProcessHandler
);
REQUEST_NOTIFICATION_STATUS
OnExecuteRequest
(
IHttpContext* pHttpContext,
IN_PROCESS_HANDLER* pInProcessHandler
);
static
INT
FilterException(unsigned int code, struct _EXCEPTION_POINTERS *ep);
HRESULT
RunDotnetApplication(
PCWSTR* argv,
hostfxr_main_fn pProc
);
static
@ -72,14 +78,13 @@ public:
return s_Application;
}
private:
// Thread executing the .NET Core process
HANDLE m_hThread;
// The request handler callback from managed code
PFN_REQUEST_HANDLER m_RequestHandler;
VOID* m_RequstHandlerContext;
VOID* m_RequestHandlerContext;
// The shutdown handler callback from managed code
PFN_SHUTDOWN_HANDLER m_ShutdownHandler;
@ -90,6 +95,10 @@ private:
// The event that gets triggered when managed initialization is complete
HANDLE m_pInitalizeEvent;
// The std log file handle
HANDLE m_hLogFileHandle;
STRU m_struLogFilePath;
// The exit code of the .NET Core process
INT m_ProcessExitCode;
@ -97,9 +106,20 @@ private:
BOOL m_fLoadManagedAppError;
BOOL m_fInitialized;
BOOL m_fIsWebSocketsConnection;
BOOL m_fDoneStdRedirect;
BOOL m_fRecycleProcessCalled;
FILE* m_pStdFile;
STTIMER m_Timer;
SRWLOCK m_srwLock;
static IN_PROCESS_APPLICATION* s_Application;
VOID
SetStdOut(
VOID
);
static
VOID
FindDotNetFolders(
@ -117,7 +137,7 @@ private:
static
BOOL
DirectoryExists(
_In_ STRU *pstrPath //todo: this does not need to be stru, can be PCWSTR
_In_ STRU *pstrPath //todo: this does not need to be stru, can be PCWSTR
);
static BOOL
@ -131,5 +151,4 @@ private:
ExecuteAspNetCoreProcess(
_In_ LPVOID pContext
);
};

Просмотреть файл

@ -0,0 +1,146 @@
#include "..\precomp.hxx"
IN_PROCESS_HANDLER::IN_PROCESS_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication
): REQUEST_HANDLER(pW3Context, pModuleId, pApplication)
{
m_fManagedRequestComplete = FALSE;
}
IN_PROCESS_HANDLER::~IN_PROCESS_HANDLER()
{
//todo
}
__override
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_HANDLER::OnExecuteRequestHandler()
{
// First get the in process Application
HRESULT hr;
hr = ((IN_PROCESS_APPLICATION*)m_pApplication)->LoadManagedApplication();
if (FAILED(hr))
{
// TODO remove com_error?
/*_com_error err(hr);
if (ANCMEvents::ANCM_START_APPLICATION_FAIL::IsEnabled(m_pW3Context->GetTraceContext()))
{
ANCMEvents::ANCM_START_APPLICATION_FAIL::RaiseEvent(
m_pW3Context->GetTraceContext(),
NULL,
err.ErrorMessage());
}
*/
//fInternalError = TRUE;
m_pW3Context->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
}
// FREB log
if (ANCMEvents::ANCM_START_APPLICATION_SUCCESS::IsEnabled(m_pW3Context->GetTraceContext()))
{
ANCMEvents::ANCM_START_APPLICATION_SUCCESS::RaiseEvent(
m_pW3Context->GetTraceContext(),
NULL,
L"InProcess Application");
}
//SetHttpSysDisconnectCallback();
return ((IN_PROCESS_APPLICATION*)m_pApplication)->OnExecuteRequest(m_pW3Context, this);
}
__override
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_HANDLER::OnAsyncCompletion(
DWORD cbCompletion,
HRESULT hrCompletionStatus
)
{
HRESULT hr;
if (FAILED(hrCompletionStatus))
{
return RQ_NOTIFICATION_FINISH_REQUEST;
}
else
{
// For now we are assuming we are in our own self contained box.
// TODO refactor Finished and Failure sections to handle in process and out of process failure.
// TODO verify that websocket's OnAsyncCompletion is not calling this.
IN_PROCESS_APPLICATION* application = (IN_PROCESS_APPLICATION*)m_pApplication;
if (application == NULL)
{
hr = E_FAIL;
return RQ_NOTIFICATION_FINISH_REQUEST;
}
return application->OnAsyncCompletion(cbCompletion, hrCompletionStatus, this);
}
}
VOID
IN_PROCESS_HANDLER::TerminateRequest(
bool fClientInitiated
)
{
UNREFERENCED_PARAMETER(fClientInitiated);
//todo
}
PVOID
IN_PROCESS_HANDLER::QueryManagedHttpContext(
VOID
)
{
return m_pManagedHttpContext;
}
BOOL
IN_PROCESS_HANDLER::QueryIsManagedRequestComplete(
VOID
)
{
return m_fManagedRequestComplete;
}
IHttpContext*
IN_PROCESS_HANDLER::QueryHttpContext(
VOID
)
{
return m_pW3Context;
}
VOID
IN_PROCESS_HANDLER::IndicateManagedRequestComplete(
VOID
)
{
m_fManagedRequestComplete = TRUE;
}
REQUEST_NOTIFICATION_STATUS
IN_PROCESS_HANDLER::QueryAsyncCompletionStatus(
VOID
)
{
return m_requestNotificationStatus;
}
VOID
IN_PROCESS_HANDLER::SetAsyncCompletionStatus(
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
)
{
m_requestNotificationStatus = requestNotificationStatus;
}
VOID
IN_PROCESS_HANDLER::SetManangedHttpContext(
PVOID pManagedHttpContext
)
{
m_pManagedHttpContext = pManagedHttpContext;
}

Просмотреть файл

@ -0,0 +1,72 @@
#pragma once
class IN_PROCESS_HANDLER : public REQUEST_HANDLER
{
public:
IN_PROCESS_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication);
~IN_PROCESS_HANDLER();
__override
REQUEST_NOTIFICATION_STATUS
OnExecuteRequestHandler();
__override
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
DWORD cbCompletion,
HRESULT hrCompletionStatus
);
__override
VOID
TerminateRequest(
bool fClientInitiated
);
PVOID
QueryManagedHttpContext(
VOID
);
VOID
SetManangedHttpContext(
PVOID pManagedHttpContext
);
IHttpContext*
QueryHttpContext(
VOID
);
BOOL
QueryIsManagedRequestComplete(
VOID
);
VOID
IndicateManagedRequestComplete(
VOID
);
REQUEST_NOTIFICATION_STATUS
QueryAsyncCompletionStatus(
VOID
);
VOID
SetAsyncCompletionStatus(
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
);
private:
PVOID m_pManagedHttpContext;
IHttpContext* m_pHttpContext;
BOOL m_fManagedRequestComplete;
REQUEST_NOTIFICATION_STATUS m_requestNotificationStatus;
};

Просмотреть файл

@ -28,83 +28,64 @@ register_callbacks(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HTTP_REQUEST*
http_get_raw_request(
_In_ IHttpContext* pHttpContext
_In_ IN_PROCESS_HANDLER* pInProcessHandler
)
{
return pHttpContext->GetRequest()->GetRawHttpRequest();
return pInProcessHandler->QueryHttpContext()->GetRequest()->GetRawHttpRequest();
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HTTP_RESPONSE*
http_get_raw_response(
_In_ IHttpContext* pHttpContext
_In_ IN_PROCESS_HANDLER* pInProcessHandler
)
{
return pHttpContext->GetResponse()->GetRawHttpResponse();
return pInProcessHandler->QueryHttpContext()->GetResponse()->GetRawHttpResponse();
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT VOID http_set_response_status_code(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ USHORT statusCode,
_In_ PCSTR pszReason
)
{
pHttpContext->GetResponse()->SetStatus(statusCode, pszReason);
pInProcessHandler->QueryHttpContext()->GetResponse()->SetStatus(statusCode, pszReason);
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_post_completion(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
DWORD cbBytes
)
{
return pHttpContext->PostCompletion(cbBytes);
return pInProcessHandler->QueryHttpContext()->PostCompletion(cbBytes);
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_set_completion_status(
_In_ IHttpContext* pHttpContext,
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ REQUEST_NOTIFICATION_STATUS requestNotificationStatus
)
{
HRESULT hr = S_OK;
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext = NULL;
hr = IN_PROCESS_STORED_CONTEXT::GetInProcessStoredContext(
pHttpContext,
&pInProcessStoredContext
);
if (FAILED(hr))
{
return hr;
}
pInProcessStoredContext->IndicateManagedRequestComplete();
pInProcessStoredContext->SetAsyncCompletionStatus(requestNotificationStatus);
pInProcessHandler->IndicateManagedRequestComplete();
pInProcessHandler->SetAsyncCompletionStatus(requestNotificationStatus);
return hr;
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_set_managed_context(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ PVOID pvManagedContext
)
{
HRESULT hr;
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext = new IN_PROCESS_STORED_CONTEXT(pHttpContext, pvManagedContext);
if (pInProcessStoredContext == NULL)
{
return E_OUTOFMEMORY;
}
hr = IN_PROCESS_STORED_CONTEXT::SetInProcessStoredContext(pHttpContext, pInProcessStoredContext);
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
{
hr = S_OK;
}
// todo: should we consider changing the signature
HRESULT hr = S_OK;
pInProcessHandler->SetManangedHttpContext(pvManagedContext);
return hr;
}
@ -112,11 +93,11 @@ http_set_managed_context(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
VOID
http_indicate_completion(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ REQUEST_NOTIFICATION_STATUS notificationStatus
)
{
pHttpContext->IndicateCompletion(notificationStatus);
pInProcessHandler->QueryHttpContext()->IndicateCompletion(notificationStatus);
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
@ -153,7 +134,7 @@ http_get_application_properties(
{
ASPNETCORE_CONFIG* pConfiguration = NULL;
IN_PROCESS_APPLICATION* pApplication = IN_PROCESS_APPLICATION::GetInstance();
if (pApplication == NULL)
{
return E_FAIL;
@ -161,7 +142,7 @@ http_get_application_properties(
pConfiguration = pApplication->QueryConfig();
pIISCofigurationData->pwzFullApplicationPath = SysAllocString(pConfiguration->QueryApplicationFullPath()->QueryStr());
pIISCofigurationData->pwzFullApplicationPath = SysAllocString(pConfiguration->QueryApplicationPhysicalPath()->QueryStr());
pIISCofigurationData->pwzVirtualApplicationPath = SysAllocString(pConfiguration->QueryApplicationVirtualPath()->QueryStr());
pIISCofigurationData->fWindowsAuthEnabled = pConfiguration->QueryWindowsAuthEnabled();
pIISCofigurationData->fBasicAuthEnabled = pConfiguration->QueryBasicAuthEnabled();
@ -173,7 +154,7 @@ http_get_application_properties(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_read_request_bytes(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_Out_ CHAR* pvBuffer,
_In_ DWORD dwCbBuffer,
_Out_ DWORD* pdwBytesReceived,
@ -182,7 +163,7 @@ http_read_request_bytes(
{
HRESULT hr;
if (pHttpContext == NULL)
if (pInProcessHandler == NULL)
{
return E_FAIL;
}
@ -190,7 +171,7 @@ http_read_request_bytes(
{
return E_FAIL;
}
IHttpRequest *pHttpRequest = (IHttpRequest*)pHttpContext->GetRequest();
IHttpRequest *pHttpRequest = (IHttpRequest*)pInProcessHandler->QueryHttpContext()->GetRequest();
BOOL fAsync = TRUE;
@ -213,13 +194,13 @@ http_read_request_bytes(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_write_response_bytes(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ HTTP_DATA_CHUNK* pDataChunks,
_In_ DWORD dwChunks,
_In_ BOOL* pfCompletionExpected
)
{
IHttpResponse *pHttpResponse = (IHttpResponse*)pHttpContext->GetResponse();
IHttpResponse *pHttpResponse = (IHttpResponse*)pInProcessHandler->QueryHttpContext()->GetResponse();
BOOL fAsync = TRUE;
BOOL fMoreData = TRUE;
DWORD dwBytesSent = 0;
@ -238,11 +219,11 @@ http_write_response_bytes(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_flush_response_bytes(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_Out_ BOOL* pfCompletionExpected
)
{
IHttpResponse *pHttpResponse = (IHttpResponse*)pHttpContext->GetResponse();
IHttpResponse *pHttpResponse = (IHttpResponse*)pInProcessHandler->QueryHttpContext()->GetResponse();
BOOL fAsync = TRUE;
BOOL fMoreData = TRUE;
@ -259,7 +240,7 @@ http_flush_response_bytes(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_websockets_read_bytes(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ CHAR* pvBuffer,
_In_ DWORD cbBuffer,
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
@ -268,7 +249,7 @@ http_websockets_read_bytes(
_In_ BOOL* pfCompletionPending
)
{
IHttpRequest3 *pHttpRequest = (IHttpRequest3*)pHttpContext->GetRequest();
IHttpRequest3 *pHttpRequest = (IHttpRequest3*)pInProcessHandler->QueryHttpContext()->GetRequest();
BOOL fAsync = TRUE;
@ -293,7 +274,7 @@ http_websockets_read_bytes(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_websockets_write_bytes(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ HTTP_DATA_CHUNK* pDataChunks,
_In_ DWORD dwChunks,
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
@ -301,7 +282,7 @@ http_websockets_write_bytes(
_In_ BOOL* pfCompletionExpected
)
{
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pHttpContext->GetResponse();
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse();
BOOL fAsync = TRUE;
BOOL fMoreData = TRUE;
@ -323,13 +304,13 @@ http_websockets_write_bytes(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_websockets_flush_bytes(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
_In_ VOID* pvCompletionContext,
_In_ BOOL* pfCompletionExpected
)
{
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pHttpContext->GetResponse();
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse();
BOOL fAsync = TRUE;
BOOL fMoreData = TRUE;
@ -348,16 +329,16 @@ http_websockets_flush_bytes(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_enable_websockets(
_In_ IHttpContext* pHttpContext
_In_ IN_PROCESS_HANDLER* pInProcessHandler
)
{
if (!g_fWebSocketSupported)
{
return E_FAIL;
}
//if (!g_fWebSocketSupported)
//{
// return E_FAIL;
//}
((IHttpContext3*)pHttpContext)->EnableFullDuplex();
((IHttpResponse2*)pHttpContext->GetResponse())->DisableBuffering();
((IHttpContext3*)pInProcessHandler->QueryHttpContext())->EnableFullDuplex();
((IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse())->DisableBuffering();
return S_OK;
}
@ -365,51 +346,50 @@ http_enable_websockets(
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_cancel_io(
_In_ IHttpContext* pHttpContext
_In_ IN_PROCESS_HANDLER* pInProcessHandler
)
{
return pHttpContext->CancelIo();
return pInProcessHandler->QueryHttpContext()->CancelIo();
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_response_set_unknown_header(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ PCSTR pszHeaderName,
_In_ PCSTR pszHeaderValue,
_In_ USHORT usHeaderValueLength,
_In_ BOOL fReplace
)
{
return pHttpContext->GetResponse()->SetHeader( pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace );
return pInProcessHandler->QueryHttpContext()->GetResponse()->SetHeader(pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace);
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_response_set_known_header(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_In_ HTTP_HEADER_ID dwHeaderId,
_In_ PCSTR pszHeaderValue,
_In_ USHORT usHeaderValueLength,
_In_ BOOL fReplace
)
{
return pHttpContext->GetResponse()->SetHeader( dwHeaderId, pszHeaderValue, usHeaderValueLength, fReplace );
return pInProcessHandler->QueryHttpContext()->GetResponse()->SetHeader(dwHeaderId, pszHeaderValue, usHeaderValueLength, fReplace);
}
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
HRESULT
http_get_authentication_information(
_In_ IHttpContext* pHttpContext,
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
_Out_ BSTR* pstrAuthType,
_Out_ VOID** pvToken
)
{
*pstrAuthType = SysAllocString(pHttpContext->GetUser()->GetAuthenticationType());
*pvToken = pHttpContext->GetUser()->GetPrimaryToken();
*pstrAuthType = SysAllocString(pInProcessHandler->QueryHttpContext()->GetUser()->GetAuthenticationType());
*pvToken = pInProcessHandler->QueryHttpContext()->GetUser()->GetPrimaryToken();
return S_OK;
}
// End of export

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
#include "..\precomp.hxx"
FORWARDER_CONNECTION::FORWARDER_CONNECTION(
VOID
@ -23,7 +23,7 @@ FORWARDER_CONNECTION::Initialize(
goto Finished;
}
m_hConnection = WinHttpConnect(FORWARDING_HANDLER::sm_hSession,
m_hConnection = WinHttpConnect(g_hWinhttpSession,
L"127.0.0.1",
(USHORT) dwPort,
0);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,199 @@
#pragma once
extern DWORD g_OptionalWinHttpFlags;
enum FORWARDING_REQUEST_STATUS
{
FORWARDER_START,
FORWARDER_SENDING_REQUEST,
FORWARDER_RECEIVING_RESPONSE,
FORWARDER_RECEIVED_WEBSOCKET_RESPONSE,
FORWARDER_DONE,
FORWARDER_FINISH_REQUEST
};
class FORWARDING_HANDLER : public REQUEST_HANDLER
{
public:
FORWARDING_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication);
~FORWARDING_HANDLER();
__override
REQUEST_NOTIFICATION_STATUS
OnExecuteRequestHandler();
__override
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
DWORD cbCompletion,
HRESULT hrCompletionStatus
);
VOID
SetStatus(
FORWARDING_REQUEST_STATUS status
)
{
m_RequestStatus = status;
}
static
VOID
CALLBACK
FORWARDING_HANDLER::OnWinHttpCompletion(
HINTERNET hRequest,
DWORD_PTR dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength
);
static
HRESULT
StaticInitialize(
BOOL fEnableReferenceCountTracing
);
static
VOID
StaticTerminate();
VOID
TerminateRequest(
bool fClientInitiated
);
private:
HRESULT
CreateWinHttpRequest(
_In_ const IHttpRequest * pRequest,
_In_ const PROTOCOL_CONFIG * pProtocol,
_In_ HINTERNET hConnect,
_Inout_ STRU * pstrUrl,
// _In_ ASPNETCORE_CONFIG* pAspNetCoreConfig,
_In_ SERVER_PROCESS* pServerProcess
);
VOID
FORWARDING_HANDLER::OnWinHttpCompletionInternal(
_In_ HINTERNET hRequest,
_In_ DWORD dwInternetStatus,
_In_ LPVOID lpvStatusInformation,
_In_ DWORD dwStatusInformationLength
);
HRESULT
OnWinHttpCompletionSendRequestOrWriteComplete(
HINTERNET hRequest,
DWORD dwInternetStatus,
_Out_ bool * pfClientError,
_Out_ bool * pfAnotherCompletionExpected
);
HRESULT
OnWinHttpCompletionStatusHeadersAvailable(
HINTERNET hRequest,
_Out_ bool * pfAnotherCompletionExpected
);
HRESULT
OnWinHttpCompletionStatusDataAvailable(
HINTERNET hRequest,
DWORD dwBytes,
_Out_ bool * pfAnotherCompletionExpected
);
HRESULT
OnWinHttpCompletionStatusReadComplete(
_In_ IHttpResponse * pResponse,
DWORD dwStatusInformationLength,
_Out_ bool * pfAnotherCompletionExpected
);
HRESULT
OnSendingRequest(
DWORD cbCompletion,
HRESULT hrCompletionStatus,
_Out_ bool * pfClientError
);
HRESULT
OnReceivingResponse();
BYTE *
GetNewResponseBuffer(
DWORD dwBufferSize
);
VOID
FreeResponseBuffers();
HRESULT
SetStatusAndHeaders(
PCSTR pszHeaders,
DWORD cchHeaders
);
HRESULT
DoReverseRewrite(
_In_ IHttpResponse *pResponse
);
HRESULT
GetHeaders(
_In_ const PROTOCOL_CONFIG * pProtocol,
_In_ bool fForwardWindowsAuthToken,
_In_ SERVER_PROCESS* pServerProcess,
_Out_ PCWSTR * ppszHeaders,
_Inout_ DWORD * pcchHeaders
);
DWORD m_Signature;
//
// WinHTTP request handle is protected using a read-write lock.
//
SRWLOCK m_RequestLock;
HINTERNET m_hRequest;
FORWARDING_REQUEST_STATUS m_RequestStatus;
bool m_fWebSocketEnabled;
bool m_fResponseHeadersReceivedAndSet;
bool m_fResetConnection;
bool m_fHandleClosedDueToClient;
bool m_fFinishRequest;
bool m_fHasError;
BOOL m_fDoReverseRewriteHeaders;
PCSTR m_pszOriginalHostHeader;
PCWSTR m_pszHeaders;
DWORD m_cchHeaders;
DWORD m_BytesToReceive;
DWORD m_BytesToSend;
DWORD m_cchLastSend;
DWORD m_cEntityBuffers;
DWORD m_cBytesBuffered;
DWORD m_cMinBufferLimit;
ULONGLONG m_cContentLength;
WEBSOCKET_HANDLER * m_pWebSocket;
ASYNC_DISCONNECT_CONTEXT * m_pDisconnect;
BYTE * m_pEntityBuffer;
static const SIZE_T INLINE_ENTITY_BUFFERS = 8;
BUFFER_T<BYTE*, INLINE_ENTITY_BUFFERS> m_buffEntityBuffers;
static ALLOC_CACHE_HANDLER * sm_pAlloc;
static PROTOCOL_CONFIG sm_ProtocolConfig;
static RESPONSE_HEADER_HASH * sm_pResponseHeaderHash;
//
// Reference cout tracing for debugging purposes.
//
static TRACE_LOG * sm_pTraceLog;
static STRA sm_pStra502ErrorMsg;
};

Просмотреть файл

@ -0,0 +1,66 @@
#include "..\precomp.hxx"
OUT_OF_PROCESS_APPLICATION::OUT_OF_PROCESS_APPLICATION(
IHttpServer* pHttpServer,
ASPNETCORE_CONFIG* pConfig) :
APPLICATION(pHttpServer, pConfig)
{
m_status = APPLICATION_STATUS::RUNNING;
m_pProcessManager = NULL;
//todo
}
OUT_OF_PROCESS_APPLICATION::~OUT_OF_PROCESS_APPLICATION()
{
if (m_pProcessManager != NULL)
{
m_pProcessManager->ShutdownAllProcesses();
m_pProcessManager->DereferenceProcessManager();
m_pProcessManager = NULL;
}
}
HRESULT
OUT_OF_PROCESS_APPLICATION::Initialize(
)
{
HRESULT hr = S_OK;
if (m_pProcessManager == NULL)
{
m_pProcessManager = new PROCESS_MANAGER;
if (m_pProcessManager == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = m_pProcessManager->Initialize();
if (FAILED(hr))
{
goto Finished;
}
}
Finished:
return hr;
}
HRESULT
OUT_OF_PROCESS_APPLICATION::GetProcess(
_Out_ SERVER_PROCESS **ppServerProcess
)
{
return m_pProcessManager->GetProcess(m_pConfig, ppServerProcess);
}
__override
VOID
OUT_OF_PROCESS_APPLICATION::ShutDown()
{
if (m_pProcessManager != NULL)
{
m_pProcessManager->ShutdownAllProcesses();
m_pProcessManager->DereferenceProcessManager();
m_pProcessManager = NULL;
}
}

Просмотреть файл

@ -0,0 +1,25 @@
#pragma once
class OUT_OF_PROCESS_APPLICATION : public APPLICATION
{
public:
OUT_OF_PROCESS_APPLICATION(IHttpServer* pHttpServer, ASPNETCORE_CONFIG *pConfig);
~OUT_OF_PROCESS_APPLICATION();
HRESULT
Initialize();
HRESULT
GetProcess(
_Out_ SERVER_PROCESS **ppServerProcess
);
__override
VOID
ShutDown();
private:
PROCESS_MANAGER * m_pProcessManager;
};

Просмотреть файл

@ -0,0 +1,296 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "..\precomp.hxx"
volatile BOOL PROCESS_MANAGER::sm_fWSAStartupDone = FALSE;
HRESULT
PROCESS_MANAGER::Initialize(
VOID
)
{
HRESULT hr = S_OK;
WSADATA wsaData;
int result;
BOOL fLocked = FALSE;
if( !sm_fWSAStartupDone )
{
AcquireSRWLockExclusive( &m_srwLock );
fLocked = TRUE;
if( !sm_fWSAStartupDone )
{
if( (result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0 )
{
hr = HRESULT_FROM_WIN32( result );
goto Finished;
}
sm_fWSAStartupDone = TRUE;
}
ReleaseSRWLockExclusive( &m_srwLock );
fLocked = FALSE;
}
m_dwRapidFailTickStart = GetTickCount();
if( m_hNULHandle == NULL )
{
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
m_hNULHandle = CreateFileW( L"NUL",
FILE_WRITE_DATA,
FILE_SHARE_READ,
&saAttr,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( m_hNULHandle == INVALID_HANDLE_VALUE )
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
}
Finished:
if(fLocked)
{
ReleaseSRWLockExclusive( &m_srwLock );
}
return hr;
}
PROCESS_MANAGER::~PROCESS_MANAGER()
{
AcquireSRWLockExclusive(&m_srwLock);
//if( m_ppServerProcessList != NULL )
//{
// for( DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
// {
// if( m_ppServerProcessList[i] != NULL )
// {
// m_ppServerProcessList[i]->DereferenceServerProcess();
// m_ppServerProcessList[i] = NULL;
// }
// }
// delete[] m_ppServerProcessList;
// m_ppServerProcessList = NULL;
//}
//if( m_hNULHandle != NULL )
//{
// CloseHandle( m_hNULHandle );
// m_hNULHandle = NULL;
//}
//if( sm_fWSAStartupDone )
//{
// WSACleanup();
// sm_fWSAStartupDone = FALSE;
//}
ReleaseSRWLockExclusive(&m_srwLock);
}
HRESULT
PROCESS_MANAGER::GetProcess(
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ SERVER_PROCESS **ppServerProcess
)
{
HRESULT hr = S_OK;
BOOL fSharedLock = FALSE;
BOOL fExclusiveLock = FALSE;
//PCWSTR apsz[1];
STACK_STRU(strEventMsg, 256);
DWORD dwProcessIndex = 0;
SERVER_PROCESS *pSelectedServerProcess = NULL;
if (!m_fServerProcessListReady)
{
AcquireSRWLockExclusive(&m_srwLock);
fExclusiveLock = TRUE;
if (!m_fServerProcessListReady)
{
m_dwProcessesPerApplication = pConfig->QueryProcessesPerApplication();
m_ppServerProcessList = new SERVER_PROCESS*[m_dwProcessesPerApplication];
if (m_ppServerProcessList == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
for (DWORD i = 0; i < m_dwProcessesPerApplication; ++i)
{
m_ppServerProcessList[i] = NULL;
}
}
m_fServerProcessListReady = TRUE;
ReleaseSRWLockExclusive(&m_srwLock);
fExclusiveLock = FALSE;
}
AcquireSRWLockShared(&m_srwLock);
fSharedLock = TRUE;
//
// round robin through to the next available process.
//
dwProcessIndex = (DWORD)InterlockedIncrement64((LONGLONG*)&m_dwRouteToProcessIndex);
dwProcessIndex = dwProcessIndex % m_dwProcessesPerApplication;
if (m_ppServerProcessList[dwProcessIndex] != NULL &&
m_ppServerProcessList[dwProcessIndex]->IsReady())
{
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
goto Finished;
}
ReleaseSRWLockShared(&m_srwLock);
fSharedLock = FALSE;
// should make the lock per process so that we can start processes simultaneously ?
if (m_ppServerProcessList[dwProcessIndex] == NULL ||
!m_ppServerProcessList[dwProcessIndex]->IsReady())
{
AcquireSRWLockExclusive(&m_srwLock);
fExclusiveLock = TRUE;
if (m_ppServerProcessList[dwProcessIndex] != NULL)
{
if (!m_ppServerProcessList[dwProcessIndex]->IsReady())
{
//
// terminate existing process that is not ready
// before creating new one.
//
//todo:
//ShutdownProcessNoLock( m_ppServerProcessList[dwProcessIndex] );
}
else
{
// server is already up and ready to serve requests.
//m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
goto Finished;
}
}
if (RapidFailsPerMinuteExceeded(pConfig->QueryRapidFailsPerMinute()))
{
//
// rapid fails per minute exceeded, do not create new process.
//
//if( SUCCEEDED( strEventMsg.SafeSnwprintf(
// ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG,
// pConfig->QueryRapidFailsPerMinute() ) ) )
//{
// apsz[0] = strEventMsg.QueryStr();
// //
// // not checking return code because if ReportEvent
// // fails, we cannot do anything.
// //
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
// {
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
// EVENTLOG_INFORMATION_TYPE,
// 0,
// ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED,
// NULL,
// 1,
// 0,
// apsz,
// NULL);
// }
//}
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
goto Finished;
}
if (m_ppServerProcessList[dwProcessIndex] == NULL)
{
pSelectedServerProcess = new SERVER_PROCESS();
if (pSelectedServerProcess == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pSelectedServerProcess->Initialize(
this, //ProcessManager
pConfig->QueryProcessPath(), //
pConfig->QueryArguments(), //
pConfig->QueryStartupTimeLimitInMS(),
pConfig->QueryShutdownTimeLimitInMS(),
pConfig->QueryWindowsAuthEnabled(),
pConfig->QueryBasicAuthEnabled(),
pConfig->QueryAnonymousAuthEnabled(),
pConfig->QueryEnvironmentVariables(),
pConfig->QueryStdoutLogEnabled(),
pConfig->QueryStdoutLogFile(),
pConfig->QueryApplicationPhysicalPath(), // physical path
pConfig->QueryApplicationPath(), // app path
pConfig->QueryApplicationVirtualPath() // App relative virtual path
);
if (FAILED(hr))
{
goto Finished;
}
hr = pSelectedServerProcess->StartProcess();
if (FAILED(hr))
{
goto Finished;
}
}
if (!pSelectedServerProcess->IsReady())
{
hr = HRESULT_FROM_WIN32(ERROR_CREATE_FAILED);
goto Finished;
}
m_ppServerProcessList[dwProcessIndex] = pSelectedServerProcess;
pSelectedServerProcess = NULL;
}
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
Finished:
if (fSharedLock)
{
ReleaseSRWLockShared(&m_srwLock);
fSharedLock = FALSE;
}
if (fExclusiveLock)
{
ReleaseSRWLockExclusive(&m_srwLock);
fExclusiveLock = FALSE;
}
if (pSelectedServerProcess != NULL)
{
delete pSelectedServerProcess;
pSelectedServerProcess = NULL;
}
return hr;
}

Просмотреть файл

@ -4,6 +4,7 @@
#pragma once
#define ONE_MINUTE_IN_MILLISECONDS 60000
class SERVER_PROCESS;
class PROCESS_MANAGER
{
@ -29,7 +30,6 @@ public:
HRESULT
GetProcess(
_In_ IHttpContext *context,
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ SERVER_PROCESS **ppServerProcess
);
@ -104,6 +104,8 @@ public:
m_fServerProcessListReady(FALSE),
m_cRefs( 1 )
{
m_ppServerProcessList = NULL;
m_fServerProcessListReady = FALSE;
InitializeSRWLock( &m_srwLock );
}

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
#include "..\precomp.hxx"
HRESULT
PROTOCOL_CONFIG::Initialize()

Просмотреть файл

@ -3,8 +3,6 @@
#pragma once
#include "aspnetcoreconfig.h"
class PROTOCOL_CONFIG
{
public:

Просмотреть файл

@ -1,9 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
RESPONSE_HEADER_HASH * g_pResponseHeaderHash = NULL;
#include "..\precomp.hxx"
HEADER_RECORD RESPONSE_HEADER_HASH::sm_rgHeaders[] =
{

Просмотреть файл

@ -106,5 +106,3 @@ private:
RESPONSE_HEADER_HASH(const RESPONSE_HEADER_HASH &);
void operator=(const RESPONSE_HEADER_HASH &);
};
extern RESPONSE_HEADER_HASH * g_pResponseHeaderHash;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -23,7 +23,6 @@
#define ASPNETCORE_IIS_AUTH_NONE L"none"
class PROCESS_MANAGER;
class FORWARDER_CONNECTION;
class SERVER_PROCESS
{
@ -42,14 +41,14 @@ public:
_In_ BOOL fAnonymousAuthEnabled,
_In_ ENVIRONMENT_VAR_HASH* pEnvironmentVariables,
_In_ BOOL fStdoutLogEnabled,
_In_ STRU *pstruStdoutLogFile
_In_ STRU *pstruStdoutLogFile,
_In_ STRU *pszAppPhysicalPath,
_In_ STRU *pszAppPath,
_In_ STRU *pszAppVirtualPath
);
HRESULT
StartProcess(
_In_ IHttpContext *context
);
StartProcess( VOID );
HRESULT
SetWindowsAuthToken(
@ -70,7 +69,7 @@ public:
VOID
);
DWORD
DWORD
GetPort()
{
return m_dwPort;
@ -90,7 +89,6 @@ public:
)
{
_ASSERT(m_cRefs != 0 );
if (InterlockedDecrement(&m_cRefs) == 0)
{
delete this;
@ -100,7 +98,15 @@ public:
virtual
~SERVER_PROCESS();
HRESULT
static
VOID
CALLBACK
ProcessHandleCallback(
_In_ PVOID pContext,
_In_ BOOL
);
HRESULT
HandleProcessExit(
VOID
);
@ -113,38 +119,11 @@ public:
return m_pForwarderConnection;
}
static
VOID
CALLBACK
TimerCallback(
_In_ PTP_CALLBACK_INSTANCE Instance,
_In_ PVOID Context,
_In_ PTP_TIMER Timer
);
LPCWSTR
QueryPortStr()
{
return m_struPort.QueryStr();
}
LPCWSTR
QueryFullLogPath()
{
return m_struFullLogFile.QueryStr();
}
LPCSTR
QueryGuid()
{
return m_straGuid.QueryStr();
}
DWORD
QueryProcessGroupId()
{
return m_dwProcessId;
}
};
VOID
SendSignal(
@ -165,8 +144,7 @@ private:
HRESULT
SetupStdHandles(
_In_ IHttpContext *context,
_In_ LPSTARTUPINFOW pStartupInfo
_Inout_ LPSTARTUPINFOW pStartupInfo
);
HRESULT
@ -184,6 +162,7 @@ private:
HRESULT
GetChildProcessHandles(
VOID
);
HRESULT
@ -193,7 +172,6 @@ private:
HRESULT
SetupAppPath(
IHttpContext* pContext,
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
);
@ -220,8 +198,7 @@ private:
HRESULT
PostStartCheck(
const STRU* const pStruCommandline,
STRU* pStruErrorMessage
VOID
);
HRESULT
@ -230,28 +207,6 @@ private:
DWORD dwExcludedPort
);
DWORD
GetNumberOfDigits(
_In_ DWORD dwNumber
)
{
DWORD digits = 0;
if( dwNumber == 0 )
{
digits = 1;
goto Finished;
}
while( dwNumber > 0)
{
dwNumber = dwNumber / 10;
digits ++;
}
Finished:
return digits;
}
static
VOID
SendShutDownSignal(
@ -286,10 +241,12 @@ private:
STRU m_struFullLogFile;
STRU m_ProcessPath;
STRU m_Arguments;
STRU m_struAppPath;
STRU m_struAppFullPath;
STRU m_struAppVirtualPath; // e.g., '/' for site
STRU m_struAppFullPath; // e.g., /LM/W3SVC/4/ROOT/Inproc
STRU m_struPhysicalPath; // e.g., c:/test/mysite
STRU m_struPort;
STRU m_pszRootApplicationPath;
STRU m_struCommandLine;
volatile LONG m_lStopping;
volatile BOOL m_fReady;
mutable LONG m_cRefs;

Просмотреть файл

@ -27,7 +27,7 @@ This prevents the need for data buffering at the Asp.Net Core Module level.
--*/
#include "precomp.hxx"
#include "..\precomp.hxx"
SRWLOCK WEBSOCKET_HANDLER::sm_RequestsListLock;
@ -48,7 +48,6 @@ WEBSOCKET_HANDLER::WEBSOCKET_HANDLER() :
DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO, "WEBSOCKET_HANDLER::WEBSOCKET_HANDLER");
InitializeCriticalSectionAndSpinCount(&_RequestLock, 1000);
InsertRequest();
}
@ -103,7 +102,6 @@ WEBSOCKET_HANDLER::StaticInitialize(
// If tracing is enabled, keep track of all websocket requests
// for debugging purposes.
//
InitializeListHead (&sm_RequestsListHead);
sm_pTraceLog = CreateRefTraceLog( 10000, 0 );
}
@ -137,9 +135,7 @@ WEBSOCKET_HANDLER::InsertRequest(
if (g_fEnableReferenceCountTracing)
{
AcquireSRWLockExclusive(&sm_RequestsListLock);
InsertTailList(&sm_RequestsListHead, &_listEntry);
ReleaseSRWLockExclusive( &sm_RequestsListLock);
}
}
@ -153,9 +149,7 @@ WEBSOCKET_HANDLER::RemoveRequest(
if (g_fEnableReferenceCountTracing)
{
AcquireSRWLockExclusive(&sm_RequestsListLock);
RemoveEntryList(&_listEntry);
ReleaseSRWLockExclusive( &sm_RequestsListLock);
}
}
@ -166,7 +160,6 @@ WEBSOCKET_HANDLER::IncrementOutstandingIo(
)
{
InterlockedIncrement(&_dwOutstandingIo);
if (sm_pTraceLog)
{
WriteRefTraceLog(sm_pTraceLog, _dwOutstandingIo, this);
@ -213,8 +206,8 @@ WEBSOCKET_HANDLER::IndicateCompletionToIIS(
--*/
{
DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::IndicateCompletionToIIS");
/*DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::IndicateCompletionToIIS");*/
_pHandler->SetStatus(FORWARDER_DONE);
@ -254,14 +247,12 @@ Routine Description:
_pHandler = pHandler;
EnterCriticalSection(&_RequestLock);
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::ProcessRequest");
//
// Cache the points to IHttpContext3
//
hr = HttpGetExtendedInterface(g_pHttpServer,
pHttpContext,
&_pHttpContext);
@ -285,7 +276,6 @@ Routine Description:
//
// Get Handle to Winhttp's websocket context.
//
_hWebSocketRequest = WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade(
hRequest,
(DWORD_PTR) pHandler);
@ -331,7 +321,6 @@ Routine Description:
//
// Initiate Read on IIS
//
hr = DoIisWebSocketReceive();
if (FAILED(hr))
{
@ -374,7 +363,6 @@ Routine Description:
--*/
{
HRESULT hr = S_OK;
DWORD dwBufferSize = RECEIVE_BUFFER_SIZE;
BOOL fUtf8Encoded;
BOOL fFinalFragment;
@ -398,10 +386,8 @@ Routine Description:
if (FAILED(hr))
{
DecrementOutstandingIo();
DebugPrintf(ASPNETCORE_DEBUG_FLAG_ERROR,
"WEBSOCKET_HANDLER::DoIisWebSocketSend failed with %08x", hr);
}
return hr;
@ -438,12 +424,9 @@ Routine Description:
if (dwError != NO_ERROR)
{
DecrementOutstandingIo();
hr = HRESULT_FROM_WIN32(dwError);
DebugPrintf(ASPNETCORE_DEBUG_FLAG_ERROR,
"WEBSOCKET_HANDLER::DoWinHttpWebSocketReceive failed with %08x", hr);
}
return hr;
@ -463,7 +446,6 @@ Routine Description:
--*/
{
HRESULT hr = S_OK;
BOOL fUtf8Encoded = FALSE;
BOOL fFinalFragment = FALSE;
BOOL fClose = FALSE;
@ -498,7 +480,6 @@ Routine Description:
//
// Convert close reason to WCHAR
//
hr = strCloseReason.CopyA((PCSTR)&_WinHttpReceiveBuffer,
dwReceived);
if (FAILED(hr))
@ -517,7 +498,6 @@ Routine Description:
//
// Send close to IIS.
//
hr = _pWebSocketContext->SendConnectionClose(
TRUE,
uStatus,
@ -542,7 +522,6 @@ Routine Description:
//
// Do the Send.
//
hr = _pWebSocketContext->WriteFragment(
&_WinHttpReceiveBuffer,
&cbData,
@ -552,7 +531,6 @@ Routine Description:
OnWriteIoCompletion,
this,
NULL);
}
if (FAILED(hr))
@ -598,7 +576,6 @@ Routine Description:
//
// Get Close status from IIS.
//
hr = _pWebSocketContext->GetCloseStatus(&uStatus,
&pszReason);
@ -610,7 +587,6 @@ Routine Description:
//
// Convert status to UTF8
//
hr = strCloseReason.CopyWToUTF8Unescaped(pszReason);
if (FAILED(hr))
{
@ -622,7 +598,6 @@ Routine Description:
//
// Send Close.
//
dwError = WINHTTP_HELPER::sm_pfnWinHttpWebSocketShutdown(
_hWebSocketRequest,
uStatus,
@ -635,7 +610,6 @@ Routine Description:
// Call will complete asynchronously, return.
// ignore error.
//
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::DoWinhttpWebSocketSend IO_PENDING");
@ -648,7 +622,6 @@ Routine Description:
//
// Call completed synchronously.
//
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::DoWinhttpWebSocketSend Shutdown successful.");
}
@ -810,7 +783,6 @@ Finished:
// The handler object can be gone after this call.
// do not reference it after this statement.
//
DecrementOutstandingIo();
return hr;
@ -841,7 +813,6 @@ WEBSOCKET_HANDLER::OnWinHttpIoError(
hr, pCompletionStatus->AsyncResult.dwResult);
Cleanup(ServerDisconnect);
DecrementOutstandingIo();
return hr;

Просмотреть файл

@ -3,6 +3,7 @@
#pragma once
extern IHttpServer * g_pHttpServer;
class FORWARDING_HANDLER;
class WEBSOCKET_HANDLER

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
#include "..\precomp.hxx"
PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE
WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade;

Просмотреть файл

@ -0,0 +1,119 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#pragma warning( disable : 4091)
//
// System related headers
//
#define _WINSOCKAPI_
#define NTDDI_VERSION 0x06010000
#define WINVER 0x0601
#define _WIN32_WINNT 0x0601
#include <windows.h>
#include <atlbase.h>
#include <pdh.h>
#include <vector>
#include <Shlobj.h>
#include <httpserv.h>
#include <winhttp.h>
#include <httptrace.h>
#include <cstdlib>
#include <reftrace.h>
#include <wchar.h>
#include <io.h>
#include <stdio.h>
// This should remove our issue of compiling for win7 without header files.
// We force the Windows 8 version check logic in iiswebsocket.h to succeed even though we're compiling for Windows 7.
// Then, we set the version defines back to Windows 7 to for the remainder of the compilation.
#undef NTDDI_VERSION
#undef WINVER
#undef _WIN32_WINNT
#define NTDDI_VERSION 0x06020000
#define WINVER 0x0602
#define _WIN32_WINNT 0x0602
#include <iiswebsocket.h>
#undef NTDDI_VERSION
#undef WINVER
#undef _WIN32_WINNT
#define NTDDI_VERSION 0x06010000
#define WINVER 0x0601
#define _WIN32_WINNT 0x0601
#include "..\IISLib\acache.h"
#include "..\IISLib\multisz.h"
#include "..\IISLib\multisza.h"
#include "..\IISLib\base64.h"
#include "..\IISLib\listentry.h"
#include "..\CommonLib\fx_ver.h"
#include "..\CommonLib\debugutil.h"
#include "..\CommonLib\requesthandler.h"
#include "..\CommonLib\aspnetcoreconfig.h"
#include "..\CommonLib\utility.h"
#include "..\CommonLib\application.h"
#include "aspnetcore_event.h"
#include "aspnetcore_msg.h"
#include "disconnectcontext.h"
#include "sttimer.h"
#include "resource.h"
#include ".\inprocess\InProcessHandler.h"
#include ".\inprocess\inprocessapplication.h"
#include ".\outofprocess\responseheaderhash.h"
#include ".\outofprocess\protocolconfig.h"
#include ".\outofprocess\forwarderconnection.h"
#include ".\outofprocess\serverprocess.h"
#include ".\outofprocess\processmanager.h"
#include ".\outofprocess\websockethandler.h"
#include ".\outofprocess\forwardinghandler.h"
#include ".\outofprocess\outprocessapplication.h"
#include ".\outofprocess\winhttphelper.h"
#ifdef max
#undef max
template<typename T> inline T max(T a, T b)
{
return a > b ? a : b;
}
#endif
#ifdef min
#undef min
template<typename T> inline T min(T a, T b)
{
return a < b ? a : b;
}
#endif
#define ASPNETCORE_EVENT_PROVIDER L"IIS AspNetCore Module"
#define ASPNETCORE_IISEXPRESS_EVENT_PROVIDER L"IIS Express AspNetCore Module"
inline bool IsSpace(char ch)
{
switch (ch)
{
case 32: // ' '
case 9: // '\t'
case 10: // '\n'
case 13: // '\r'
case 11: // '\v'
case 12: // '\f'
return true;
default:
return false;
}
}
extern BOOL g_fAsyncDisconnectAvailable;
extern BOOL g_fWinHttpNonBlockingCallbackAvailable;
extern BOOL g_fWebSocketSupported;
extern BOOL g_fNsiApiNotSupported;
extern BOOL g_fEnableReferenceCountTracing;
extern DWORD g_dwActiveServerProcesses;
extern DWORD g_OptionalWinHttpFlags;
extern SRWLOCK g_srwLockRH;
extern HINTERNET g_hWinhttpSession;
extern DWORD g_dwTlsIndex;

Просмотреть файл

@ -0,0 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#define IDS_INVALID_PROPERTY 1000
#define IDS_SERVER_ERROR 1001
#define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and is listening on port '%d'."
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG L"Maximum rapid fail count per minute of '%d' exceeded."
#define ASPNETCORE_EVENT_PROCESS_START_INTERNAL_ERROR_MSG L"Application '%s' failed to parse processPath and arguments due to internal error, ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_PROCESS_START_POSTCREATE_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s'but failed to get its status, ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_PROCESS_START_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s', ErrorCode = '0x%x' processStatus code '%x'."
#define ASPNETCORE_EVENT_PROCESS_START_WRONGPORT_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but failed to listen on the given port '%d'"
#define ASPNETCORE_EVENT_PROCESS_START_NOTREADY_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but either crashed or did not reponse or did not listen on the given port '%d', ErrorCode = '0x%x'"
#define ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG L"Warning: Could not create stdoutLogFile %s, ErrorCode = %d."
#define ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE_MSG L"Failed to gracefully shutdown process '%d'."
#define ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST_MSG L"Sent shutdown HTTP message to process '%d' and received http status '%d'."
#define ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG L"Application '%s' with physical root '%s' failed to load clr and managed application, ErrorCode = '0x%x."
#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 '%s' other than the one of running application(s)."
#define ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG L"Failed to start application '%s', ErrorCode '0x%x'."
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, ErrorCode = '0x%x."

Просмотреть файл

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#ifndef _STTIMER_H
#define _STTIMER_H
@ -111,6 +113,41 @@ public:
fInCanel = FALSE;
}
static
VOID
CALLBACK
TimerCallback(
_In_ PTP_CALLBACK_INSTANCE Instance,
_In_ PVOID Context,
_In_ PTP_TIMER Timer
)
{
Instance;
Timer;
STRU* pstruLogFilePath = (STRU*)Context;
HANDLE hStdoutHandle = NULL;
SECURITY_ATTRIBUTES saAttr = { 0 };
HRESULT hr = S_OK;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
hStdoutHandle = CreateFileW(pstruLogFilePath->QueryStr(),
FILE_READ_DATA,
FILE_SHARE_WRITE,
&saAttr,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hStdoutHandle == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
CloseHandle(hStdoutHandle);
}
private:
VOID

Просмотреть файл

@ -0,0 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
#define FileVersion 7,1,1987,0
#define FileVersionStr "7.1.1987.0\0"
#define ProductVersion 7,1,1987,0
#define ProductVersionStr "7.1.1987.0\0"
#define PlatformToolset "v141\0"