Panwang/refactor (#277)

* 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 committed by Justin Kotalik
parent 9a1cc4ba1c
commit 30bbd87d81
103 changed files with 7317 additions and 5797 deletions

11
.gitignore vendored
View File

@ -25,15 +25,9 @@ project.lock.json
*.ncrunchsolution
*.*sdf
*.ipch
<<<<<<< HEAD
*.vs/
.vscode/
.testPublish/
.build/
*.nuget.props
*.nuget.targets
global.json
=======
*.bin
*.vs/
.testPublish/
@ -41,12 +35,15 @@ global.json
*.obj
*.tlog
*.CppClean.log
*msbuild.log
src/*/Debug/
src/*/x64/Debug/
src/*/Release/
src/*/x64/Release/
x64/
*vcxproj.filters
*.aps
*.pdb
*.lib
@ -59,5 +56,3 @@ src/AspNetCore/version.h
*.VC.*db
global.json
>>>>>>> ANCM/dev

View File

@ -1,93 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27110.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCore", "src\AspNetCore\AspNetCore.vcxproj", "{439824F9-1455-4CC4-BD79-B44FA0A16552}"
ProjectSection(ProjectDependencies) = postProject
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}
EndProjectSection
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}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FDD2EDF8-1B62-4978-9815-9D95260B8B91}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCoreModule.Test", "test\AspNetCoreModule.Test\AspNetCoreModule.Test.csproj", "{4DDA7560-AA29-4161-A5EA-A7E8F3997321}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCoreModule.TestSites.Standard", "test\AspNetCoreModule.TestSites.Standard\AspNetCoreModule.TestSites.Standard.csproj", "{030225D8-4EE8-47E5-B692-2A96B3B51A38}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0EF45656-B25D-40D8-959C-726EAF185E60}"
ProjectSection(SolutionItems) = preProject
NuGet.Config = NuGet.Config
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|Win32 = Release|Win32
Release|x64 = Release|x64
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|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
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|Win32.ActiveCfg = Release|Win32
{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
{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|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
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|Win32.ActiveCfg = Release|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|Win32.Build.0 = Release|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.ActiveCfg = Release|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.Build.0 = Release|x64
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Win32.ActiveCfg = Debug|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Win32.Build.0 = Debug|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|x64.ActiveCfg = Debug|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|x64.Build.0 = Debug|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Any CPU.Build.0 = Release|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Win32.ActiveCfg = Release|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Win32.Build.0 = Release|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|x64.ActiveCfg = Release|Any CPU
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|x64.Build.0 = Release|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Win32.ActiveCfg = Debug|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Win32.Build.0 = Debug|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|x64.ActiveCfg = Debug|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|x64.Build.0 = Debug|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Any CPU.Build.0 = Release|Any CPU
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Win32.ActiveCfg = Release|Any CPU
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0967E9B4-FEE7-40D7-860A-23E340E65840}
EndGlobalSection
EndGlobal

View File

@ -1,17 +1,12 @@
<<<<<<< HEAD
<Project>
<Project>
<Import
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))\AspNetCoreSettings.props"
Condition=" '$(CI)' != 'true' AND '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))' != '' " />
=======
<Project>
>>>>>>> ANCM/dev
<Import Project="version.props" />
<Import Project="build\dependencies.props" />
<Import Project="build\sources.props" />
<<<<<<< HEAD
<PropertyGroup>
<Product>Microsoft ASP.NET Core</Product>
<RepositoryUrl>https://github.com/aspnet/IISIntegration</RepositoryUrl>
@ -28,14 +23,4 @@
<PackageReference Include="Microsoft.NETCore.Compilers" Version="$(MicrosoftNETCoreCompilersPackageVersion)" PrivateAssets="All" />
</ItemGroup>
=======
<PropertyGroup>
<Product>Microsoft ASP.NET Core</Product>
<RepositoryUrl>https://github.com/aspnet/AspNetCoreModule</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
</PropertyGroup>
>>>>>>> ANCM/dev
</Project>

View File

@ -45,6 +45,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISTestSite", "test\IISTest
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.IISServerFunctionalTests", "test\IISIntegration.IISServerFunctionalTests\IISIntegration.IISServerFunctionalTests.csproj", "{C745BBFD-7888-4038-B41B-6D1832D13878}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCore", "src\AspNetCore\AspNetCore.vcxproj", "{439824F9-1455-4CC4-BD79-B44FA0A16552}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IISLib", "src\IISLib\IISLib.vcxproj", "{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandler", "src\RequestHandler\RequestHandler.vcxproj", "{D57EA297-6DC2-4BC0-8C91-334863327863}"
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
@ -150,6 +158,50 @@ Global
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x64.ActiveCfg = Release|Any CPU
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x64.Build.0 = Release|Any CPU
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x86.ActiveCfg = Release|Any CPU
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Any CPU.ActiveCfg = Debug|Win32
{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}.Debug|x86.ActiveCfg = Debug|Win32
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x86.Build.0 = Debug|Win32
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|Any CPU.ActiveCfg = Release|Win32
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.ActiveCfg = Release|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.Build.0 = Release|x64
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x86.ActiveCfg = Release|Win32
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x86.Build.0 = Release|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Any CPU.ActiveCfg = Debug|Win32
{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}.Debug|x86.ActiveCfg = Debug|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|x86.Build.0 = Debug|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|Any CPU.ActiveCfg = Release|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.ActiveCfg = Release|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.Build.0 = Release|x64
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x86.ActiveCfg = Release|Win32
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x86.Build.0 = Release|Win32
{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
{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
@ -163,6 +215,10 @@ Global
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
{679FA2A2-898B-4320-884E-C2D294A97CE1} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{C745BBFD-7888-4038-B41B-6D1832D13878} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
{D57EA297-6DC2-4BC0-8C91-334863327863} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
{55494E58-E061-4C4C-A0A8-837008E72F85} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}

View File

@ -1,4 +1,3 @@
<<<<<<< HEAD
Copyright (c) .NET Foundation and Contributors
All rights reserved.
@ -13,7 +12,7 @@ Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
=======
ASP.NET Core Module
Copyright (c) .NET Foundation
@ -36,5 +35,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>>>>>>> ANCM/dev
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,10 +1,7 @@
<<<<<<< HEAD
ASP.NET Core IIS Integration
========
This repo hosts the ASP.NET Core middleware for IIS integration.
This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo.
=======
# ASP.NET Core Module

View File

@ -1,6 +1,2 @@
@ECHO OFF
<<<<<<< HEAD
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
=======
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
>>>>>>> ANCM/dev

View File

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

View File

@ -1,5 +1,4 @@
<<<<<<< HEAD
<Project>
<Project>
<Import Project="dependencies.props" />
<ItemGroup>

View File

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

View File

@ -1,8 +1,4 @@
<<<<<<< HEAD
<Project>
=======
<Project>
>>>>>>> ANCM/dev
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
<PropertyGroup Label="RestoreSources">

View File

@ -1,7 +1,2 @@
<<<<<<< HEAD
version:2.1.0-preview1-15576
commithash:2f3856d2ba4f659fcb9253215b83946a06794a27
=======
version:2.1.0-preview1-15620
commithash:6432b49a2c00310416df39b6fe548ef4af9c6011
>>>>>>> ANCM/dev

View File

@ -1,9 +1,4 @@
{
<<<<<<< HEAD
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
"channel": "dev"
}
=======
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
"channel": "dev",
"toolsets": {
@ -16,5 +11,4 @@
]
}
}
}
>>>>>>> ANCM/dev
}

View File

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

View File

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

View File

@ -1,6 +1,2 @@
@ECHO OFF
<<<<<<< HEAD
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
=======
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
>>>>>>> ANCM/dev

36
run.ps1
View File

@ -29,12 +29,9 @@ Updates KoreBuild to the latest version even if a lock file is present.
.PARAMETER ConfigFile
The path to the configuration file that stores values. Defaults to korebuild.json.
<<<<<<< HEAD
.PARAMETER ToolsSourceSuffix
The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores.
=======
>>>>>>> ANCM/dev
.PARAMETER Arguments
Arguments to be passed to the command
@ -57,11 +54,7 @@ Example config file:
#>
[CmdletBinding(PositionalBinding = $false)]
param(
<<<<<<< HEAD
[Parameter(Mandatory = $true, Position = 0)]
=======
[Parameter(Mandatory=$true, Position = 0)]
>>>>>>> ANCM/dev
[string]$Command,
[string]$Path = $PSScriptRoot,
[Alias('c')]
@ -73,10 +66,7 @@ param(
[Alias('u')]
[switch]$Update,
[string]$ConfigFile,
<<<<<<< HEAD
[string]$ToolsSourceSuffix,
=======
>>>>>>> ANCM/dev
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Arguments
)
@ -93,11 +83,7 @@ function Get-KoreBuild {
$lockFile = Join-Path $Path 'korebuild-lock.txt'
if (!(Test-Path $lockFile) -or $Update) {
<<<<<<< HEAD
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix
=======
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile
>>>>>>> ANCM/dev
}
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
@ -114,11 +100,7 @@ function Get-KoreBuild {
try {
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
<<<<<<< HEAD
Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix
=======
Get-RemoteFile $remotePath $tmpfile
>>>>>>> ANCM/dev
if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
# Use built-in commands where possible as they are cross-plat compatible
Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
@ -146,11 +128,7 @@ function Join-Paths([string]$path, [string[]]$childPaths) {
return $path
}
<<<<<<< HEAD
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) {
=======
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
>>>>>>> ANCM/dev
if ($RemotePath -notlike 'http*') {
Copy-Item $RemotePath $LocalPath
return
@ -160,11 +138,7 @@ function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
while ($retries -gt 0) {
$retries -= 1
try {
<<<<<<< HEAD
Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath
=======
Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
>>>>>>> ANCM/dev
return
}
catch {
@ -191,12 +165,8 @@ if (Test-Path $ConfigFile) {
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
}
<<<<<<< HEAD
}
catch {
=======
} catch {
>>>>>>> ANCM/dev
Write-Warning "$ConfigFile could not be read. Its settings will be ignored."
Write-Warning $Error[0]
}
@ -223,8 +193,4 @@ try {
}
finally {
Remove-Module 'KoreBuild' -ErrorAction Ignore
<<<<<<< HEAD
}
=======
}
>>>>>>> ANCM/dev
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

BIN
src/CommonLib/stdafx.cpp Normal file

Binary file not shown.

BIN
src/CommonLib/stdafx.h Normal file

Binary file not shown.

BIN
src/CommonLib/targetver.h Normal file

Binary file not shown.

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

View File

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

View File

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

View File

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

Binary file not shown.

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

View File

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

Binary file not shown.

View File

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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[] =
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More