Adds support for ANCM in process (#425)
This commit is contained in:
parent
461044f548
commit
9dc69fe361
|
|
@ -1,4 +1,4 @@
|
|||
<Project InitialTargets="EnsureKoreBuildRestored">
|
||||
<Project InitialTargets="EnsureKoreBuildRestored">
|
||||
<Target Name="EnsureKoreBuildRestored" Condition=" '$(KoreBuildRestoreTargetsImported)' != 'true' AND '$(MSBuildProjectName)' != 'BenchmarkDotNet.Autogenerated'">
|
||||
<PropertyGroup>
|
||||
<_BootstrapperFile Condition=" $([MSBuild]::IsOSUnixLike()) ">build.sh</_BootstrapperFile>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7E80C58E
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.FunctionalTests", "test\IISIntegration.FunctionalTests\IISIntegration.FunctionalTests.csproj", "{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IIS", "src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj", "{5C475A6A-8FF6-401F-A35E-01461312C8F6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeIISSample", "samples\NativeIISSample\NativeIISSample.csproj", "{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISTestSite", "test\IISTestSite\IISTestSite.csproj", "{679FA2A2-898B-4320-884E-C2D294A97CE1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.IISServerFunctionalTests", "test\IISIntegration.IISServerFunctionalTests\IISIntegration.IISServerFunctionalTests.csproj", "{C745BBFD-7888-4038-B41B-6D1832D13878}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -109,6 +117,53 @@ Global
|
|||
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x86.Build.0 = Release|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{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
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -119,6 +174,10 @@ Global
|
|||
{4106DB10-E09F-480E-9CE6-B39235512EE6} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{F54715C3-88D8-49E3-A291-C13570FE81FC} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{5C475A6A-8FF6-401F-A35E-01461312C8F6} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{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}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<Project>
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\TestSites\*.csproj" />
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\IISTestSite\*.csproj" />
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\IISIntegration.FunctionalTests\*.csproj" Condition="'$(OS)' != 'Windows_NT'" />
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\IISIntegration.IISServerFunctionalTests\*.csproj" Condition="'$(OS)' != 'Windows_NT'" />
|
||||
<PackageLineup Include="Internal.AspNetCore.Universe.Lineup" Version="2.1.0-*" />
|
||||
<PackageLineup Include="Internal.AspNetCore.Partners.Lineup" Version="2.1.0-*" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:5762/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Local ANCM": {
|
||||
"commandName": "Executable",
|
||||
"executablePath": "$(ProgramW6432)\\IIS Express\\iisexpress.exe",
|
||||
"commandLineArgs": "/config:\"$(MSBuildThisFileDirectory)applicationhost.config\" /site:\"$(ProjectName)\" /apppool:\"Clr4IntegratedAppPool\"",
|
||||
"environmentVariables": {
|
||||
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
|
||||
"ANCM_PATH": "$(ProgramW6432)\\IIS Express",
|
||||
"LAUNCHER_ARGS": "$(TargetPath)",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"LAUNCHER_PATH": "dotnet.exe"
|
||||
}
|
||||
},
|
||||
"NativeIISSample": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:5763/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Server.IIS;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace NativeIISSample
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
app.Run(async (context) =>
|
||||
{
|
||||
context.Response.ContentType = "text/plain";
|
||||
await context.Response.WriteAsync("Hello World - " + DateTimeOffset.Now + Environment.NewLine);
|
||||
await context.Response.WriteAsync(Environment.NewLine);
|
||||
|
||||
await context.Response.WriteAsync("Address:" + Environment.NewLine);
|
||||
await context.Response.WriteAsync("Scheme: " + context.Request.Scheme + Environment.NewLine);
|
||||
await context.Response.WriteAsync("Host: " + context.Request.Headers["Host"] + Environment.NewLine);
|
||||
await context.Response.WriteAsync("PathBase: " + context.Request.PathBase.Value + Environment.NewLine);
|
||||
await context.Response.WriteAsync("Path: " + context.Request.Path.Value + Environment.NewLine);
|
||||
await context.Response.WriteAsync("Query: " + context.Request.QueryString.Value + Environment.NewLine);
|
||||
await context.Response.WriteAsync(Environment.NewLine);
|
||||
|
||||
await context.Response.WriteAsync("Connection:" + Environment.NewLine);
|
||||
await context.Response.WriteAsync("RemoteIp: " + context.Connection.RemoteIpAddress + Environment.NewLine);
|
||||
await context.Response.WriteAsync("RemotePort: " + context.Connection.RemotePort + Environment.NewLine);
|
||||
await context.Response.WriteAsync("LocalIp: " + context.Connection.LocalIpAddress + Environment.NewLine);
|
||||
await context.Response.WriteAsync("LocalPort: " + context.Connection.LocalPort + Environment.NewLine);
|
||||
await context.Response.WriteAsync("ClientCert: " + context.Connection.ClientCertificate + Environment.NewLine);
|
||||
await context.Response.WriteAsync(Environment.NewLine);
|
||||
|
||||
await context.Response.WriteAsync("User: " + context.User.Identity.Name + Environment.NewLine);
|
||||
//var scheme = await authSchemeProvider.GetSchemeAsync(IISDefaults.AuthenticationScheme);
|
||||
//await context.Response.WriteAsync("DisplayName: " + scheme?.DisplayName + Environment.NewLine);
|
||||
|
||||
await context.Response.WriteAsync(Environment.NewLine);
|
||||
|
||||
await context.Response.WriteAsync("Headers:" + Environment.NewLine);
|
||||
foreach (var header in context.Request.Headers)
|
||||
{
|
||||
await context.Response.WriteAsync(header.Key + ": " + header.Value + Environment.NewLine);
|
||||
}
|
||||
await context.Response.WriteAsync(Environment.NewLine);
|
||||
|
||||
await context.Response.WriteAsync("Environment Variables:" + Environment.NewLine);
|
||||
var vars = Environment.GetEnvironmentVariables();
|
||||
foreach (var key in vars.Keys.Cast<string>().OrderBy(key => key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var value = vars[key];
|
||||
await context.Response.WriteAsync(key + ": " + value + Environment.NewLine);
|
||||
}
|
||||
await context.Response.WriteAsync(Environment.NewLine);
|
||||
});
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseNativeIIS()
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,987 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
IIS configuration sections.
|
||||
|
||||
For schema documentation, see
|
||||
%IIS_BIN%\config\schema\IIS_schema.xml.
|
||||
|
||||
Please make a backup of this file before making any changes to it.
|
||||
|
||||
NOTE: The following environment variables are available to be used
|
||||
within this file and are understood by the IIS Express.
|
||||
|
||||
%IIS_USER_HOME% - The IIS Express home directory for the user
|
||||
%IIS_SITES_HOME% - The default home directory for sites
|
||||
%IIS_BIN% - The location of the IIS Express binaries
|
||||
%SYSTEMDRIVE% - The drive letter of %IIS_BIN%
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
<!--
|
||||
|
||||
The <configSections> section controls the registration of sections.
|
||||
Section is the basic unit of deployment, locking, searching and
|
||||
containment for configuration settings.
|
||||
|
||||
Every section belongs to one section group.
|
||||
A section group is a container of logically-related sections.
|
||||
|
||||
Sections cannot be nested.
|
||||
Section groups may be nested.
|
||||
|
||||
<section
|
||||
name="" [Required, Collection Key] [XML name of the section]
|
||||
allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set]
|
||||
overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode]
|
||||
allowLocation="true" [true|false] [Allowed in location tags]
|
||||
/>
|
||||
|
||||
The recommended way to unlock sections is by using a location tag:
|
||||
<location path="Default Web Site" overrideMode="Allow">
|
||||
<system.webServer>
|
||||
<asp />
|
||||
</system.webServer>
|
||||
</location>
|
||||
|
||||
-->
|
||||
<configSections>
|
||||
<sectionGroup name="system.applicationHost">
|
||||
<section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="sites" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<sectionGroup name="system.webServer">
|
||||
<section name="asp" overrideModeDefault="Deny" />
|
||||
<section name="caching" overrideModeDefault="Allow" />
|
||||
<section name="cgi" overrideModeDefault="Deny" />
|
||||
<section name="defaultDocument" overrideModeDefault="Allow" />
|
||||
<section name="directoryBrowse" overrideModeDefault="Allow" />
|
||||
<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="globalModules" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="handlers" overrideModeDefault="Deny" />
|
||||
<section name="httpCompression" overrideModeDefault="Allow" />
|
||||
<section name="httpErrors" overrideModeDefault="Allow" />
|
||||
<section name="httpLogging" overrideModeDefault="Deny" />
|
||||
<section name="httpProtocol" overrideModeDefault="Allow" />
|
||||
<section name="httpRedirect" overrideModeDefault="Allow" />
|
||||
<section name="httpTracing" overrideModeDefault="Deny" />
|
||||
<section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||
<section name="odbcLogging" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="security">
|
||||
<section name="access" overrideModeDefault="Deny" />
|
||||
<section name="applicationDependencies" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="authentication">
|
||||
<section name="anonymousAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="basicAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="digestAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="windowsAuthentication" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="authorization" overrideModeDefault="Allow" />
|
||||
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||
<section name="dynamicIpSecurity" overrideModeDefault="Deny" />
|
||||
<section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="requestFiltering" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
<section name="serverRuntime" overrideModeDefault="Deny" />
|
||||
<section name="serverSideInclude" overrideModeDefault="Deny" />
|
||||
<section name="staticContent" overrideModeDefault="Allow" />
|
||||
<sectionGroup name="tracing">
|
||||
<section name="traceFailedRequests" overrideModeDefault="Allow" />
|
||||
<section name="traceProviderDefinitions" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="urlCompression" overrideModeDefault="Allow" />
|
||||
<section name="validation" overrideModeDefault="Allow" />
|
||||
<sectionGroup name="webdav">
|
||||
<section name="globalSettings" overrideModeDefault="Deny" />
|
||||
<section name="authoring" overrideModeDefault="Deny" />
|
||||
<section name="authoringRules" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<sectionGroup name="rewrite">
|
||||
<section name="allowedServerVariables" overrideModeDefault="Deny" />
|
||||
<section name="rules" overrideModeDefault="Allow" />
|
||||
<section name="outboundRules" overrideModeDefault="Allow" />
|
||||
<section name="globalRules" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
<section name="providers" overrideModeDefault="Allow" />
|
||||
<section name="rewriteMaps" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
<section name="webSocket" overrideModeDefault="Deny" />
|
||||
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<configProtectedData>
|
||||
<providers>
|
||||
<add name="IISWASOnlyRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
|
||||
<add name="AesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAAKmFQvWHDEETRz8l2bjZlRxIkwcqTFaCUnCLljn3Q1OkesrhEO9YyLyx4bUhsj1/DyShAv7OAFFhXlrlomaornnk5PLeyO4lIXxaiT33yOFUUgxDx4GSaygkqghVV0tO5yQ/XguUBp2juMfZyztnsNa4pLcz7ZNZQ6p4yn9hxwNs=" />
|
||||
<add name="IISWASOnlyAesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAA4WoiRJ8KHwzAG8AgejPxEOO4/2Vhkolbwo/8gZeNdUDSD36m55hWv4uC9tr/MlKdnwRLL0NhT50Gccyftqz5xTZ0dg5FtvQhTw/he1NwexTKbV+I4Zrd+sZUqHZTsr7JiEr6OHGXL70qoISW5G2m9U8wKT3caPiDPNj2aAaYPLo=" />
|
||||
</providers>
|
||||
</configProtectedData>
|
||||
<system.applicationHost>
|
||||
<applicationPools>
|
||||
<add name="Clr4IntegratedAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||
<add name="Clr4ClassicAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||
<add name="Clr2IntegratedAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||
<add name="Clr2ClassicAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||
<add name="UnmanagedClassicAppPool" managedRuntimeVersion="" managedPipelineMode="Classic" autoStart="true" />
|
||||
<applicationPoolDefaults managedRuntimeLoader="v4.0">
|
||||
<processModel />
|
||||
</applicationPoolDefaults>
|
||||
</applicationPools>
|
||||
<!--
|
||||
|
||||
The <listenerAdapters> section defines the protocols with which the
|
||||
Windows Process Activation Service (WAS) binds.
|
||||
|
||||
-->
|
||||
<listenerAdapters>
|
||||
<add name="http" />
|
||||
</listenerAdapters>
|
||||
<sites>
|
||||
<site name="WebSite1" id="1" serverAutoStart="true">
|
||||
<application path="/">
|
||||
<virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\WebSite1" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation=":8080:localhost" />
|
||||
</bindings>
|
||||
</site>
|
||||
<site name="NativeIISSample" id="2">
|
||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||
<virtualDirectory path="/" physicalPath="%IIS_SITE_PATH%" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:50690:localhost" />
|
||||
</bindings>
|
||||
</site>
|
||||
<siteDefaults>
|
||||
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
|
||||
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
|
||||
</siteDefaults>
|
||||
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
|
||||
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||
</sites>
|
||||
<webLimits />
|
||||
</system.applicationHost>
|
||||
<system.webServer>
|
||||
<serverRuntime />
|
||||
<asp scriptErrorSentToBrowser="true">
|
||||
<cache diskTemplateCacheDirectory="%TEMP%\iisexpress\ASP Compiled Templates" />
|
||||
<limits />
|
||||
</asp>
|
||||
<caching enabled="true" enableKernelCache="true"></caching>
|
||||
<cgi />
|
||||
<defaultDocument enabled="true">
|
||||
<files>
|
||||
<add value="Default.htm" />
|
||||
<add value="Default.asp" />
|
||||
<add value="index.htm" />
|
||||
<add value="index.html" />
|
||||
<add value="iisstart.htm" />
|
||||
<add value="default.aspx" />
|
||||
</files>
|
||||
</defaultDocument>
|
||||
<directoryBrowse enabled="false" />
|
||||
<fastCgi />
|
||||
<!--
|
||||
|
||||
The <globalModules> section defines all native-code modules.
|
||||
To enable a module, specify it in the <modules> section.
|
||||
|
||||
-->
|
||||
<globalModules>
|
||||
<add name="HttpLoggingModule" image="%IIS_BIN%\loghttp.dll" />
|
||||
<add name="UriCacheModule" image="%IIS_BIN%\cachuri.dll" />
|
||||
<!-- <add name="FileCacheModule" image="%IIS_BIN%\cachfile.dll" /> -->
|
||||
<add name="TokenCacheModule" image="%IIS_BIN%\cachtokn.dll" />
|
||||
<!-- <add name="HttpCacheModule" image="%IIS_BIN%\cachhttp.dll" /> -->
|
||||
<add name="DynamicCompressionModule" image="%IIS_BIN%\compdyn.dll" />
|
||||
<add name="StaticCompressionModule" image="%IIS_BIN%\compstat.dll" />
|
||||
<add name="DefaultDocumentModule" image="%IIS_BIN%\defdoc.dll" />
|
||||
<add name="DirectoryListingModule" image="%IIS_BIN%\dirlist.dll" />
|
||||
<add name="ProtocolSupportModule" image="%IIS_BIN%\protsup.dll" />
|
||||
<add name="HttpRedirectionModule" image="%IIS_BIN%\redirect.dll" />
|
||||
<add name="ServerSideIncludeModule" image="%IIS_BIN%\iis_ssi.dll" />
|
||||
<add name="StaticFileModule" image="%IIS_BIN%\static.dll" />
|
||||
<add name="AnonymousAuthenticationModule" image="%IIS_BIN%\authanon.dll" />
|
||||
<add name="CertificateMappingAuthenticationModule" image="%IIS_BIN%\authcert.dll" />
|
||||
<add name="UrlAuthorizationModule" image="%IIS_BIN%\urlauthz.dll" />
|
||||
<add name="BasicAuthenticationModule" image="%IIS_BIN%\authbas.dll" />
|
||||
<add name="WindowsAuthenticationModule" image="%IIS_BIN%\authsspi.dll" />
|
||||
<!-- <add name="DigestAuthenticationModule" image="%IIS_BIN%\authmd5.dll" /> -->
|
||||
<add name="IISCertificateMappingAuthenticationModule" image="%IIS_BIN%\authmap.dll" />
|
||||
<add name="IpRestrictionModule" image="%IIS_BIN%\iprestr.dll" />
|
||||
<add name="DynamicIpRestrictionModule" image="%IIS_BIN%\diprestr.dll" />
|
||||
<add name="RequestFilteringModule" image="%IIS_BIN%\modrqflt.dll" />
|
||||
<add name="CustomLoggingModule" image="%IIS_BIN%\logcust.dll" />
|
||||
<add name="CustomErrorModule" image="%IIS_BIN%\custerr.dll" />
|
||||
<!-- <add name="TracingModule" image="%IIS_BIN%\iisetw.dll" /> -->
|
||||
<add name="FailedRequestsTracingModule" image="%IIS_BIN%\iisfreb.dll" />
|
||||
<add name="RequestMonitorModule" image="%IIS_BIN%\iisreqs.dll" />
|
||||
<add name="IsapiModule" image="%IIS_BIN%\isapi.dll" />
|
||||
<add name="IsapiFilterModule" image="%IIS_BIN%\filter.dll" />
|
||||
<add name="CgiModule" image="%IIS_BIN%\cgi.dll" />
|
||||
<add name="FastCgiModule" image="%IIS_BIN%\iisfcgi.dll" />
|
||||
<!-- <add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" /> -->
|
||||
<add name="RewriteModule" image="%IIS_BIN%\rewrite.dll" />
|
||||
<add name="ConfigurationValidationModule" image="%IIS_BIN%\validcfg.dll" />
|
||||
<add name="WebSocketModule" image="%IIS_BIN%\iiswsock.dll" />
|
||||
<add name="WebMatrixSupportModule" image="%IIS_BIN%\webmatrixsup.dll" />
|
||||
<add name="ManagedEngine" image="%windir%\Microsoft.NET\Framework\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness32" />
|
||||
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
|
||||
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="ApplicationInitializationModule" image="%IIS_BIN%\warmup.dll" />
|
||||
<add name="AspNetCoreModule" image="%ANCM_PATH%\aspnetcore.dll" />
|
||||
</globalModules>
|
||||
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
|
||||
<scheme name="gzip" dll="%IIS_BIN%\gzip.dll" />
|
||||
<dynamicTypes>
|
||||
<add mimeType="text/*" enabled="true" />
|
||||
<add mimeType="message/*" enabled="true" />
|
||||
<add mimeType="application/javascript" enabled="true" />
|
||||
<add mimeType="application/atom+xml" enabled="true" />
|
||||
<add mimeType="application/xaml+xml" enabled="true" />
|
||||
<add mimeType="*/*" enabled="false" />
|
||||
</dynamicTypes>
|
||||
<staticTypes>
|
||||
<add mimeType="text/*" enabled="true" />
|
||||
<add mimeType="message/*" enabled="true" />
|
||||
<add mimeType="image/svg+xml" enabled="true" />
|
||||
<add mimeType="application/javascript" enabled="true" />
|
||||
<add mimeType="application/atom+xml" enabled="true" />
|
||||
<add mimeType="application/xaml+xml" enabled="true" />
|
||||
<add mimeType="*/*" enabled="false" />
|
||||
</staticTypes>
|
||||
</httpCompression>
|
||||
<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
|
||||
<error statusCode="401" prefixLanguageFilePath="%IIS_BIN%\custerr" path="401.htm" />
|
||||
<error statusCode="403" prefixLanguageFilePath="%IIS_BIN%\custerr" path="403.htm" />
|
||||
<error statusCode="404" prefixLanguageFilePath="%IIS_BIN%\custerr" path="404.htm" />
|
||||
<error statusCode="405" prefixLanguageFilePath="%IIS_BIN%\custerr" path="405.htm" />
|
||||
<error statusCode="406" prefixLanguageFilePath="%IIS_BIN%\custerr" path="406.htm" />
|
||||
<error statusCode="412" prefixLanguageFilePath="%IIS_BIN%\custerr" path="412.htm" />
|
||||
<error statusCode="500" prefixLanguageFilePath="%IIS_BIN%\custerr" path="500.htm" />
|
||||
<error statusCode="501" prefixLanguageFilePath="%IIS_BIN%\custerr" path="501.htm" />
|
||||
<error statusCode="502" prefixLanguageFilePath="%IIS_BIN%\custerr" path="502.htm" />
|
||||
</httpErrors>
|
||||
<httpLogging dontLog="false" />
|
||||
<httpProtocol>
|
||||
<customHeaders>
|
||||
<clear />
|
||||
<add name="X-Powered-By" value="ASP.NET" />
|
||||
</customHeaders>
|
||||
<redirectHeaders>
|
||||
<clear />
|
||||
</redirectHeaders>
|
||||
</httpProtocol>
|
||||
<httpRedirect enabled="false" />
|
||||
<httpTracing></httpTracing>
|
||||
<isapiFilters>
|
||||
<filter name="ASP.Net_2.0.50727-64" path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv2.0" />
|
||||
<filter name="ASP.Net_2.0.50727.0" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv2.0" />
|
||||
<filter name="ASP.Net_2.0_for_v1.1" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="runtimeVersionv1.1" />
|
||||
<filter name="ASP.Net_4.0_32bit" path="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv4.0" />
|
||||
<filter name="ASP.Net_4.0_64bit" path="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv4.0" />
|
||||
</isapiFilters>
|
||||
<odbcLogging />
|
||||
<security>
|
||||
<access sslFlags="None" />
|
||||
<applicationDependencies>
|
||||
<application name="Active Server Pages" groupId="ASP" />
|
||||
</applicationDependencies>
|
||||
<authentication>
|
||||
<anonymousAuthentication enabled="true" userName="" />
|
||||
<basicAuthentication enabled="false" />
|
||||
<clientCertificateMappingAuthentication enabled="false" />
|
||||
<digestAuthentication enabled="false" />
|
||||
<iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
|
||||
<windowsAuthentication enabled="false">
|
||||
<providers>
|
||||
<add value="Negotiate" />
|
||||
<add value="NTLM" />
|
||||
</providers>
|
||||
</windowsAuthentication>
|
||||
</authentication>
|
||||
<authorization>
|
||||
<add accessType="Allow" users="*" />
|
||||
</authorization>
|
||||
<ipSecurity allowUnlisted="true" />
|
||||
<isapiCgiRestriction notListedIsapisAllowed="true" notListedCgisAllowed="true">
|
||||
<add path="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
|
||||
<add path="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
|
||||
<add path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
|
||||
<add path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
|
||||
</isapiCgiRestriction>
|
||||
<requestFiltering>
|
||||
<fileExtensions allowUnlisted="true" applyToWebDAV="true">
|
||||
<add fileExtension=".asa" allowed="false" />
|
||||
<add fileExtension=".asax" allowed="false" />
|
||||
<add fileExtension=".ascx" allowed="false" />
|
||||
<add fileExtension=".master" allowed="false" />
|
||||
<add fileExtension=".skin" allowed="false" />
|
||||
<add fileExtension=".browser" allowed="false" />
|
||||
<add fileExtension=".sitemap" allowed="false" />
|
||||
<add fileExtension=".config" allowed="false" />
|
||||
<add fileExtension=".cs" allowed="false" />
|
||||
<add fileExtension=".csproj" allowed="false" />
|
||||
<add fileExtension=".vb" allowed="false" />
|
||||
<add fileExtension=".vbproj" allowed="false" />
|
||||
<add fileExtension=".webinfo" allowed="false" />
|
||||
<add fileExtension=".licx" allowed="false" />
|
||||
<add fileExtension=".resx" allowed="false" />
|
||||
<add fileExtension=".resources" allowed="false" />
|
||||
<add fileExtension=".mdb" allowed="false" />
|
||||
<add fileExtension=".vjsproj" allowed="false" />
|
||||
<add fileExtension=".java" allowed="false" />
|
||||
<add fileExtension=".jsl" allowed="false" />
|
||||
<add fileExtension=".ldb" allowed="false" />
|
||||
<add fileExtension=".dsdgm" allowed="false" />
|
||||
<add fileExtension=".ssdgm" allowed="false" />
|
||||
<add fileExtension=".lsad" allowed="false" />
|
||||
<add fileExtension=".ssmap" allowed="false" />
|
||||
<add fileExtension=".cd" allowed="false" />
|
||||
<add fileExtension=".dsprototype" allowed="false" />
|
||||
<add fileExtension=".lsaprototype" allowed="false" />
|
||||
<add fileExtension=".sdm" allowed="false" />
|
||||
<add fileExtension=".sdmDocument" allowed="false" />
|
||||
<add fileExtension=".mdf" allowed="false" />
|
||||
<add fileExtension=".ldf" allowed="false" />
|
||||
<add fileExtension=".ad" allowed="false" />
|
||||
<add fileExtension=".dd" allowed="false" />
|
||||
<add fileExtension=".ldd" allowed="false" />
|
||||
<add fileExtension=".sd" allowed="false" />
|
||||
<add fileExtension=".adprototype" allowed="false" />
|
||||
<add fileExtension=".lddprototype" allowed="false" />
|
||||
<add fileExtension=".exclude" allowed="false" />
|
||||
<add fileExtension=".refresh" allowed="false" />
|
||||
<add fileExtension=".compiled" allowed="false" />
|
||||
<add fileExtension=".msgx" allowed="false" />
|
||||
<add fileExtension=".vsdisco" allowed="false" />
|
||||
<add fileExtension=".rules" allowed="false" />
|
||||
</fileExtensions>
|
||||
<verbs allowUnlisted="true" applyToWebDAV="true" />
|
||||
<hiddenSegments applyToWebDAV="true">
|
||||
<add segment="web.config" />
|
||||
<add segment="bin" />
|
||||
<add segment="App_code" />
|
||||
<add segment="App_GlobalResources" />
|
||||
<add segment="App_LocalResources" />
|
||||
<add segment="App_WebReferences" />
|
||||
<add segment="App_Data" />
|
||||
<add segment="App_Browsers" />
|
||||
</hiddenSegments>
|
||||
</requestFiltering>
|
||||
</security>
|
||||
<serverSideInclude ssiExecDisable="false" />
|
||||
<staticContent lockAttributes="isDocFooterFileName">
|
||||
<mimeMap fileExtension=".323" mimeType="text/h323" />
|
||||
<mimeMap fileExtension=".3g2" mimeType="video/3gpp2" />
|
||||
<mimeMap fileExtension=".3gp2" mimeType="video/3gpp2" />
|
||||
<mimeMap fileExtension=".3gp" mimeType="video/3gpp" />
|
||||
<mimeMap fileExtension=".3gpp" mimeType="video/3gpp" />
|
||||
<mimeMap fileExtension=".aac" mimeType="audio/aac" />
|
||||
<mimeMap fileExtension=".aaf" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".aca" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".accdb" mimeType="application/msaccess" />
|
||||
<mimeMap fileExtension=".accde" mimeType="application/msaccess" />
|
||||
<mimeMap fileExtension=".accdt" mimeType="application/msaccess" />
|
||||
<mimeMap fileExtension=".acx" mimeType="application/internet-property-stream" />
|
||||
<mimeMap fileExtension=".adt" mimeType="audio/vnd.dlna.adts" />
|
||||
<mimeMap fileExtension=".adts" mimeType="audio/vnd.dlna.adts" />
|
||||
<mimeMap fileExtension=".afm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ai" mimeType="application/postscript" />
|
||||
<mimeMap fileExtension=".aif" mimeType="audio/x-aiff" />
|
||||
<mimeMap fileExtension=".aifc" mimeType="audio/aiff" />
|
||||
<mimeMap fileExtension=".aiff" mimeType="audio/aiff" />
|
||||
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
|
||||
<mimeMap fileExtension=".application" mimeType="application/x-ms-application" />
|
||||
<mimeMap fileExtension=".art" mimeType="image/x-jg" />
|
||||
<mimeMap fileExtension=".asd" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".asf" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".asi" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".asm" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".asr" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".asx" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".atom" mimeType="application/atom+xml" />
|
||||
<mimeMap fileExtension=".au" mimeType="audio/basic" />
|
||||
<mimeMap fileExtension=".avi" mimeType="video/msvideo" />
|
||||
<mimeMap fileExtension=".axs" mimeType="application/olescript" />
|
||||
<mimeMap fileExtension=".bas" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".bcpio" mimeType="application/x-bcpio" />
|
||||
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".bmp" mimeType="image/bmp" />
|
||||
<mimeMap fileExtension=".c" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".cab" mimeType="application/vnd.ms-cab-compressed" />
|
||||
<mimeMap fileExtension=".calx" mimeType="application/vnd.ms-office.calx" />
|
||||
<mimeMap fileExtension=".cat" mimeType="application/vnd.ms-pki.seccat" />
|
||||
<mimeMap fileExtension=".cdf" mimeType="application/x-cdf" />
|
||||
<mimeMap fileExtension=".chm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".class" mimeType="application/x-java-applet" />
|
||||
<mimeMap fileExtension=".clp" mimeType="application/x-msclip" />
|
||||
<mimeMap fileExtension=".cmx" mimeType="image/x-cmx" />
|
||||
<mimeMap fileExtension=".cnf" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".cod" mimeType="image/cis-cod" />
|
||||
<mimeMap fileExtension=".cpio" mimeType="application/x-cpio" />
|
||||
<mimeMap fileExtension=".cpp" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".crd" mimeType="application/x-mscardfile" />
|
||||
<mimeMap fileExtension=".crl" mimeType="application/pkix-crl" />
|
||||
<mimeMap fileExtension=".crt" mimeType="application/x-x509-ca-cert" />
|
||||
<mimeMap fileExtension=".csh" mimeType="application/x-csh" />
|
||||
<mimeMap fileExtension=".css" mimeType="text/css" />
|
||||
<mimeMap fileExtension=".csv" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".cur" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".dcr" mimeType="application/x-director" />
|
||||
<mimeMap fileExtension=".deploy" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".der" mimeType="application/x-x509-ca-cert" />
|
||||
<mimeMap fileExtension=".dib" mimeType="image/bmp" />
|
||||
<mimeMap fileExtension=".dir" mimeType="application/x-director" />
|
||||
<mimeMap fileExtension=".disco" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".dll" mimeType="application/x-msdownload" />
|
||||
<mimeMap fileExtension=".dll.config" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".dlm" mimeType="text/dlm" />
|
||||
<mimeMap fileExtension=".doc" mimeType="application/msword" />
|
||||
<mimeMap fileExtension=".docm" mimeType="application/vnd.ms-word.document.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".docx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
|
||||
<mimeMap fileExtension=".dot" mimeType="application/msword" />
|
||||
<mimeMap fileExtension=".dotm" mimeType="application/vnd.ms-word.template.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".dotx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" />
|
||||
<mimeMap fileExtension=".dsp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".dtd" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".dvi" mimeType="application/x-dvi" />
|
||||
<mimeMap fileExtension=".dvr-ms" mimeType="video/x-ms-dvr" />
|
||||
<mimeMap fileExtension=".dwf" mimeType="drawing/x-dwf" />
|
||||
<mimeMap fileExtension=".dwp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".dxr" mimeType="application/x-director" />
|
||||
<mimeMap fileExtension=".eml" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".emz" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
|
||||
<mimeMap fileExtension=".eps" mimeType="application/postscript" />
|
||||
<mimeMap fileExtension=".etx" mimeType="text/x-setext" />
|
||||
<mimeMap fileExtension=".evy" mimeType="application/envoy" />
|
||||
<mimeMap fileExtension=".exe" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".exe.config" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".fdf" mimeType="application/vnd.fdf" />
|
||||
<mimeMap fileExtension=".fif" mimeType="application/fractals" />
|
||||
<mimeMap fileExtension=".fla" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".flr" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".flv" mimeType="video/x-flv" />
|
||||
<mimeMap fileExtension=".gif" mimeType="image/gif" />
|
||||
<mimeMap fileExtension=".gtar" mimeType="application/x-gtar" />
|
||||
<mimeMap fileExtension=".gz" mimeType="application/x-gzip" />
|
||||
<mimeMap fileExtension=".h" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".hdf" mimeType="application/x-hdf" />
|
||||
<mimeMap fileExtension=".hdml" mimeType="text/x-hdml" />
|
||||
<mimeMap fileExtension=".hhc" mimeType="application/x-oleobject" />
|
||||
<mimeMap fileExtension=".hhk" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".hhp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".hlp" mimeType="application/winhlp" />
|
||||
<mimeMap fileExtension=".hqx" mimeType="application/mac-binhex40" />
|
||||
<mimeMap fileExtension=".hta" mimeType="application/hta" />
|
||||
<mimeMap fileExtension=".htc" mimeType="text/x-component" />
|
||||
<mimeMap fileExtension=".htm" mimeType="text/html" />
|
||||
<mimeMap fileExtension=".html" mimeType="text/html" />
|
||||
<mimeMap fileExtension=".htt" mimeType="text/webviewhtml" />
|
||||
<mimeMap fileExtension=".hxt" mimeType="text/html" />
|
||||
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
|
||||
<mimeMap fileExtension=".ics" mimeType="text/calendar" />
|
||||
<mimeMap fileExtension=".ief" mimeType="image/ief" />
|
||||
<mimeMap fileExtension=".iii" mimeType="application/x-iphone" />
|
||||
<mimeMap fileExtension=".inf" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ins" mimeType="application/x-internet-signup" />
|
||||
<mimeMap fileExtension=".isp" mimeType="application/x-internet-signup" />
|
||||
<mimeMap fileExtension=".IVF" mimeType="video/x-ivf" />
|
||||
<mimeMap fileExtension=".jar" mimeType="application/java-archive" />
|
||||
<mimeMap fileExtension=".java" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".jck" mimeType="application/liquidmotion" />
|
||||
<mimeMap fileExtension=".jcz" mimeType="application/liquidmotion" />
|
||||
<mimeMap fileExtension=".jfif" mimeType="image/pjpeg" />
|
||||
<mimeMap fileExtension=".jpb" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".jpe" mimeType="image/jpeg" />
|
||||
<mimeMap fileExtension=".jpeg" mimeType="image/jpeg" />
|
||||
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
|
||||
<mimeMap fileExtension=".js" mimeType="application/javascript" />
|
||||
<mimeMap fileExtension=".json" mimeType="application/json" />
|
||||
<mimeMap fileExtension=".jsonld" mimeType="application/ld+json" />
|
||||
<mimeMap fileExtension=".jsx" mimeType="text/jscript" />
|
||||
<mimeMap fileExtension=".latex" mimeType="application/x-latex" />
|
||||
<mimeMap fileExtension=".less" mimeType="text/css" />
|
||||
<mimeMap fileExtension=".lit" mimeType="application/x-ms-reader" />
|
||||
<mimeMap fileExtension=".lpk" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".lsf" mimeType="video/x-la-asf" />
|
||||
<mimeMap fileExtension=".lsx" mimeType="video/x-la-asf" />
|
||||
<mimeMap fileExtension=".lzh" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".m13" mimeType="application/x-msmediaview" />
|
||||
<mimeMap fileExtension=".m14" mimeType="application/x-msmediaview" />
|
||||
<mimeMap fileExtension=".m1v" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".m2ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||
<mimeMap fileExtension=".m3u" mimeType="audio/x-mpegurl" />
|
||||
<mimeMap fileExtension=".m4a" mimeType="audio/mp4" />
|
||||
<mimeMap fileExtension=".m4v" mimeType="video/mp4" />
|
||||
<mimeMap fileExtension=".man" mimeType="application/x-troff-man" />
|
||||
<mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest" />
|
||||
<mimeMap fileExtension=".map" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".mdb" mimeType="application/x-msaccess" />
|
||||
<mimeMap fileExtension=".mdp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".me" mimeType="application/x-troff-me" />
|
||||
<mimeMap fileExtension=".mht" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".mhtml" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".mid" mimeType="audio/mid" />
|
||||
<mimeMap fileExtension=".midi" mimeType="audio/mid" />
|
||||
<mimeMap fileExtension=".mix" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".mmf" mimeType="application/x-smaf" />
|
||||
<mimeMap fileExtension=".mno" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".mny" mimeType="application/x-msmoney" />
|
||||
<mimeMap fileExtension=".mov" mimeType="video/quicktime" />
|
||||
<mimeMap fileExtension=".movie" mimeType="video/x-sgi-movie" />
|
||||
<mimeMap fileExtension=".mp2" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg" />
|
||||
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
|
||||
<mimeMap fileExtension=".mp4v" mimeType="video/mp4" />
|
||||
<mimeMap fileExtension=".mpa" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpe" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpeg" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpg" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpp" mimeType="application/vnd.ms-project" />
|
||||
<mimeMap fileExtension=".mpv2" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".ms" mimeType="application/x-troff-ms" />
|
||||
<mimeMap fileExtension=".msi" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".mso" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".mvb" mimeType="application/x-msmediaview" />
|
||||
<mimeMap fileExtension=".mvc" mimeType="application/x-miva-compiled" />
|
||||
<mimeMap fileExtension=".nc" mimeType="application/x-netcdf" />
|
||||
<mimeMap fileExtension=".nsc" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".nws" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".ocx" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".oda" mimeType="application/oda" />
|
||||
<mimeMap fileExtension=".odc" mimeType="text/x-ms-odc" />
|
||||
<mimeMap fileExtension=".ods" mimeType="application/oleobject" />
|
||||
<mimeMap fileExtension=".oga" mimeType="audio/ogg" />
|
||||
<mimeMap fileExtension=".ogg" mimeType="video/ogg" />
|
||||
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
|
||||
<mimeMap fileExtension=".one" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onea" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onetoc" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onetoc2" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onetmp" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onepkg" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".osdx" mimeType="application/opensearchdescription+xml" />
|
||||
<mimeMap fileExtension=".otf" mimeType="font/otf" />
|
||||
<mimeMap fileExtension=".p10" mimeType="application/pkcs10" />
|
||||
<mimeMap fileExtension=".p12" mimeType="application/x-pkcs12" />
|
||||
<mimeMap fileExtension=".p7b" mimeType="application/x-pkcs7-certificates" />
|
||||
<mimeMap fileExtension=".p7c" mimeType="application/pkcs7-mime" />
|
||||
<mimeMap fileExtension=".p7m" mimeType="application/pkcs7-mime" />
|
||||
<mimeMap fileExtension=".p7r" mimeType="application/x-pkcs7-certreqresp" />
|
||||
<mimeMap fileExtension=".p7s" mimeType="application/pkcs7-signature" />
|
||||
<mimeMap fileExtension=".pbm" mimeType="image/x-portable-bitmap" />
|
||||
<mimeMap fileExtension=".pcx" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pcz" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pdf" mimeType="application/pdf" />
|
||||
<mimeMap fileExtension=".pfb" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pfm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pfx" mimeType="application/x-pkcs12" />
|
||||
<mimeMap fileExtension=".pgm" mimeType="image/x-portable-graymap" />
|
||||
<mimeMap fileExtension=".pko" mimeType="application/vnd.ms-pki.pko" />
|
||||
<mimeMap fileExtension=".pma" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pmc" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pml" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pmr" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pmw" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".png" mimeType="image/png" />
|
||||
<mimeMap fileExtension=".pnm" mimeType="image/x-portable-anymap" />
|
||||
<mimeMap fileExtension=".pnz" mimeType="image/png" />
|
||||
<mimeMap fileExtension=".pot" mimeType="application/vnd.ms-powerpoint" />
|
||||
<mimeMap fileExtension=".potm" mimeType="application/vnd.ms-powerpoint.template.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".potx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" />
|
||||
<mimeMap fileExtension=".ppam" mimeType="application/vnd.ms-powerpoint.addin.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".ppm" mimeType="image/x-portable-pixmap" />
|
||||
<mimeMap fileExtension=".pps" mimeType="application/vnd.ms-powerpoint" />
|
||||
<mimeMap fileExtension=".ppsm" mimeType="application/vnd.ms-powerpoint.slideshow.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".ppsx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
|
||||
<mimeMap fileExtension=".ppt" mimeType="application/vnd.ms-powerpoint" />
|
||||
<mimeMap fileExtension=".pptm" mimeType="application/vnd.ms-powerpoint.presentation.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".pptx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
|
||||
<mimeMap fileExtension=".prf" mimeType="application/pics-rules" />
|
||||
<mimeMap fileExtension=".prm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".prx" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ps" mimeType="application/postscript" />
|
||||
<mimeMap fileExtension=".psd" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".psm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".psp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pub" mimeType="application/x-mspublisher" />
|
||||
<mimeMap fileExtension=".qt" mimeType="video/quicktime" />
|
||||
<mimeMap fileExtension=".qtl" mimeType="application/x-quicktimeplayer" />
|
||||
<mimeMap fileExtension=".qxd" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ra" mimeType="audio/x-pn-realaudio" />
|
||||
<mimeMap fileExtension=".ram" mimeType="audio/x-pn-realaudio" />
|
||||
<mimeMap fileExtension=".rar" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ras" mimeType="image/x-cmu-raster" />
|
||||
<mimeMap fileExtension=".rf" mimeType="image/vnd.rn-realflash" />
|
||||
<mimeMap fileExtension=".rgb" mimeType="image/x-rgb" />
|
||||
<mimeMap fileExtension=".rm" mimeType="application/vnd.rn-realmedia" />
|
||||
<mimeMap fileExtension=".rmi" mimeType="audio/mid" />
|
||||
<mimeMap fileExtension=".roff" mimeType="application/x-troff" />
|
||||
<mimeMap fileExtension=".rpm" mimeType="audio/x-pn-realaudio-plugin" />
|
||||
<mimeMap fileExtension=".rtf" mimeType="application/rtf" />
|
||||
<mimeMap fileExtension=".rtx" mimeType="text/richtext" />
|
||||
<mimeMap fileExtension=".scd" mimeType="application/x-msschedule" />
|
||||
<mimeMap fileExtension=".sct" mimeType="text/scriptlet" />
|
||||
<mimeMap fileExtension=".sea" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".setpay" mimeType="application/set-payment-initiation" />
|
||||
<mimeMap fileExtension=".setreg" mimeType="application/set-registration-initiation" />
|
||||
<mimeMap fileExtension=".sgml" mimeType="text/sgml" />
|
||||
<mimeMap fileExtension=".sh" mimeType="application/x-sh" />
|
||||
<mimeMap fileExtension=".shar" mimeType="application/x-shar" />
|
||||
<mimeMap fileExtension=".sit" mimeType="application/x-stuffit" />
|
||||
<mimeMap fileExtension=".sldm" mimeType="application/vnd.ms-powerpoint.slide.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".sldx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slide" />
|
||||
<mimeMap fileExtension=".smd" mimeType="audio/x-smd" />
|
||||
<mimeMap fileExtension=".smi" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".smx" mimeType="audio/x-smd" />
|
||||
<mimeMap fileExtension=".smz" mimeType="audio/x-smd" />
|
||||
<mimeMap fileExtension=".snd" mimeType="audio/basic" />
|
||||
<mimeMap fileExtension=".snp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".spc" mimeType="application/x-pkcs7-certificates" />
|
||||
<mimeMap fileExtension=".spl" mimeType="application/futuresplash" />
|
||||
<mimeMap fileExtension=".spx" mimeType="audio/ogg" />
|
||||
<mimeMap fileExtension=".src" mimeType="application/x-wais-source" />
|
||||
<mimeMap fileExtension=".ssm" mimeType="application/streamingmedia" />
|
||||
<mimeMap fileExtension=".sst" mimeType="application/vnd.ms-pki.certstore" />
|
||||
<mimeMap fileExtension=".stl" mimeType="application/vnd.ms-pki.stl" />
|
||||
<mimeMap fileExtension=".sv4cpio" mimeType="application/x-sv4cpio" />
|
||||
<mimeMap fileExtension=".sv4crc" mimeType="application/x-sv4crc" />
|
||||
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
|
||||
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
|
||||
<mimeMap fileExtension=".swf" mimeType="application/x-shockwave-flash" />
|
||||
<mimeMap fileExtension=".t" mimeType="application/x-troff" />
|
||||
<mimeMap fileExtension=".tar" mimeType="application/x-tar" />
|
||||
<mimeMap fileExtension=".tcl" mimeType="application/x-tcl" />
|
||||
<mimeMap fileExtension=".tex" mimeType="application/x-tex" />
|
||||
<mimeMap fileExtension=".texi" mimeType="application/x-texinfo" />
|
||||
<mimeMap fileExtension=".texinfo" mimeType="application/x-texinfo" />
|
||||
<mimeMap fileExtension=".tgz" mimeType="application/x-compressed" />
|
||||
<mimeMap fileExtension=".thmx" mimeType="application/vnd.ms-officetheme" />
|
||||
<mimeMap fileExtension=".thn" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".tif" mimeType="image/tiff" />
|
||||
<mimeMap fileExtension=".tiff" mimeType="image/tiff" />
|
||||
<mimeMap fileExtension=".toc" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".tr" mimeType="application/x-troff" />
|
||||
<mimeMap fileExtension=".trm" mimeType="application/x-msterminal" />
|
||||
<mimeMap fileExtension=".ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||
<mimeMap fileExtension=".tsv" mimeType="text/tab-separated-values" />
|
||||
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".tts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||
<mimeMap fileExtension=".txt" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".u32" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".uls" mimeType="text/iuls" />
|
||||
<mimeMap fileExtension=".ustar" mimeType="application/x-ustar" />
|
||||
<mimeMap fileExtension=".vbs" mimeType="text/vbscript" />
|
||||
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard" />
|
||||
<mimeMap fileExtension=".vcs" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".vdx" mimeType="application/vnd.ms-visio.viewer" />
|
||||
<mimeMap fileExtension=".vml" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".vsd" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vss" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vst" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vsto" mimeType="application/x-ms-vsto" />
|
||||
<mimeMap fileExtension=".vsw" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vsx" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vtx" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".wav" mimeType="audio/wav" />
|
||||
<mimeMap fileExtension=".wax" mimeType="audio/x-ms-wax" />
|
||||
<mimeMap fileExtension=".wbmp" mimeType="image/vnd.wap.wbmp" />
|
||||
<mimeMap fileExtension=".wcm" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".wdb" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".webm" mimeType="video/webm" />
|
||||
<mimeMap fileExtension=".wks" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".wm" mimeType="video/x-ms-wm" />
|
||||
<mimeMap fileExtension=".wma" mimeType="audio/x-ms-wma" />
|
||||
<mimeMap fileExtension=".wmd" mimeType="application/x-ms-wmd" />
|
||||
<mimeMap fileExtension=".wmf" mimeType="application/x-msmetafile" />
|
||||
<mimeMap fileExtension=".wml" mimeType="text/vnd.wap.wml" />
|
||||
<mimeMap fileExtension=".wmlc" mimeType="application/vnd.wap.wmlc" />
|
||||
<mimeMap fileExtension=".wmls" mimeType="text/vnd.wap.wmlscript" />
|
||||
<mimeMap fileExtension=".wmlsc" mimeType="application/vnd.wap.wmlscriptc" />
|
||||
<mimeMap fileExtension=".wmp" mimeType="video/x-ms-wmp" />
|
||||
<mimeMap fileExtension=".wmv" mimeType="video/x-ms-wmv" />
|
||||
<mimeMap fileExtension=".wmx" mimeType="video/x-ms-wmx" />
|
||||
<mimeMap fileExtension=".wmz" mimeType="application/x-ms-wmz" />
|
||||
<mimeMap fileExtension=".woff" mimeType="font/x-woff" />
|
||||
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
|
||||
<mimeMap fileExtension=".wps" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".wri" mimeType="application/x-mswrite" />
|
||||
<mimeMap fileExtension=".wrl" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".wrz" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".wsdl" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".wtv" mimeType="video/x-ms-wtv" />
|
||||
<mimeMap fileExtension=".wvx" mimeType="video/x-ms-wvx" />
|
||||
<mimeMap fileExtension=".x" mimeType="application/directx" />
|
||||
<mimeMap fileExtension=".xaf" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".xaml" mimeType="application/xaml+xml" />
|
||||
<mimeMap fileExtension=".xap" mimeType="application/x-silverlight-app" />
|
||||
<mimeMap fileExtension=".xbap" mimeType="application/x-ms-xbap" />
|
||||
<mimeMap fileExtension=".xbm" mimeType="image/x-xbitmap" />
|
||||
<mimeMap fileExtension=".xdr" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".xht" mimeType="application/xhtml+xml" />
|
||||
<mimeMap fileExtension=".xhtml" mimeType="application/xhtml+xml" />
|
||||
<mimeMap fileExtension=".xla" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xlam" mimeType="application/vnd.ms-excel.addin.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xlc" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xlm" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xls" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xlsb" mimeType="application/vnd.ms-excel.sheet.binary.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xlsm" mimeType="application/vnd.ms-excel.sheet.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xlsx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
|
||||
<mimeMap fileExtension=".xlt" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xltm" mimeType="application/vnd.ms-excel.template.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xltx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" />
|
||||
<mimeMap fileExtension=".xlw" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xml" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xof" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".xpm" mimeType="image/x-xpixmap" />
|
||||
<mimeMap fileExtension=".xps" mimeType="application/vnd.ms-xpsdocument" />
|
||||
<mimeMap fileExtension=".xsd" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xsf" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xsl" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xslt" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xsn" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".xtp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".xwd" mimeType="image/x-xwindowdump" />
|
||||
<mimeMap fileExtension=".z" mimeType="application/x-compress" />
|
||||
<mimeMap fileExtension=".zip" mimeType="application/x-zip-compressed" />
|
||||
</staticContent>
|
||||
<tracing>
|
||||
<traceProviderDefinitions>
|
||||
<add name="WWW Server" guid="{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}">
|
||||
<areas>
|
||||
<clear />
|
||||
<add name="Authentication" value="2" />
|
||||
<add name="Security" value="4" />
|
||||
<add name="Filter" value="8" />
|
||||
<add name="StaticFile" value="16" />
|
||||
<add name="CGI" value="32" />
|
||||
<add name="Compression" value="64" />
|
||||
<add name="Cache" value="128" />
|
||||
<add name="RequestNotifications" value="256" />
|
||||
<add name="Module" value="512" />
|
||||
<add name="Rewrite" value="1024" />
|
||||
<add name="FastCGI" value="4096" />
|
||||
<add name="WebSocket" value="16384" />
|
||||
</areas>
|
||||
</add>
|
||||
<add name="ASP" guid="{06b94d9a-b15e-456e-a4ef-37c984a2cb4b}">
|
||||
<areas>
|
||||
<clear />
|
||||
</areas>
|
||||
</add>
|
||||
<add name="ISAPI Extension" guid="{a1c2040e-8840-4c31-ba11-9871031a19ea}">
|
||||
<areas>
|
||||
<clear />
|
||||
</areas>
|
||||
</add>
|
||||
<add name="ASPNET" guid="{AFF081FE-0247-4275-9C4E-021F3DC1DA35}">
|
||||
<areas>
|
||||
<add name="Infrastructure" value="1" />
|
||||
<add name="Module" value="2" />
|
||||
<add name="Page" value="4" />
|
||||
<add name="AppServices" value="8" />
|
||||
</areas>
|
||||
</add>
|
||||
</traceProviderDefinitions>
|
||||
<traceFailedRequests>
|
||||
<add path="*">
|
||||
<traceAreas>
|
||||
<add provider="ASP" verbosity="Verbose" />
|
||||
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
|
||||
<add provider="ISAPI Extension" verbosity="Verbose" />
|
||||
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,Rewrite,WebSocket" verbosity="Verbose" />
|
||||
</traceAreas>
|
||||
<failureDefinitions statusCodes="200-999" />
|
||||
</add>
|
||||
</traceFailedRequests>
|
||||
</tracing>
|
||||
<urlCompression />
|
||||
<validation />
|
||||
<webdav>
|
||||
<globalSettings>
|
||||
<propertyStores>
|
||||
<add name="webdav_simple_prop" image="%IIS_BIN%\webdav_simple_prop.dll" image32="%IIS_BIN%\webdav_simple_prop.dll" />
|
||||
</propertyStores>
|
||||
<lockStores>
|
||||
<add name="webdav_simple_lock" image="%IIS_BIN%\webdav_simple_lock.dll" image32="%IIS_BIN%\webdav_simple_lock.dll" />
|
||||
</lockStores>
|
||||
</globalSettings>
|
||||
<authoring>
|
||||
<locks enabled="true" lockStore="webdav_simple_lock" />
|
||||
</authoring>
|
||||
<authoringRules />
|
||||
</webdav>
|
||||
<webSocket />
|
||||
<applicationInitialization />
|
||||
</system.webServer>
|
||||
<location path="" overrideMode="Allow">
|
||||
<system.webServer>
|
||||
<modules>
|
||||
<add name="IsapiFilterModule" lockItem="true" />
|
||||
<add name="BasicAuthenticationModule" lockItem="true" />
|
||||
<add name="IsapiModule" lockItem="true" />
|
||||
<add name="HttpLoggingModule" lockItem="true" />
|
||||
<!--
|
||||
<add name="HttpCacheModule" lockItem="true" />
|
||||
-->
|
||||
<add name="DynamicCompressionModule" lockItem="true" />
|
||||
<add name="StaticCompressionModule" lockItem="true" />
|
||||
<add name="DefaultDocumentModule" lockItem="true" />
|
||||
<add name="DirectoryListingModule" lockItem="true" />
|
||||
<add name="ProtocolSupportModule" lockItem="true" />
|
||||
<add name="HttpRedirectionModule" lockItem="true" />
|
||||
<add name="ServerSideIncludeModule" lockItem="true" />
|
||||
<add name="StaticFileModule" lockItem="true" />
|
||||
<add name="AnonymousAuthenticationModule" lockItem="true" />
|
||||
<add name="CertificateMappingAuthenticationModule" lockItem="true" />
|
||||
<add name="UrlAuthorizationModule" lockItem="true" />
|
||||
<add name="WindowsAuthenticationModule" lockItem="true" />
|
||||
<!--
|
||||
<add name="DigestAuthenticationModule" lockItem="true" />
|
||||
-->
|
||||
<add name="IISCertificateMappingAuthenticationModule" lockItem="true" />
|
||||
<add name="WebMatrixSupportModule" lockItem="true" />
|
||||
<add name="IpRestrictionModule" lockItem="true" />
|
||||
<add name="DynamicIpRestrictionModule" lockItem="true" />
|
||||
<add name="RequestFilteringModule" lockItem="true" />
|
||||
<add name="CustomLoggingModule" lockItem="true" />
|
||||
<add name="CustomErrorModule" lockItem="true" />
|
||||
<add name="FailedRequestsTracingModule" lockItem="true" />
|
||||
<add name="CgiModule" lockItem="true" />
|
||||
<add name="FastCgiModule" lockItem="true" />
|
||||
<!-- <add name="WebDAVModule" /> -->
|
||||
<add name="RewriteModule" />
|
||||
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" preCondition="managedHandler" />
|
||||
<add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition="managedHandler" />
|
||||
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" preCondition="managedHandler" />
|
||||
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" />
|
||||
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="managedHandler" />
|
||||
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" preCondition="managedHandler" />
|
||||
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
|
||||
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" preCondition="managedHandler" />
|
||||
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" preCondition="managedHandler" />
|
||||
<add name="Profile" type="System.Web.Profile.ProfileModule" preCondition="managedHandler" />
|
||||
<add name="UrlMappingsModule" type="System.Web.UrlMappingsModule" preCondition="managedHandler" />
|
||||
<add name="ApplicationInitializationModule" lockItem="true" />
|
||||
<add name="WebSocketModule" lockItem="true" />
|
||||
<add name="ServiceModel-4.0" type="System.ServiceModel.Activation.ServiceHttpModule,System.ServiceModel.Activation,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ConfigurationValidationModule" lockItem="true" />
|
||||
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||
<add name="AspNetCoreModule" lockItem="true" />
|
||||
</modules>
|
||||
<handlers accessPolicy="Read, Script">
|
||||
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
|
||||
<add name="AXD-ISAPI-4.0_64bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="SimpleHandlerFactory-ISAPI-4.0_64bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="WebServiceHandlerFactory-ISAPI-4.0_64bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_64bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_64bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||
<add name="aspq-ISAPI-4.0_64bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="cshtm-ISAPI-4.0_64bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="cshtml-ISAPI-4.0_64bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="vbhtm-ISAPI-4.0_64bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="vbhtml-ISAPI-4.0_64bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="AXD-ISAPI-4.0_32bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="PageHandlerFactory-ISAPI-4.0_32bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="SimpleHandlerFactory-ISAPI-4.0_32bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="WebServiceHandlerFactory-ISAPI-4.0_32bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_32bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_32bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||
<add name="aspq-ISAPI-4.0_32bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="cshtm-ISAPI-4.0_32bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="cshtml-ISAPI-4.0_32bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="vbhtm-ISAPI-4.0_32bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="vbhtml-ISAPI-4.0_32bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="TraceHandler-Integrated-4.0" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="WebAdminHandler-Integrated-4.0" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="AssemblyResourceLoader-Integrated-4.0" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="WebServiceHandlerFactory-Integrated-4.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="HttpRemotingHandlerFactory-rem-Integrated-4.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="HttpRemotingHandlerFactory-soap-Integrated-4.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="aspq-Integrated-4.0" path="*.aspq" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="cshtm-Integrated-4.0" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="cshtml-Integrated-4.0" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="vbhtm-Integrated-4.0" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="vbhtml-Integrated-4.0" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="ScriptHandlerFactoryAppServices-Integrated-4.0" path="*_AppService.axd" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="ScriptResourceIntegrated-4.0" path="*ScriptResource.axd" verb="GET,HEAD" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
|
||||
<add name="SecurityCertificate" path="*.cer" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
|
||||
<add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
|
||||
<add name="TraceHandler-Integrated" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="WebAdminHandler-Integrated" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="AssemblyResourceLoader-Integrated" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="WebServiceHandlerFactory-Integrated" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Services.Protocols.WebServiceHandlerFactory,System.Web.Services,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="HttpRemotingHandlerFactory-rem-Integrated" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="HttpRemotingHandlerFactory-soap-Integrated" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||
<add name="AXD-ISAPI-2.0" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="PageHandlerFactory-ISAPI-2.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="SimpleHandlerFactory-ISAPI-2.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="WebServiceHandlerFactory-ISAPI-2.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="AXD-ISAPI-2.0-64" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="PageHandlerFactory-ISAPI-2.0-64" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="SimpleHandlerFactory-ISAPI-2.0-64" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="WebServiceHandlerFactory-ISAPI-2.0-64" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0-64" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0-64" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
|
||||
<add name="SSINC-stm" path="*.stm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||
<add name="SSINC-shtm" path="*.shtm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||
<add name="SSINC-shtml" path="*.shtml" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||
<add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" />
|
||||
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" />
|
||||
<add name="ExtensionlessUrl-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
|
||||
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</location>
|
||||
<location path="NativeIISSample">
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="false" hostingModel="inprocess"/>
|
||||
<httpCompression>
|
||||
<dynamicCompression>
|
||||
<add mimeType="text/event-stream" enabled="false" />
|
||||
</dynamicCompression>
|
||||
</httpCompression>
|
||||
</system.webServer>
|
||||
</location>
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
// TODO redudant file, remove
|
||||
// See https://github.com/aspnet/IISIntegration/issues/426
|
||||
internal class DuplexStream : Stream
|
||||
{
|
||||
private Stream _requestBody;
|
||||
private Stream _responseBody;
|
||||
|
||||
public DuplexStream(Stream requestBody, Stream responseBody)
|
||||
{
|
||||
_requestBody = requestBody;
|
||||
_responseBody = responseBody;
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => true;
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
_responseBody.Flush();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return _requestBody.Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
_responseBody.Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return _requestBody.ReadAsync(buffer, offset, count, cancellationToken);
|
||||
}
|
||||
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return _responseBody.WriteAsync(buffer, offset, count, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
internal partial class HttpProtocol : IFeatureCollection,
|
||||
IHttpRequestFeature,
|
||||
IHttpResponseFeature,
|
||||
IHttpUpgradeFeature,
|
||||
IHttpConnectionFeature,
|
||||
IHttpRequestLifetimeFeature,
|
||||
IHttpRequestIdentifierFeature
|
||||
{
|
||||
// NOTE: When feature interfaces are added to or removed from this HttpProtocol implementation,
|
||||
// then the list of `implementedFeatures` in the generated code project MUST also be updated.
|
||||
|
||||
private int _featureRevision;
|
||||
private string _httpProtocolVersion = null;
|
||||
|
||||
private List<KeyValuePair<Type, object>> MaybeExtra;
|
||||
public void ResetFeatureCollection()
|
||||
{
|
||||
Initialize();
|
||||
MaybeExtra?.Clear();
|
||||
_featureRevision++;
|
||||
}
|
||||
|
||||
private object ExtraFeatureGet(Type key)
|
||||
{
|
||||
if (MaybeExtra == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (var i = 0; i < MaybeExtra.Count; i++)
|
||||
{
|
||||
var kv = MaybeExtra[i];
|
||||
if (kv.Key == key)
|
||||
{
|
||||
return kv.Value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ExtraFeatureSet(Type key, object value)
|
||||
{
|
||||
if (MaybeExtra == null)
|
||||
{
|
||||
MaybeExtra = new List<KeyValuePair<Type, object>>(2);
|
||||
}
|
||||
|
||||
for (var i = 0; i < MaybeExtra.Count; i++)
|
||||
{
|
||||
if (MaybeExtra[i].Key == key)
|
||||
{
|
||||
MaybeExtra[i] = new KeyValuePair<Type, object>(key, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
MaybeExtra.Add(new KeyValuePair<Type, object>(key, value));
|
||||
}
|
||||
|
||||
string IHttpRequestFeature.Protocol
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_httpProtocolVersion == null)
|
||||
{
|
||||
var protocol = HttpVersion;
|
||||
if (protocol.Major == 1 && protocol.Minor == 1)
|
||||
{
|
||||
_httpProtocolVersion = "HTTP/1.1";
|
||||
}
|
||||
else if (protocol.Major == 1 && protocol.Minor == 0)
|
||||
{
|
||||
_httpProtocolVersion = "HTTP/1.0";
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpProtocolVersion = "HTTP/" + protocol.ToString(2);
|
||||
}
|
||||
}
|
||||
return _httpProtocolVersion;
|
||||
}
|
||||
set
|
||||
{
|
||||
_httpProtocolVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
string IHttpRequestFeature.Scheme
|
||||
{
|
||||
get => Scheme;
|
||||
set => Scheme = value;
|
||||
}
|
||||
|
||||
string IHttpRequestFeature.Method
|
||||
{
|
||||
get => Method;
|
||||
set => Method = value;
|
||||
}
|
||||
|
||||
string IHttpRequestFeature.PathBase
|
||||
{
|
||||
get => PathBase;
|
||||
set => PathBase = value;
|
||||
}
|
||||
|
||||
string IHttpRequestFeature.Path
|
||||
{
|
||||
get => Path;
|
||||
set => Path = value;
|
||||
}
|
||||
|
||||
string IHttpRequestFeature.QueryString
|
||||
{
|
||||
get => QueryString;
|
||||
set => QueryString = value;
|
||||
}
|
||||
|
||||
string IHttpRequestFeature.RawTarget
|
||||
{
|
||||
get => RawTarget;
|
||||
set => RawTarget = value;
|
||||
}
|
||||
|
||||
IHeaderDictionary IHttpRequestFeature.Headers
|
||||
{
|
||||
get => RequestHeaders;
|
||||
set => RequestHeaders = value;
|
||||
}
|
||||
|
||||
Stream IHttpRequestFeature.Body
|
||||
{
|
||||
get => RequestBody;
|
||||
set => RequestBody = value;
|
||||
}
|
||||
|
||||
int IHttpResponseFeature.StatusCode
|
||||
{
|
||||
get => StatusCode;
|
||||
set => StatusCode = value;
|
||||
}
|
||||
|
||||
string IHttpResponseFeature.ReasonPhrase
|
||||
{
|
||||
get => ReasonPhrase;
|
||||
set => ReasonPhrase = value;
|
||||
}
|
||||
|
||||
IHeaderDictionary IHttpResponseFeature.Headers
|
||||
{
|
||||
get => ResponseHeaders;
|
||||
set => ResponseHeaders = value;
|
||||
}
|
||||
|
||||
Stream IHttpResponseFeature.Body
|
||||
{
|
||||
get => ResponseBody;
|
||||
set => ResponseBody = value;
|
||||
}
|
||||
|
||||
CancellationToken IHttpRequestLifetimeFeature.RequestAborted
|
||||
{
|
||||
get => RequestAborted;
|
||||
set => RequestAborted = value;
|
||||
}
|
||||
|
||||
bool IHttpResponseFeature.HasStarted => HasResponseStarted;
|
||||
|
||||
bool IHttpUpgradeFeature.IsUpgradableRequest => UpgradeAvailable;
|
||||
|
||||
bool IFeatureCollection.IsReadOnly => false;
|
||||
|
||||
int IFeatureCollection.Revision => _featureRevision;
|
||||
|
||||
IPAddress IHttpConnectionFeature.RemoteIpAddress
|
||||
{
|
||||
get => RemoteIpAddress;
|
||||
set => RemoteIpAddress = value;
|
||||
}
|
||||
|
||||
IPAddress IHttpConnectionFeature.LocalIpAddress
|
||||
{
|
||||
get => LocalIpAddress;
|
||||
set => LocalIpAddress = value;
|
||||
}
|
||||
|
||||
int IHttpConnectionFeature.RemotePort
|
||||
{
|
||||
get => RemotePort;
|
||||
set => RemotePort = value;
|
||||
}
|
||||
|
||||
int IHttpConnectionFeature.LocalPort
|
||||
{
|
||||
get => LocalPort;
|
||||
set => LocalPort = value;
|
||||
}
|
||||
|
||||
string IHttpConnectionFeature.ConnectionId
|
||||
{
|
||||
get => RequestConnectionId;
|
||||
set => RequestConnectionId = value;
|
||||
}
|
||||
|
||||
string IHttpRequestIdentifierFeature.TraceIdentifier
|
||||
{
|
||||
get => TraceIdentifier;
|
||||
set => TraceIdentifier = value;
|
||||
}
|
||||
|
||||
object IFeatureCollection.this[Type key]
|
||||
{
|
||||
get => FastFeatureGet(key);
|
||||
set => FastFeatureSet(key, value);
|
||||
}
|
||||
|
||||
TFeature IFeatureCollection.Get<TFeature>()
|
||||
{
|
||||
return (TFeature)FastFeatureGet(typeof(TFeature));
|
||||
}
|
||||
|
||||
void IFeatureCollection.Set<TFeature>(TFeature instance)
|
||||
{
|
||||
FastFeatureSet(typeof(TFeature), instance);
|
||||
}
|
||||
|
||||
void IHttpResponseFeature.OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
OnStarting(callback, state);
|
||||
}
|
||||
|
||||
void IHttpResponseFeature.OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
OnCompleted(callback, state);
|
||||
}
|
||||
|
||||
async Task<Stream> IHttpUpgradeFeature.UpgradeAsync()
|
||||
{
|
||||
// TODO fix these exceptions strings
|
||||
if (!((IHttpUpgradeFeature)this).IsUpgradableRequest)
|
||||
{
|
||||
throw new InvalidOperationException("CoreStrings.CannotUpgradeNonUpgradableRequest");
|
||||
}
|
||||
|
||||
if (_wasUpgraded)
|
||||
{
|
||||
throw new InvalidOperationException("CoreStrings.UpgradeCannotBeCalledMultipleTimes");
|
||||
}
|
||||
if (HasResponseStarted)
|
||||
{
|
||||
throw new InvalidOperationException("CoreStrings.UpgradeCannotBeCalledMultipleTimes");
|
||||
}
|
||||
|
||||
_wasUpgraded = true;
|
||||
|
||||
StatusCode = StatusCodes.Status101SwitchingProtocols;
|
||||
ReasonPhrase = ReasonPhrases.GetReasonPhrase(StatusCodes.Status101SwitchingProtocols);
|
||||
await UpgradeAsync();
|
||||
|
||||
return new DuplexStream(RequestBody, ResponseBody);
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<Type, object>> IEnumerable<KeyValuePair<Type, object>>.GetEnumerator() => FastEnumerable().GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => FastEnumerable().GetEnumerator();
|
||||
|
||||
void IHttpRequestLifetimeFeature.Abort()
|
||||
{
|
||||
Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
internal partial class HttpProtocol
|
||||
{
|
||||
private static readonly Type IHttpRequestFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpRequestFeature);
|
||||
private static readonly Type IHttpResponseFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpResponseFeature);
|
||||
private static readonly Type IHttpRequestIdentifierFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature);
|
||||
private static readonly Type IServiceProvidersFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature);
|
||||
private static readonly Type IHttpRequestLifetimeFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature);
|
||||
private static readonly Type IHttpConnectionFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature);
|
||||
private static readonly Type IHttpAuthenticationFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature);
|
||||
private static readonly Type IQueryFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IQueryFeature);
|
||||
private static readonly Type IFormFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IFormFeature);
|
||||
private static readonly Type IHttpUpgradeFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature);
|
||||
private static readonly Type IResponseCookiesFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IResponseCookiesFeature);
|
||||
private static readonly Type IItemsFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IItemsFeature);
|
||||
private static readonly Type ITlsConnectionFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature);
|
||||
private static readonly Type IHttpWebSocketFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature);
|
||||
private static readonly Type ISessionFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.ISessionFeature);
|
||||
private static readonly Type IHttpBodyControlFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature);
|
||||
private static readonly Type IHttpSendFileFeatureType = typeof(global::Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature);
|
||||
|
||||
private object _currentIHttpRequestFeature;
|
||||
private object _currentIHttpResponseFeature;
|
||||
private object _currentIHttpRequestIdentifierFeature;
|
||||
private object _currentIServiceProvidersFeature;
|
||||
private object _currentIHttpRequestLifetimeFeature;
|
||||
private object _currentIHttpConnectionFeature;
|
||||
private object _currentIHttpAuthenticationFeature;
|
||||
private object _currentIQueryFeature;
|
||||
private object _currentIFormFeature;
|
||||
private object _currentIHttpUpgradeFeature;
|
||||
private object _currentIResponseCookiesFeature;
|
||||
private object _currentIItemsFeature;
|
||||
private object _currentITlsConnectionFeature;
|
||||
private object _currentIHttpMaxRequestBodySizeFeature;
|
||||
private object _currentIHttpMinRequestBodyDataRateFeature;
|
||||
private object _currentIHttpMinResponseDataRateFeature;
|
||||
private object _currentIHttpWebSocketFeature;
|
||||
private object _currentISessionFeature;
|
||||
private object _currentIHttpBodyControlFeature;
|
||||
private object _currentIHttpSendFileFeature;
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
_currentIHttpRequestFeature = this;
|
||||
_currentIHttpResponseFeature = this;
|
||||
_currentIHttpUpgradeFeature = this;
|
||||
_currentIHttpRequestIdentifierFeature = this;
|
||||
_currentIHttpRequestLifetimeFeature = this;
|
||||
_currentIHttpConnectionFeature = this;
|
||||
_currentIHttpMaxRequestBodySizeFeature = this;
|
||||
_currentIHttpMinRequestBodyDataRateFeature = this;
|
||||
_currentIHttpMinResponseDataRateFeature = this;
|
||||
_currentIHttpBodyControlFeature = this;
|
||||
}
|
||||
|
||||
internal object FastFeatureGet(Type key)
|
||||
{
|
||||
if (key == IHttpRequestFeatureType)
|
||||
{
|
||||
return _currentIHttpRequestFeature;
|
||||
}
|
||||
if (key == IHttpResponseFeatureType)
|
||||
{
|
||||
return _currentIHttpResponseFeature;
|
||||
}
|
||||
if (key == IHttpRequestIdentifierFeatureType)
|
||||
{
|
||||
return _currentIHttpRequestIdentifierFeature;
|
||||
}
|
||||
if (key == IServiceProvidersFeatureType)
|
||||
{
|
||||
return _currentIServiceProvidersFeature;
|
||||
}
|
||||
if (key == IHttpRequestLifetimeFeatureType)
|
||||
{
|
||||
return _currentIHttpRequestLifetimeFeature;
|
||||
}
|
||||
if (key == IHttpConnectionFeatureType)
|
||||
{
|
||||
return _currentIHttpConnectionFeature;
|
||||
}
|
||||
if (key == IHttpAuthenticationFeatureType)
|
||||
{
|
||||
return _currentIHttpAuthenticationFeature;
|
||||
}
|
||||
if (key == IQueryFeatureType)
|
||||
{
|
||||
return _currentIQueryFeature;
|
||||
}
|
||||
if (key == IFormFeatureType)
|
||||
{
|
||||
return _currentIFormFeature;
|
||||
}
|
||||
if (key == IHttpUpgradeFeatureType)
|
||||
{
|
||||
return _currentIHttpUpgradeFeature;
|
||||
}
|
||||
if (key == IResponseCookiesFeatureType)
|
||||
{
|
||||
return _currentIResponseCookiesFeature;
|
||||
}
|
||||
if (key == IItemsFeatureType)
|
||||
{
|
||||
return _currentIItemsFeature;
|
||||
}
|
||||
if (key == ITlsConnectionFeatureType)
|
||||
{
|
||||
return _currentITlsConnectionFeature;
|
||||
}
|
||||
if (key == IHttpWebSocketFeatureType)
|
||||
{
|
||||
return _currentIHttpWebSocketFeature;
|
||||
}
|
||||
if (key == ISessionFeatureType)
|
||||
{
|
||||
return _currentISessionFeature;
|
||||
}
|
||||
if (key == IHttpBodyControlFeatureType)
|
||||
{
|
||||
return _currentIHttpBodyControlFeature;
|
||||
}
|
||||
if (key == IHttpSendFileFeatureType)
|
||||
{
|
||||
return _currentIHttpSendFileFeature;
|
||||
}
|
||||
return ExtraFeatureGet(key);
|
||||
}
|
||||
|
||||
internal void FastFeatureSet(Type key, object feature)
|
||||
{
|
||||
_featureRevision++;
|
||||
|
||||
if (key == IHttpRequestFeatureType)
|
||||
{
|
||||
_currentIHttpRequestFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpResponseFeatureType)
|
||||
{
|
||||
_currentIHttpResponseFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpRequestIdentifierFeatureType)
|
||||
{
|
||||
_currentIHttpRequestIdentifierFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IServiceProvidersFeatureType)
|
||||
{
|
||||
_currentIServiceProvidersFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpRequestLifetimeFeatureType)
|
||||
{
|
||||
_currentIHttpRequestLifetimeFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpConnectionFeatureType)
|
||||
{
|
||||
_currentIHttpConnectionFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpAuthenticationFeatureType)
|
||||
{
|
||||
_currentIHttpAuthenticationFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IQueryFeatureType)
|
||||
{
|
||||
_currentIQueryFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IFormFeatureType)
|
||||
{
|
||||
_currentIFormFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpUpgradeFeatureType)
|
||||
{
|
||||
_currentIHttpUpgradeFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IResponseCookiesFeatureType)
|
||||
{
|
||||
_currentIResponseCookiesFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IItemsFeatureType)
|
||||
{
|
||||
_currentIItemsFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == ITlsConnectionFeatureType)
|
||||
{
|
||||
_currentITlsConnectionFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpWebSocketFeatureType)
|
||||
{
|
||||
_currentIHttpWebSocketFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == ISessionFeatureType)
|
||||
{
|
||||
_currentISessionFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpBodyControlFeatureType)
|
||||
{
|
||||
_currentIHttpBodyControlFeature = feature;
|
||||
return;
|
||||
}
|
||||
if (key == IHttpSendFileFeatureType)
|
||||
{
|
||||
_currentIHttpSendFileFeature = feature;
|
||||
return;
|
||||
};
|
||||
ExtraFeatureSet(key, feature);
|
||||
}
|
||||
|
||||
private IEnumerable<KeyValuePair<Type, object>> FastEnumerable()
|
||||
{
|
||||
if (_currentIHttpRequestFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpRequestFeatureType, _currentIHttpRequestFeature as global::Microsoft.AspNetCore.Http.Features.IHttpRequestFeature);
|
||||
}
|
||||
if (_currentIHttpResponseFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpResponseFeatureType, _currentIHttpResponseFeature as global::Microsoft.AspNetCore.Http.Features.IHttpResponseFeature);
|
||||
}
|
||||
if (_currentIHttpRequestIdentifierFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpRequestIdentifierFeatureType, _currentIHttpRequestIdentifierFeature as global::Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature);
|
||||
}
|
||||
if (_currentIServiceProvidersFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IServiceProvidersFeatureType, _currentIServiceProvidersFeature as global::Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature);
|
||||
}
|
||||
if (_currentIHttpRequestLifetimeFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpRequestLifetimeFeatureType, _currentIHttpRequestLifetimeFeature as global::Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature);
|
||||
}
|
||||
if (_currentIHttpConnectionFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpConnectionFeatureType, _currentIHttpConnectionFeature as global::Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature);
|
||||
}
|
||||
if (_currentIHttpAuthenticationFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpAuthenticationFeatureType, _currentIHttpAuthenticationFeature as global::Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature);
|
||||
}
|
||||
if (_currentIQueryFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IQueryFeatureType, _currentIQueryFeature as global::Microsoft.AspNetCore.Http.Features.IQueryFeature);
|
||||
}
|
||||
if (_currentIFormFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IFormFeatureType, _currentIFormFeature as global::Microsoft.AspNetCore.Http.Features.IFormFeature);
|
||||
}
|
||||
if (_currentIHttpUpgradeFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpUpgradeFeatureType, _currentIHttpUpgradeFeature as global::Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature);
|
||||
}
|
||||
if (_currentIResponseCookiesFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IResponseCookiesFeatureType, _currentIResponseCookiesFeature as global::Microsoft.AspNetCore.Http.Features.IResponseCookiesFeature);
|
||||
}
|
||||
if (_currentIItemsFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IItemsFeatureType, _currentIItemsFeature as global::Microsoft.AspNetCore.Http.Features.IItemsFeature);
|
||||
}
|
||||
if (_currentITlsConnectionFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(ITlsConnectionFeatureType, _currentITlsConnectionFeature as global::Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature);
|
||||
}
|
||||
if (_currentIHttpWebSocketFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpWebSocketFeatureType, _currentIHttpWebSocketFeature as global::Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature);
|
||||
}
|
||||
if (_currentISessionFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(ISessionFeatureType, _currentISessionFeature as global::Microsoft.AspNetCore.Http.Features.ISessionFeature);
|
||||
}
|
||||
if (_currentIHttpBodyControlFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpBodyControlFeatureType, _currentIHttpBodyControlFeature as global::Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature);
|
||||
}
|
||||
if (_currentIHttpSendFileFeature != null)
|
||||
{
|
||||
yield return new KeyValuePair<Type, object>(IHttpSendFileFeatureType, _currentIHttpSendFileFeature as global::Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature);
|
||||
}
|
||||
|
||||
if (MaybeExtra != null)
|
||||
{
|
||||
foreach (var item in MaybeExtra)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,874 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.HttpSys.Internal;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
internal abstract partial class HttpProtocol : NativeRequestContext, IDisposable
|
||||
{
|
||||
private const int MinAllocBufferSize = 2048;
|
||||
|
||||
private static bool UpgradeAvailable = (Environment.OSVersion.Version >= new Version(6, 2));
|
||||
|
||||
protected readonly IntPtr _pHttpContext;
|
||||
private bool _wasUpgraded;
|
||||
private int _statusCode;
|
||||
private string _reasonPhrase;
|
||||
private readonly object _onStartingSync = new object();
|
||||
private readonly object _onCompletedSync = new object();
|
||||
protected Stack<KeyValuePair<Func<object, Task>, object>> _onStarting;
|
||||
protected Stack<KeyValuePair<Func<object, Task>, object>> _onCompleted;
|
||||
|
||||
protected Exception _applicationException;
|
||||
private readonly PipeFactory _pipeFactory;
|
||||
|
||||
private List<GCHandle> _pinnedHeaders;
|
||||
|
||||
private GCHandle _thisHandle;
|
||||
private BufferHandle _inputHandle;
|
||||
private IISAwaitable _readOperation = new IISAwaitable();
|
||||
private IISAwaitable _writeOperation = new IISAwaitable();
|
||||
private IISAwaitable _flushOperation = new IISAwaitable();
|
||||
|
||||
private TaskCompletionSource<object> _upgradeTcs;
|
||||
|
||||
protected Task _readingTask;
|
||||
protected Task _writingTask;
|
||||
|
||||
protected int _requestAborted;
|
||||
|
||||
internal unsafe HttpProtocol(PipeFactory pipeFactory, IntPtr pHttpContext)
|
||||
: base((HttpApiTypes.HTTP_REQUEST*) NativeMethods.http_get_raw_request(pHttpContext))
|
||||
{
|
||||
_thisHandle = GCHandle.Alloc(this);
|
||||
|
||||
_pipeFactory = pipeFactory;
|
||||
_pHttpContext = pHttpContext;
|
||||
|
||||
unsafe
|
||||
{
|
||||
Method = GetVerb();
|
||||
|
||||
RawTarget = GetRawUrl();
|
||||
// TODO version is slow.
|
||||
HttpVersion = GetVersion();
|
||||
Scheme = SslStatus != SslStatus.Insecure ? Constants.HttpsScheme : Constants.HttpScheme;
|
||||
KnownMethod = VerbId;
|
||||
|
||||
var originalPath = RequestUriBuilder.DecodeAndUnescapePath(GetRawUrlInBytes());
|
||||
|
||||
// TODO: Read this from IIS config
|
||||
// See https://github.com/aspnet/IISIntegration/issues/427
|
||||
var prefix = "/";
|
||||
if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawTarget, "*", StringComparison.Ordinal))
|
||||
{
|
||||
PathBase = string.Empty;
|
||||
Path = string.Empty;
|
||||
}
|
||||
// These paths are both unescaped already.
|
||||
else if (originalPath.Length == prefix.Length - 1)
|
||||
{
|
||||
// They matched exactly except for the trailing slash.
|
||||
PathBase = originalPath;
|
||||
Path = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// url: /base/path, prefix: /base/, base: /base, path: /path
|
||||
// url: /, prefix: /, base: , path: /
|
||||
PathBase = originalPath.Substring(0, prefix.Length - 1);
|
||||
Path = originalPath.Substring(prefix.Length - 1);
|
||||
}
|
||||
|
||||
var cookedUrl = GetCookedUrl();
|
||||
QueryString = cookedUrl.GetQueryString() ?? string.Empty;
|
||||
|
||||
// TODO: Avoid using long.ToString, it's pretty slow
|
||||
RequestConnectionId = ConnectionId.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
// Copied from WebListener
|
||||
// This is the base GUID used by HTTP.SYS for generating the activity ID.
|
||||
// HTTP.SYS overwrites the first 8 bytes of the base GUID with RequestId to generate ETW activity ID.
|
||||
// The requestId should be set by the NativeRequestContext
|
||||
var guid = new Guid(0xffcb4c93, 0xa57f, 0x453c, 0xb6, 0x3f, 0x84, 0x71, 0xc, 0x79, 0x67, 0xbb);
|
||||
*((ulong*)&guid) = RequestId;
|
||||
|
||||
// TODO: Also make this not slow
|
||||
TraceIdentifier = guid.ToString();
|
||||
|
||||
var localEndPoint = GetLocalEndPoint();
|
||||
LocalIpAddress = localEndPoint.GetIPAddress();
|
||||
LocalPort = localEndPoint.GetPort();
|
||||
|
||||
var remoteEndPoint = GetRemoteEndPoint();
|
||||
RemoteIpAddress = remoteEndPoint.GetIPAddress();
|
||||
RemotePort = remoteEndPoint.GetPort();
|
||||
StatusCode = 200;
|
||||
|
||||
RequestHeaders = new RequestHeaders(this);
|
||||
HttpResponseHeaders = new HeaderCollection(); // TODO Optimize for known headers
|
||||
ResponseHeaders = HttpResponseHeaders;
|
||||
|
||||
ResetFeatureCollection();
|
||||
}
|
||||
|
||||
RequestBody = new IISHttpRequestBody(this);
|
||||
ResponseBody = new IISHttpResponseBody(this);
|
||||
|
||||
Input = _pipeFactory.Create(new PipeOptions { ReaderScheduler = TaskRunScheduler.Default });
|
||||
var pipe = _pipeFactory.Create(new PipeOptions { ReaderScheduler = TaskRunScheduler.Default });
|
||||
Output = new OutputProducer(pipe);
|
||||
}
|
||||
|
||||
public Version HttpVersion { get; set; }
|
||||
public string Scheme { get; set; }
|
||||
public string Method { get; set; }
|
||||
public string PathBase { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string QueryString { get; set; }
|
||||
public string RawTarget { get; set; }
|
||||
public CancellationToken RequestAborted { get; set; }
|
||||
public bool HasResponseStarted { get; set; }
|
||||
public IPAddress RemoteIpAddress { get; set; }
|
||||
public int RemotePort { get; set; }
|
||||
public IPAddress LocalIpAddress { get; set; }
|
||||
public int LocalPort { get; set; }
|
||||
public string RequestConnectionId { get; set; }
|
||||
public string TraceIdentifier { get; set; }
|
||||
|
||||
public Stream RequestBody { get; set; }
|
||||
public Stream ResponseBody { get; set; }
|
||||
public IPipe Input { get; set; }
|
||||
public OutputProducer Output { get; set; }
|
||||
|
||||
public IHeaderDictionary RequestHeaders { get; set; }
|
||||
public IHeaderDictionary ResponseHeaders { get; set; }
|
||||
private HeaderCollection HttpResponseHeaders { get; set; }
|
||||
internal HttpApiTypes.HTTP_VERB KnownMethod { get; }
|
||||
|
||||
public int StatusCode
|
||||
{
|
||||
get { return _statusCode; }
|
||||
set
|
||||
{
|
||||
if (HasResponseStarted)
|
||||
{
|
||||
ThrowResponseAlreadyStartedException(nameof(StatusCode));
|
||||
}
|
||||
_statusCode = (ushort)value;
|
||||
}
|
||||
}
|
||||
|
||||
public string ReasonPhrase
|
||||
{
|
||||
get { return _reasonPhrase; }
|
||||
set
|
||||
{
|
||||
if (HasResponseStarted)
|
||||
{
|
||||
ThrowResponseAlreadyStartedException(nameof(ReasonPhrase));
|
||||
}
|
||||
_reasonPhrase = value;
|
||||
}
|
||||
}
|
||||
|
||||
private IISAwaitable DoFlushAsync()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var hr = 0;
|
||||
hr = NativeMethods.http_flush_response_bytes(_pHttpContext, IISAwaitable.FlushCallback, (IntPtr)_thisHandle, out var fCompletionExpected);
|
||||
|
||||
if (!fCompletionExpected)
|
||||
{
|
||||
CompleteFlush(hr, 0);
|
||||
}
|
||||
}
|
||||
return _flushOperation;
|
||||
}
|
||||
|
||||
public async Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
await InitializeResponse(0);
|
||||
await Output.FlushAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task UpgradeAsync()
|
||||
{
|
||||
if (_upgradeTcs == null)
|
||||
{
|
||||
_upgradeTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
await FlushAsync();
|
||||
await _upgradeTcs.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public Task WriteAsync(ArraySegment<byte> data, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (!HasResponseStarted)
|
||||
{
|
||||
return WriteAsyncAwaited(data, cancellationToken);
|
||||
}
|
||||
|
||||
// VerifyAndUpdateWrite(data.Count);
|
||||
return Output.WriteAsync(data, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public async Task WriteAsyncAwaited(ArraySegment<byte> data, CancellationToken cancellationToken)
|
||||
{
|
||||
await InitializeResponseAwaited(data.Count);
|
||||
|
||||
// WriteAsyncAwaited is only called for the first write to the body.
|
||||
// Ensure headers are flushed if Write(Chunked)Async isn't called.
|
||||
await Output.WriteAsync(data, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public Task InitializeResponse(int firstWriteByteCount)
|
||||
{
|
||||
if (HasResponseStarted)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (_onStarting != null)
|
||||
{
|
||||
return InitializeResponseAwaited(firstWriteByteCount);
|
||||
}
|
||||
|
||||
if (_applicationException != null)
|
||||
{
|
||||
ThrowResponseAbortedException();
|
||||
}
|
||||
|
||||
ProduceStart(appCompleted: false);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task InitializeResponseAwaited(int firstWriteByteCount)
|
||||
{
|
||||
await FireOnStarting();
|
||||
|
||||
if (_applicationException != null)
|
||||
{
|
||||
ThrowResponseAbortedException();
|
||||
}
|
||||
|
||||
ProduceStart(appCompleted: false);
|
||||
}
|
||||
|
||||
private void ThrowResponseAbortedException()
|
||||
{
|
||||
throw new ObjectDisposedException("Unhandled application exception", _applicationException);
|
||||
}
|
||||
|
||||
private void ProduceStart(bool appCompleted)
|
||||
{
|
||||
if (HasResponseStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HasResponseStarted = true;
|
||||
|
||||
SendResponseHeaders(appCompleted);
|
||||
|
||||
StartWritingResponseBody();
|
||||
}
|
||||
|
||||
protected Task ProduceEnd()
|
||||
{
|
||||
if (_applicationException != null)
|
||||
{
|
||||
if (HasResponseStarted)
|
||||
{
|
||||
// We can no longer change the response, so we simply close the connection.
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// If the request was rejected, the error state has already been set by SetBadRequestState and
|
||||
// that should take precedence.
|
||||
else
|
||||
{
|
||||
// 500 Internal Server Error
|
||||
SetErrorResponseHeaders(statusCode: StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
if (!HasResponseStarted)
|
||||
{
|
||||
return ProduceEndAwaited();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void SetErrorResponseHeaders(int statusCode)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
ReasonPhrase = string.Empty;
|
||||
HttpResponseHeaders.Clear();
|
||||
}
|
||||
|
||||
private async Task ProduceEndAwaited()
|
||||
{
|
||||
ProduceStart(appCompleted: true);
|
||||
|
||||
// Force flush
|
||||
await Output.FlushAsync();
|
||||
}
|
||||
|
||||
public unsafe void SendResponseHeaders(bool appCompleted)
|
||||
{
|
||||
// Verifies we have sent the statuscode before writing a header
|
||||
var reasonPhraseBytes = Encoding.UTF8.GetBytes(ReasonPhrase ?? ReasonPhrases.GetReasonPhrase(StatusCode));
|
||||
|
||||
fixed (byte* pReasonPhrase = reasonPhraseBytes)
|
||||
{
|
||||
// This copies data into the underlying buffer
|
||||
NativeMethods.http_set_response_status_code(_pHttpContext, (ushort)StatusCode, pReasonPhrase);
|
||||
}
|
||||
|
||||
HttpApiTypes.HTTP_RESPONSE_V2* pHttpResponse = NativeMethods.http_get_raw_response(_pHttpContext);
|
||||
|
||||
// We should be sending the headers here as there are many responses that don't have status codes.
|
||||
_pinnedHeaders = SerializeHeaders(pHttpResponse);
|
||||
}
|
||||
|
||||
// From HttpSys, except does not write to response
|
||||
private unsafe List<GCHandle> SerializeHeaders(HttpApiTypes.HTTP_RESPONSE_V2* pHttpResponse)
|
||||
{
|
||||
HttpResponseHeaders.IsReadOnly = true;
|
||||
HttpApiTypes.HTTP_UNKNOWN_HEADER[] unknownHeaders = null;
|
||||
HttpApiTypes.HTTP_RESPONSE_INFO[] knownHeaderInfo = null;
|
||||
var pinnedHeaders = new List<GCHandle>();
|
||||
GCHandle gcHandle;
|
||||
|
||||
if (HttpResponseHeaders.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string headerName;
|
||||
string headerValue;
|
||||
int lookup;
|
||||
var numUnknownHeaders = 0;
|
||||
int numKnownMultiHeaders = 0;
|
||||
byte[] bytes = null;
|
||||
|
||||
foreach (var headerPair in HttpResponseHeaders)
|
||||
{
|
||||
if (headerPair.Value.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
lookup = HttpApiTypes.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerPair.Key);
|
||||
if (lookup == -1) // TODO handle opaque stream upgrade?
|
||||
{
|
||||
numUnknownHeaders++;
|
||||
}
|
||||
else if (headerPair.Value.Count > 1)
|
||||
{
|
||||
numKnownMultiHeaders++;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var pKnownHeaders = &pHttpResponse->Response_V1.Headers.KnownHeaders;
|
||||
foreach (var headerPair in HttpResponseHeaders)
|
||||
{
|
||||
if (headerPair.Value.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
headerName = headerPair.Key;
|
||||
StringValues headerValues = headerPair.Value;
|
||||
lookup = HttpApiTypes.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerName);
|
||||
if (lookup == -1)
|
||||
{
|
||||
if (unknownHeaders == null)
|
||||
{
|
||||
unknownHeaders = new HttpApiTypes.HTTP_UNKNOWN_HEADER[numUnknownHeaders];
|
||||
gcHandle = GCHandle.Alloc(unknownHeaders, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
pHttpResponse->Response_V1.Headers.pUnknownHeaders = (HttpApiTypes.HTTP_UNKNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
|
||||
pHttpResponse->Response_V1.Headers.UnknownHeaderCount = 0; // to remove the iis header for server=...
|
||||
}
|
||||
|
||||
for (var headerValueIndex = 0; headerValueIndex < headerValues.Count; headerValueIndex++)
|
||||
{
|
||||
// Add Name
|
||||
bytes = HeaderEncoding.GetBytes(headerName);
|
||||
unknownHeaders[pHttpResponse->Response_V1.Headers.UnknownHeaderCount].NameLength = (ushort)bytes.Length;
|
||||
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
unknownHeaders[pHttpResponse->Response_V1.Headers.UnknownHeaderCount].pName = (byte*)gcHandle.AddrOfPinnedObject();
|
||||
|
||||
// Add Value
|
||||
headerValue = headerValues[headerValueIndex] ?? string.Empty;
|
||||
bytes = HeaderEncoding.GetBytes(headerValue);
|
||||
unknownHeaders[pHttpResponse->Response_V1.Headers.UnknownHeaderCount].RawValueLength = (ushort)bytes.Length;
|
||||
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
unknownHeaders[pHttpResponse->Response_V1.Headers.UnknownHeaderCount].pRawValue = (byte*)gcHandle.AddrOfPinnedObject();
|
||||
pHttpResponse->Response_V1.Headers.UnknownHeaderCount++;
|
||||
}
|
||||
}
|
||||
else if (headerPair.Value.Count == 1)
|
||||
{
|
||||
headerValue = headerValues[0] ?? string.Empty;
|
||||
bytes = HeaderEncoding.GetBytes(headerValue);
|
||||
pKnownHeaders[lookup].RawValueLength = (ushort)bytes.Length;
|
||||
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
pKnownHeaders[lookup].pRawValue = (byte*)gcHandle.AddrOfPinnedObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (knownHeaderInfo == null)
|
||||
{
|
||||
knownHeaderInfo = new HttpApiTypes.HTTP_RESPONSE_INFO[numKnownMultiHeaders];
|
||||
gcHandle = GCHandle.Alloc(knownHeaderInfo, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
pHttpResponse->pResponseInfo = (HttpApiTypes.HTTP_RESPONSE_INFO*)gcHandle.AddrOfPinnedObject();
|
||||
}
|
||||
|
||||
knownHeaderInfo[pHttpResponse->ResponseInfoCount].Type = HttpApiTypes.HTTP_RESPONSE_INFO_TYPE.HttpResponseInfoTypeMultipleKnownHeaders;
|
||||
knownHeaderInfo[pHttpResponse->ResponseInfoCount].Length = (uint)Marshal.SizeOf<HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS>();
|
||||
|
||||
var header = new HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS();
|
||||
|
||||
header.HeaderId = (HttpApiTypes.HTTP_RESPONSE_HEADER_ID.Enum)lookup;
|
||||
header.Flags = HttpApiTypes.HTTP_RESPONSE_INFO_FLAGS.PreserveOrder; // TODO: The docs say this is for www-auth only.
|
||||
|
||||
var nativeHeaderValues = new HttpApiTypes.HTTP_KNOWN_HEADER[headerValues.Count];
|
||||
gcHandle = GCHandle.Alloc(nativeHeaderValues, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
header.KnownHeaders = (HttpApiTypes.HTTP_KNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
|
||||
|
||||
for (int headerValueIndex = 0; headerValueIndex < headerValues.Count; headerValueIndex++)
|
||||
{
|
||||
// Add Value
|
||||
headerValue = headerValues[headerValueIndex] ?? string.Empty;
|
||||
bytes = HeaderEncoding.GetBytes(headerValue);
|
||||
nativeHeaderValues[header.KnownHeaderCount].RawValueLength = (ushort)bytes.Length;
|
||||
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
nativeHeaderValues[header.KnownHeaderCount].pRawValue = (byte*)gcHandle.AddrOfPinnedObject();
|
||||
header.KnownHeaderCount++;
|
||||
}
|
||||
|
||||
// This type is a struct, not an object, so pinning it causes a boxed copy to be created. We can't do that until after all the fields are set.
|
||||
gcHandle = GCHandle.Alloc(header, GCHandleType.Pinned);
|
||||
pinnedHeaders.Add(gcHandle);
|
||||
knownHeaderInfo[pHttpResponse->ResponseInfoCount].pInfo = (HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS*)gcHandle.AddrOfPinnedObject();
|
||||
|
||||
pHttpResponse->ResponseInfoCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
FreePinnedHeaders(pinnedHeaders);
|
||||
throw;
|
||||
}
|
||||
return pinnedHeaders;
|
||||
}
|
||||
|
||||
private static void FreePinnedHeaders(List<GCHandle> pinnedHeaders)
|
||||
{
|
||||
if (pinnedHeaders != null)
|
||||
{
|
||||
foreach (GCHandle gcHandle in pinnedHeaders)
|
||||
{
|
||||
if (gcHandle.IsAllocated)
|
||||
{
|
||||
gcHandle.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void StartReadingRequestBody()
|
||||
{
|
||||
if (_readingTask == null)
|
||||
{
|
||||
_readingTask = ProcessRequestBody();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessRequestBody()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// These buffers are pinned
|
||||
var wb = Input.Writer.Alloc(MinAllocBufferSize);
|
||||
_inputHandle = wb.Buffer.Retain(true);
|
||||
|
||||
try
|
||||
{
|
||||
int read = await ReadAsync(wb.Buffer.Length);
|
||||
|
||||
if (read == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
wb.Advance(read);
|
||||
}
|
||||
finally
|
||||
{
|
||||
wb.Commit();
|
||||
_inputHandle.Dispose();
|
||||
}
|
||||
|
||||
var result = await wb.FlushAsync();
|
||||
|
||||
if (result.IsCompleted || result.IsCancelled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Input.Writer.Complete();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Input.Writer.Complete(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartWritingResponseBody()
|
||||
{
|
||||
if (_writingTask == null)
|
||||
{
|
||||
_writingTask = ProcessResponseBody();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessResponseBody()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
ReadResult result;
|
||||
|
||||
try
|
||||
{
|
||||
result = await Output.Reader.ReadAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Output.Reader.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
var buffer = result.Buffer;
|
||||
var consumed = buffer.End;
|
||||
|
||||
try
|
||||
{
|
||||
if (result.IsCancelled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!buffer.IsEmpty)
|
||||
{
|
||||
await WriteAsync(buffer);
|
||||
}
|
||||
else if (result.IsCompleted)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
await DoFlushAsync();
|
||||
}
|
||||
|
||||
_upgradeTcs?.TrySetResult(null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Output.Reader.Advance(consumed);
|
||||
}
|
||||
}
|
||||
Output.Reader.Complete();
|
||||
}
|
||||
|
||||
private unsafe IISAwaitable WriteAsync(ReadableBuffer buffer)
|
||||
{
|
||||
var fCompletionExpected = false;
|
||||
var hr = 0;
|
||||
var nChunks = 0;
|
||||
|
||||
if (buffer.IsSingleSpan)
|
||||
{
|
||||
nChunks = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var memory in buffer)
|
||||
{
|
||||
nChunks++;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.IsSingleSpan)
|
||||
{
|
||||
var pDataChunks = stackalloc HttpApiTypes.HTTP_DATA_CHUNK[1];
|
||||
|
||||
fixed (byte* pBuffer = &buffer.First.Span.DangerousGetPinnableReference())
|
||||
{
|
||||
ref var chunk = ref pDataChunks[0];
|
||||
|
||||
chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
|
||||
chunk.fromMemory.pBuffer = (IntPtr)pBuffer;
|
||||
chunk.fromMemory.BufferLength = (uint)buffer.Length;
|
||||
|
||||
hr = NativeMethods.http_write_response_bytes(_pHttpContext, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// REVIEW: Do we need to guard against this getting too big? It seems unlikely that we'd have more than say 10 chunks in real life
|
||||
var pDataChunks = stackalloc HttpApiTypes.HTTP_DATA_CHUNK[nChunks];
|
||||
var currentChunk = 0;
|
||||
|
||||
// REVIEW: We don't really need this list since the memory is already pinned with the default pool,
|
||||
// but shouldn't assume the pool implementation right now. Unfortunately, this causes a heap allocation...
|
||||
var handles = new BufferHandle[nChunks];
|
||||
|
||||
foreach (var b in buffer)
|
||||
{
|
||||
ref var handle = ref handles[currentChunk];
|
||||
ref var chunk = ref pDataChunks[currentChunk];
|
||||
|
||||
handle = b.Retain(true);
|
||||
|
||||
chunk.DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
|
||||
chunk.fromMemory.BufferLength = (uint)b.Length;
|
||||
chunk.fromMemory.pBuffer = (IntPtr)handle.PinnedPointer;
|
||||
|
||||
currentChunk++;
|
||||
}
|
||||
|
||||
hr = NativeMethods.http_write_response_bytes(_pHttpContext, pDataChunks, nChunks, IISAwaitable.WriteCallback, (IntPtr)_thisHandle, out fCompletionExpected);
|
||||
|
||||
// Free the handles
|
||||
foreach (var handle in handles)
|
||||
{
|
||||
handle.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
if (!fCompletionExpected)
|
||||
{
|
||||
CompleteWrite(hr, cbBytes: 0);
|
||||
}
|
||||
|
||||
return _writeOperation;
|
||||
}
|
||||
|
||||
private unsafe IISAwaitable ReadAsync(int length)
|
||||
{
|
||||
var hr = NativeMethods.http_read_request_bytes(
|
||||
_pHttpContext,
|
||||
(byte*)_inputHandle.PinnedPointer,
|
||||
length,
|
||||
IISAwaitable.ReadCallback,
|
||||
(IntPtr)_thisHandle,
|
||||
out var dwReceivedBytes,
|
||||
out var fCompletionExpected);
|
||||
|
||||
if (!fCompletionExpected)
|
||||
{
|
||||
CompleteRead(hr, dwReceivedBytes);
|
||||
}
|
||||
|
||||
return _readOperation;
|
||||
}
|
||||
|
||||
public abstract Task ProcessRequestAsync();
|
||||
|
||||
public void OnStarting(Func<object, Task> callback, object state)
|
||||
{
|
||||
lock (_onStartingSync)
|
||||
{
|
||||
if (HasResponseStarted)
|
||||
{
|
||||
throw new InvalidOperationException("Response already started");
|
||||
}
|
||||
|
||||
if (_onStarting == null)
|
||||
{
|
||||
_onStarting = new Stack<KeyValuePair<Func<object, Task>, object>>();
|
||||
}
|
||||
_onStarting.Push(new KeyValuePair<Func<object, Task>, object>(callback, state));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Func<object, Task> callback, object state)
|
||||
{
|
||||
lock (_onCompletedSync)
|
||||
{
|
||||
if (_onCompleted == null)
|
||||
{
|
||||
_onCompleted = new Stack<KeyValuePair<Func<object, Task>, object>>();
|
||||
}
|
||||
_onCompleted.Push(new KeyValuePair<Func<object, Task>, object>(callback, state));
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task FireOnStarting()
|
||||
{
|
||||
Stack<KeyValuePair<Func<object, Task>, object>> onStarting = null;
|
||||
lock (_onStartingSync)
|
||||
{
|
||||
onStarting = _onStarting;
|
||||
_onStarting = null;
|
||||
}
|
||||
if (onStarting != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var entry in onStarting)
|
||||
{
|
||||
await entry.Key.Invoke(entry.Value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportApplicationError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task FireOnCompleted()
|
||||
{
|
||||
Stack<KeyValuePair<Func<object, Task>, object>> onCompleted = null;
|
||||
lock (_onCompletedSync)
|
||||
{
|
||||
onCompleted = _onCompleted;
|
||||
_onCompleted = null;
|
||||
}
|
||||
if (onCompleted != null)
|
||||
{
|
||||
foreach (var entry in onCompleted)
|
||||
{
|
||||
try
|
||||
{
|
||||
await entry.Key.Invoke(entry.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportApplicationError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void ReportApplicationError(Exception ex)
|
||||
{
|
||||
if (_applicationException == null)
|
||||
{
|
||||
_applicationException = ex;
|
||||
}
|
||||
else if (_applicationException is AggregateException)
|
||||
{
|
||||
_applicationException = new AggregateException(_applicationException, ex).Flatten();
|
||||
}
|
||||
else
|
||||
{
|
||||
_applicationException = new AggregateException(_applicationException, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostCompletion()
|
||||
{
|
||||
Debug.Assert(!_readOperation.HasContinuation, "Pending read async operation!");
|
||||
Debug.Assert(!_writeOperation.HasContinuation, "Pending write async operation!");
|
||||
|
||||
var hr = NativeMethods.http_post_completion(_pHttpContext, 0);
|
||||
|
||||
if (hr != NativeMethods.S_OK)
|
||||
{
|
||||
throw Marshal.GetExceptionForHR(hr);
|
||||
}
|
||||
}
|
||||
|
||||
public void IndicateCompletion(NativeMethods.REQUEST_NOTIFICATION_STATUS notificationStatus)
|
||||
{
|
||||
NativeMethods.http_indicate_completion(_pHttpContext, notificationStatus);
|
||||
}
|
||||
|
||||
internal void CompleteWrite(int hr, int cbBytes)
|
||||
{
|
||||
_writeOperation.Complete(hr, cbBytes);
|
||||
}
|
||||
|
||||
internal void CompleteRead(int hr, int cbBytes)
|
||||
{
|
||||
_readOperation.Complete(hr, cbBytes);
|
||||
}
|
||||
|
||||
internal void CompleteFlush(int hr, int cbBytes)
|
||||
{
|
||||
FreePinnedHeaders(_pinnedHeaders);
|
||||
_pinnedHeaders = null;
|
||||
|
||||
_flushOperation.Complete(hr, cbBytes);
|
||||
}
|
||||
|
||||
private bool disposedValue = false; // To detect redundant calls
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// TODO: dispose managed state (managed objects).
|
||||
_thisHandle.Free();
|
||||
}
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
// This code added to correctly implement the disposable pattern.
|
||||
public override void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void ThrowResponseAlreadyStartedException(string value)
|
||||
{
|
||||
throw new InvalidOperationException("Response already started");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
// Primarily copied from https://github.com/aspnet/KestrelHttpServer/blob/dev/src/Kestrel.Transport.Libuv/Internal/LibuvAwaitable.cs
|
||||
public class IISAwaitable : ICriticalNotifyCompletion
|
||||
{
|
||||
private readonly static Action _callbackCompleted = () => { };
|
||||
|
||||
private Action _callback;
|
||||
|
||||
private Exception _exception;
|
||||
|
||||
private int _cbBytes;
|
||||
|
||||
public static readonly NativeMethods.PFN_ASYNC_COMPLETION ReadCallback = (IntPtr pHttpContext, IntPtr pCompletionInfo, IntPtr pvCompletionContext) =>
|
||||
{
|
||||
var context = (HttpProtocol)GCHandle.FromIntPtr(pvCompletionContext).Target;
|
||||
|
||||
NativeMethods.http_get_completion_info(pCompletionInfo, out int cbBytes, out int hr);
|
||||
|
||||
context.CompleteRead(hr, cbBytes);
|
||||
|
||||
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING;
|
||||
};
|
||||
|
||||
public static readonly NativeMethods.PFN_ASYNC_COMPLETION WriteCallback = (IntPtr pHttpContext, IntPtr pCompletionInfo, IntPtr pvCompletionContext) =>
|
||||
{
|
||||
var context = (HttpProtocol)GCHandle.FromIntPtr(pvCompletionContext).Target;
|
||||
|
||||
NativeMethods.http_get_completion_info(pCompletionInfo, out int cbBytes, out int hr);
|
||||
|
||||
context.CompleteWrite(hr, cbBytes);
|
||||
|
||||
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING;
|
||||
};
|
||||
|
||||
public static readonly NativeMethods.PFN_ASYNC_COMPLETION FlushCallback = (IntPtr pHttpContext, IntPtr pCompletionInfo, IntPtr pvCompletionContext) =>
|
||||
{
|
||||
var context = (HttpProtocol)GCHandle.FromIntPtr(pvCompletionContext).Target;
|
||||
|
||||
NativeMethods.http_get_completion_info(pCompletionInfo, out int cbBytes, out int hr);
|
||||
|
||||
context.CompleteFlush(hr, cbBytes);
|
||||
|
||||
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING;
|
||||
};
|
||||
|
||||
public IISAwaitable GetAwaiter() => this;
|
||||
public bool IsCompleted => _callback == _callbackCompleted;
|
||||
|
||||
public bool HasContinuation => _callback != null && !IsCompleted;
|
||||
|
||||
public int GetResult()
|
||||
{
|
||||
var exception = _exception;
|
||||
var cbBytes = _cbBytes;
|
||||
|
||||
// Reset the awaitable state
|
||||
_exception = null;
|
||||
_cbBytes = 0;
|
||||
_callback = null;
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return cbBytes;
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
// There should never be a race between IsCompleted and OnCompleted since both operations
|
||||
// should always be on the libuv thread
|
||||
|
||||
if (_callback == _callbackCompleted ||
|
||||
Interlocked.CompareExchange(ref _callback, continuation, null) == _callbackCompleted)
|
||||
{
|
||||
// Just run it inline
|
||||
Task.Run(continuation);
|
||||
}
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
OnCompleted(continuation);
|
||||
}
|
||||
|
||||
public void Complete(int hr, int cbBytes)
|
||||
{
|
||||
_exception = Marshal.GetExceptionForHR(hr);
|
||||
_cbBytes = cbBytes;
|
||||
|
||||
var continuation = Interlocked.Exchange(ref _callback, _callbackCompleted);
|
||||
|
||||
continuation?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using System.Threading;
|
||||
using System.IO.Pipelines;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
internal class IISHttpContextOfT<TContext> : HttpProtocol
|
||||
{
|
||||
private readonly IHttpApplication<TContext> _application;
|
||||
|
||||
public IISHttpContextOfT(PipeFactory pipeFactory, IHttpApplication<TContext> application, IntPtr pHttpContext)
|
||||
: base(pipeFactory, pHttpContext)
|
||||
{
|
||||
_application = application;
|
||||
}
|
||||
|
||||
public override async Task ProcessRequestAsync()
|
||||
{
|
||||
var context = default(TContext);
|
||||
|
||||
try
|
||||
{
|
||||
context = _application.CreateContext(this);
|
||||
|
||||
await _application.ProcessRequestAsync(context);
|
||||
// TODO Verification of Response
|
||||
//if (Volatile.Read(ref _requestAborted) == 0)
|
||||
//{
|
||||
// VerifyResponseContentLength();
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportApplicationError(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!HasResponseStarted && _applicationException == null && _onStarting != null)
|
||||
{
|
||||
await FireOnStarting();
|
||||
// Dispose
|
||||
}
|
||||
|
||||
if (_onCompleted != null)
|
||||
{
|
||||
await FireOnCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
if (Volatile.Read(ref _requestAborted) == 0)
|
||||
{
|
||||
await ProduceEnd();
|
||||
}
|
||||
else if (!HasResponseStarted)
|
||||
{
|
||||
// If the request was aborted and no response was sent, there's no
|
||||
// meaningful status code to log.
|
||||
StatusCode = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_application.DisposeContext(context, _applicationException);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO Log this
|
||||
_applicationException = _applicationException ?? ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// The app is finished and there should be nobody writing to the response pipe
|
||||
Output.Dispose();
|
||||
|
||||
if (_writingTask != null)
|
||||
{
|
||||
await _writingTask;
|
||||
}
|
||||
|
||||
// The app is finished and there should be nobody reading from the request pipe
|
||||
Input.Reader.Complete();
|
||||
|
||||
if (_readingTask != null)
|
||||
{
|
||||
await _readingTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
internal class IISHttpRequestBody : Stream
|
||||
{
|
||||
private readonly HttpProtocol _httpContext;
|
||||
|
||||
public IISHttpRequestBody(HttpProtocol httpContext)
|
||||
{
|
||||
_httpContext = httpContext;
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return ReadAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
_httpContext.StartReadingRequestBody();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var result = await _httpContext.Input.Reader.ReadAsync();
|
||||
var readableBuffer = result.Buffer;
|
||||
try
|
||||
{
|
||||
if (!readableBuffer.IsEmpty)
|
||||
{
|
||||
var actual = Math.Min(readableBuffer.Length, count);
|
||||
readableBuffer = readableBuffer.Slice(0, actual);
|
||||
readableBuffer.CopyTo(buffer);
|
||||
return (int)actual;
|
||||
}
|
||||
else if (result.IsCompleted)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_httpContext.Input.Reader.Advance(readableBuffer.End, readableBuffer.End);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public unsafe override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
internal class IISHttpResponseBody : Stream
|
||||
{
|
||||
private readonly HttpProtocol _httpContext;
|
||||
|
||||
public IISHttpResponseBody(HttpProtocol httpContext)
|
||||
{
|
||||
_httpContext = httpContext;
|
||||
}
|
||||
|
||||
public override bool CanRead => false;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => true;
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
FlushAsync(CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public unsafe override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override unsafe Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpContext.WriteAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken);
|
||||
}
|
||||
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpContext.FlushAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO.Pipelines;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
public class IISHttpServer : IServer
|
||||
{
|
||||
private static NativeMethods.PFN_REQUEST_HANDLER _requestHandler = HandleRequest;
|
||||
private static NativeMethods.PFN_SHUTDOWN_HANDLER _shutdownHandler = HandleShutdown;
|
||||
|
||||
private IISContextFactory _iisContextFactory;
|
||||
|
||||
private PipeFactory _pipeFactory = new PipeFactory();
|
||||
private GCHandle _httpServerHandle;
|
||||
private IApplicationLifetime _applicationLifetime;
|
||||
|
||||
public IFeatureCollection Features { get; } = new FeatureCollection();
|
||||
public IISHttpServer(IApplicationLifetime applicationLifetime)
|
||||
{
|
||||
_applicationLifetime = applicationLifetime;
|
||||
}
|
||||
|
||||
public Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken)
|
||||
{
|
||||
_httpServerHandle = GCHandle.Alloc(this);
|
||||
|
||||
_iisContextFactory = new IISContextFactory<TContext>(_pipeFactory, application);
|
||||
|
||||
// Start the server by registering the callback
|
||||
// TODO the context may change here for shutdown.
|
||||
NativeMethods.register_callbacks(_requestHandler, _shutdownHandler, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Drain pending requests
|
||||
|
||||
// Stop all further calls back into managed code by unhooking the callback
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_httpServerHandle.IsAllocated)
|
||||
{
|
||||
_httpServerHandle.Free();
|
||||
}
|
||||
|
||||
_pipeFactory.Dispose();
|
||||
}
|
||||
|
||||
private static NativeMethods.REQUEST_NOTIFICATION_STATUS HandleRequest(IntPtr pHttpContext, IntPtr pvRequestContext)
|
||||
{
|
||||
// Unwrap the server so we can create an http context and process the request
|
||||
var server = (IISHttpServer)GCHandle.FromIntPtr(pvRequestContext).Target;
|
||||
|
||||
var context = server._iisContextFactory.CreateHttpContext(pHttpContext);
|
||||
|
||||
var task = context.ProcessRequestAsync();
|
||||
|
||||
// This should never fail
|
||||
if (task.IsCompleted)
|
||||
{
|
||||
context.Dispose();
|
||||
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_CONTINUE;
|
||||
}
|
||||
|
||||
task.ContinueWith((t, state) => CompleteRequest((HttpProtocol)state), context);
|
||||
|
||||
return NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_PENDING;
|
||||
}
|
||||
|
||||
private static bool HandleShutdown(IntPtr pvRequestContext)
|
||||
{
|
||||
var server = (IISHttpServer)GCHandle.FromIntPtr(pvRequestContext).Target;
|
||||
server._applicationLifetime.StopApplication();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void CompleteRequest(HttpProtocol context)
|
||||
{
|
||||
// Post completion after completing the request to resume the state machine
|
||||
context.PostCompletion();
|
||||
|
||||
// Dispose the context
|
||||
context.Dispose();
|
||||
}
|
||||
|
||||
private class IISContextFactory<T> : IISContextFactory
|
||||
{
|
||||
private readonly IHttpApplication<T> _application;
|
||||
private readonly PipeFactory _pipeFactory;
|
||||
|
||||
public IISContextFactory(PipeFactory pipeFactory, IHttpApplication<T> application)
|
||||
{
|
||||
_application = application;
|
||||
_pipeFactory = pipeFactory;
|
||||
}
|
||||
|
||||
public HttpProtocol CreateHttpContext(IntPtr pHttpContext)
|
||||
{
|
||||
return new IISHttpContextOfT<T>(_pipeFactory, _application, pHttpContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Over engineering to avoid allocations...
|
||||
internal interface IISContextFactory
|
||||
{
|
||||
HttpProtocol CreateHttpContext(IntPtr pHttpContext);
|
||||
}
|
||||
|
||||
public static class WebHostBuilderExtensions
|
||||
{
|
||||
public static IWebHostBuilder UseNativeIIS(this IWebHostBuilder builder)
|
||||
{
|
||||
if (NativeMethods.is_ancm_loaded())
|
||||
{
|
||||
// TODO put this in options and use path.
|
||||
var path = NativeMethods.http_get_application_full_path();
|
||||
builder.UseContentRoot(path);
|
||||
return builder.ConfigureServices(services =>
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
services.AddSingleton<IServer, IISHttpServer>();
|
||||
}
|
||||
});
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core components for running the in process mode for AspNetCoreModule.</Description>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;iis</PackageTags>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Security.Principal.Windows" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.HttpSys.Sources" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.AspNetCore.HttpSys.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
public static class NativeMethods
|
||||
{
|
||||
public const int S_OK = 0;
|
||||
private const string AspNetCoreModuleDll = "aspnetcore.dll";
|
||||
|
||||
public enum REQUEST_NOTIFICATION_STATUS
|
||||
{
|
||||
RQ_NOTIFICATION_CONTINUE,
|
||||
RQ_NOTIFICATION_PENDING,
|
||||
RQ_NOTIFICATION_FINISH_REQUEST
|
||||
}
|
||||
|
||||
public delegate REQUEST_NOTIFICATION_STATUS PFN_REQUEST_HANDLER(IntPtr pHttpContext, IntPtr pvRequestContext);
|
||||
public delegate bool PFN_SHUTDOWN_HANDLER(IntPtr pvRequestContext);
|
||||
public delegate REQUEST_NOTIFICATION_STATUS PFN_ASYNC_COMPLETION(IntPtr pHttpContext, IntPtr completionInfo, IntPtr pvCompletionContext);
|
||||
|
||||
// TODO make this all internal
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public static extern int http_post_completion(IntPtr pHttpContext, int cbBytes);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public static extern void http_indicate_completion(IntPtr pHttpContext, REQUEST_NOTIFICATION_STATUS notificationStatus);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public static extern void register_callbacks(PFN_REQUEST_HANDLER request_callback, PFN_SHUTDOWN_HANDLER shutdown_callback, IntPtr pvRequestContext, IntPtr pvShutdownContext);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
internal unsafe static extern int http_write_response_bytes(IntPtr pHttpContext, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, PFN_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out bool fCompletionExpected);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public unsafe static extern int http_flush_response_bytes(IntPtr pHttpContext, PFN_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out bool fCompletionExpected);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
internal unsafe static extern HttpApiTypes.HTTP_REQUEST_V2* http_get_raw_request(IntPtr pHttpContext);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
internal unsafe static extern HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pHttpContext);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public unsafe static extern void http_set_response_status_code(IntPtr pHttpContext, ushort statusCode, byte* pszReason);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public unsafe static extern int http_read_request_bytes(IntPtr pHttpContext, byte* pvBuffer, int cbBuffer, PFN_ASYNC_COMPLETION pfnCompletionCallback, IntPtr pvCompletionContext, out int dwBytesReceived, out bool fCompletionExpected);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public unsafe static extern bool http_get_completion_info(IntPtr pCompletionInfo, out int cbBytes, out int hr);
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
public unsafe static extern string http_get_application_full_path();
|
||||
|
||||
[DllImport(AspNetCoreModuleDll)]
|
||||
public unsafe static extern bool http_shutdown();
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
public static bool is_ancm_loaded()
|
||||
{
|
||||
return GetModuleHandle(AspNetCoreModuleDll) != IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS
|
||||
{
|
||||
public class OutputProducer
|
||||
{
|
||||
private static readonly ArraySegment<byte> _emptyData = new ArraySegment<byte>(new byte[0]);
|
||||
|
||||
// This locks access to to all of the below fields
|
||||
private readonly object _contextLock = new object();
|
||||
|
||||
private bool _completed = false;
|
||||
|
||||
private readonly IPipe _pipe;
|
||||
|
||||
// https://github.com/dotnet/corefxlab/issues/1334
|
||||
// Pipelines don't support multiple awaiters on flush
|
||||
// this is temporary until it does
|
||||
private TaskCompletionSource<object> _flushTcs;
|
||||
private readonly object _flushLock = new object();
|
||||
private Action _flushCompleted;
|
||||
|
||||
public OutputProducer(IPipe pipe)
|
||||
{
|
||||
_pipe = pipe;
|
||||
_flushCompleted = OnFlushCompleted;
|
||||
}
|
||||
|
||||
public IPipeReader Reader => _pipe.Reader;
|
||||
|
||||
public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return WriteAsync(_emptyData, cancellationToken);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_contextLock)
|
||||
{
|
||||
if (_completed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_completed = true;
|
||||
_pipe.Writer.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void Abort(Exception error)
|
||||
{
|
||||
lock (_contextLock)
|
||||
{
|
||||
if (_completed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_completed = true;
|
||||
|
||||
_pipe.Reader.CancelPendingRead();
|
||||
_pipe.Writer.Complete(error);
|
||||
}
|
||||
}
|
||||
|
||||
public Task WriteAsync(
|
||||
ArraySegment<byte> buffer,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var writableBuffer = default(WritableBuffer);
|
||||
|
||||
lock (_contextLock)
|
||||
{
|
||||
if (_completed)
|
||||
{
|
||||
throw new ObjectDisposedException("Response is already completed");
|
||||
}
|
||||
|
||||
writableBuffer = _pipe.Writer.Alloc(1);
|
||||
// TODO obsolete
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var writer = new WritableBufferWriter(writableBuffer);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
writer.Write(buffer.Array, buffer.Offset, buffer.Count);
|
||||
}
|
||||
|
||||
writableBuffer.Commit();
|
||||
}
|
||||
|
||||
return FlushAsync(writableBuffer, cancellationToken);
|
||||
}
|
||||
|
||||
private Task FlushAsync(WritableBuffer writableBuffer,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var awaitable = writableBuffer.FlushAsync(cancellationToken);
|
||||
if (awaitable.IsCompleted)
|
||||
{
|
||||
// The flush task can't fail today
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
return FlushAsyncAwaited(awaitable, writableBuffer.BytesWritten, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task FlushAsyncAwaited(WritableBufferAwaitable awaitable, long count, CancellationToken cancellationToken)
|
||||
{
|
||||
// https://github.com/dotnet/corefxlab/issues/1334
|
||||
// Since the flush awaitable doesn't currently support multiple awaiters
|
||||
// we need to use a task to track the callbacks.
|
||||
// All awaiters get the same task
|
||||
lock (_flushLock)
|
||||
{
|
||||
if (_flushTcs == null || _flushTcs.Task.IsCompleted)
|
||||
{
|
||||
_flushTcs = new TaskCompletionSource<object>();
|
||||
|
||||
awaitable.OnCompleted(_flushCompleted);
|
||||
}
|
||||
}
|
||||
|
||||
await _flushTcs.Task;
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
private void OnFlushCompleted()
|
||||
{
|
||||
_flushTcs.TrySetResult(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
#if NETCOREAPP2_0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
@ -19,4 +19,4 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
"TestSites"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1026,4 +1026,4 @@
|
|||
</handlers>
|
||||
</system.webServer>
|
||||
</location>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
#if NETCOREAPP2_0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
using Xunit;
|
||||
using Xunit;
|
||||
|
||||
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]
|
||||
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||
{
|
||||
public class FeatureCollectionTest : LoggedTest
|
||||
{
|
||||
public FeatureCollectionTest(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
}
|
||||
|
||||
[Theory(Skip = "See https://github.com/aspnet/IISIntegration/issues/424")]
|
||||
[InlineData("SetRequestFeatures")]
|
||||
[InlineData("SetResponseFeatures")]
|
||||
[InlineData("SetConnectionFeatures")]
|
||||
public Task FeatureCollectionTest_SetHttpContextFeatures(string path)
|
||||
{
|
||||
return SetFeatures(RuntimeFlavor.CoreClr, ApplicationType.Portable, path);
|
||||
}
|
||||
|
||||
private async Task SetFeatures(RuntimeFlavor runtimeFlavor, ApplicationType applicationType, string path)
|
||||
{
|
||||
var serverType = ServerType.IISExpress;
|
||||
var architecture = RuntimeArchitecture.x64;
|
||||
var testName = $"SetFeatures_{runtimeFlavor}";
|
||||
using (StartLog(out var loggerFactory, testName))
|
||||
{
|
||||
var logger = loggerFactory.CreateLogger("SetFeaturesTest");
|
||||
|
||||
var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture)
|
||||
{
|
||||
EnvironmentName = "FeatureCollection", // Will pick the Start class named 'StartupFeatureCollection',
|
||||
ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Http.config") : null,
|
||||
SiteName = "HttpTestSite", // This is configured in the Http.config
|
||||
TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0",
|
||||
ApplicationType = applicationType,
|
||||
};
|
||||
|
||||
using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
|
||||
{
|
||||
var deploymentResult = await deployer.DeployAsync();
|
||||
deploymentResult.HttpClient.Timeout = TimeSpan.FromSeconds(5);
|
||||
|
||||
// Request to base address and check if various parts of the body are rendered & measure the cold startup time.
|
||||
var response = await RetryHelper.RetryRequest(() =>
|
||||
{
|
||||
return deploymentResult.HttpClient.GetAsync(path + "?query");
|
||||
}, logger, deploymentResult.HostShutdownToken, retryCount: 30);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
Assert.Equal("Success", responseText);
|
||||
}
|
||||
catch (XunitException)
|
||||
{
|
||||
logger.LogWarning(response.ToString());
|
||||
logger.LogWarning(responseText);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||
{
|
||||
public class HelloWorldTests : LoggedTest
|
||||
{
|
||||
public HelloWorldTests(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact( Skip ="See https://github.com/aspnet/IISIntegration/issues/424")]
|
||||
public Task HelloWorld_InProcess_IISExpress_CoreClr_X64_Portable()
|
||||
{
|
||||
return HelloWorld(RuntimeFlavor.CoreClr, ApplicationType.Portable);
|
||||
}
|
||||
|
||||
private async Task HelloWorld(RuntimeFlavor runtimeFlavor, ApplicationType applicationType)
|
||||
{
|
||||
var serverType = ServerType.IISExpress;
|
||||
var architecture = RuntimeArchitecture.x64;
|
||||
var testName = $"HelloWorld_{runtimeFlavor}";
|
||||
using (StartLog(out var loggerFactory, testName))
|
||||
{
|
||||
var logger = loggerFactory.CreateLogger("HelloWorldTest");
|
||||
|
||||
var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture)
|
||||
{
|
||||
EnvironmentName = "HelloWorld", // Will pick the Start class named 'StartupHelloWorld',
|
||||
ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Http.config") : null,
|
||||
SiteName = "HttpTestSite", // This is configured in the Http.config
|
||||
TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0",
|
||||
ApplicationType = applicationType
|
||||
};
|
||||
|
||||
using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
|
||||
{
|
||||
var deploymentResult = await deployer.DeployAsync();
|
||||
deploymentResult.HttpClient.Timeout = TimeSpan.FromSeconds(5);
|
||||
|
||||
// Request to base address and check if various parts of the body are rendered & measure the cold startup time.
|
||||
var response = await RetryHelper.RetryRequest(() =>
|
||||
{
|
||||
return deploymentResult.HttpClient.GetAsync(string.Empty);
|
||||
}, logger, deploymentResult.HostShutdownToken, retryCount: 30);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
Assert.Equal("Hello World", responseText);
|
||||
|
||||
response = await deploymentResult.HttpClient.GetAsync("/Path%3F%3F?query");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("/Path??", responseText);
|
||||
|
||||
response = await deploymentResult.HttpClient.GetAsync("/Query%3FPath?query?");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("?query?", responseText);
|
||||
}
|
||||
catch (XunitException)
|
||||
{
|
||||
logger.LogWarning(response.ToString());
|
||||
logger.LogWarning(responseText);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||
{
|
||||
public class Helpers
|
||||
{
|
||||
public static string GetTestSitesPath()
|
||||
{
|
||||
return Path.GetFullPath(
|
||||
Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
|
||||
"..", // tfm
|
||||
"..", // debug
|
||||
"..", // obj
|
||||
"..", // projectfolder
|
||||
"IISTestSite"));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="*.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||
{
|
||||
public class LargeResponseBodyTests : LoggedTest
|
||||
{
|
||||
|
||||
public LargeResponseBodyTests(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
}
|
||||
|
||||
[Theory(Skip = "See https://github.com/aspnet/IISIntegration/issues/424")]
|
||||
[InlineData(10000)]
|
||||
[InlineData(100000)]
|
||||
[InlineData(1000000)]
|
||||
[InlineData(10000000)]
|
||||
public Task LargeResponseBodyTestCheckAllResponseBodyBytesWritten(int query)
|
||||
{
|
||||
return LargeResponseBody(RuntimeFlavor.CoreClr, ApplicationType.Portable, query);
|
||||
}
|
||||
|
||||
private async Task LargeResponseBody(RuntimeFlavor runtimeFlavor, ApplicationType applicationType, int query)
|
||||
{
|
||||
var serverType = ServerType.IISExpress;
|
||||
var architecture = RuntimeArchitecture.x64;
|
||||
var testName = $"SetFeatures_{runtimeFlavor}";
|
||||
using (StartLog(out var loggerFactory, testName))
|
||||
{
|
||||
var logger = loggerFactory.CreateLogger("SetFeaturesTest");
|
||||
|
||||
var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture)
|
||||
{
|
||||
EnvironmentName = "LargeResponseBody", // Will pick the Start class named 'StartupLargeResponseBody',
|
||||
ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Http.config") : null,
|
||||
SiteName = "HttpTestSite", // This is configured in the Http.config
|
||||
TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0",
|
||||
ApplicationType = applicationType
|
||||
};
|
||||
|
||||
using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
|
||||
{
|
||||
var deploymentResult = await deployer.DeployAsync();
|
||||
deploymentResult.HttpClient.Timeout = TimeSpan.FromSeconds(5);
|
||||
|
||||
// Request to base address and check if various parts of the body are rendered & measure the cold startup time.
|
||||
var response = await RetryHelper.RetryRequest(() =>
|
||||
{
|
||||
return deploymentResult.HttpClient.GetAsync("LargeResponseBody?length=" + query);
|
||||
}, logger, deploymentResult.HostShutdownToken, retryCount: 30);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
Assert.Equal(new string('a', query), responseText);
|
||||
}
|
||||
catch (XunitException)
|
||||
{
|
||||
logger.LogWarning(response.ToString());
|
||||
logger.LogWarning(responseText);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact (Skip = "See https://github.com/aspnet/IISIntegration/issues/424")]
|
||||
public Task LargeFileResponseBodyInternalCheck()
|
||||
{
|
||||
return LargeResponseBodyFromFile(RuntimeFlavor.CoreClr, ApplicationType.Portable);
|
||||
}
|
||||
|
||||
private async Task LargeResponseBodyFromFile(RuntimeFlavor runtimeFlavor, ApplicationType applicationType)
|
||||
{
|
||||
var serverType = ServerType.IISExpress;
|
||||
var architecture = RuntimeArchitecture.x64;
|
||||
var testName = $"SetFeatures_{runtimeFlavor}";
|
||||
using (StartLog(out var loggerFactory, testName))
|
||||
{
|
||||
var logger = loggerFactory.CreateLogger("SetFeaturesTest");
|
||||
var expected = File.ReadAllText("Http.config");
|
||||
var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture)
|
||||
{
|
||||
EnvironmentName = "LargeResponseBody", // Will pick the Start class named 'StartupLargeResponseBody',
|
||||
ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? expected : null,
|
||||
SiteName = "HttpTestSite", // This is configured in the Http.config
|
||||
TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0",
|
||||
ApplicationType = applicationType,
|
||||
|
||||
};
|
||||
|
||||
using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
|
||||
{
|
||||
var deploymentResult = await deployer.DeployAsync();
|
||||
deploymentResult.HttpClient.Timeout = TimeSpan.FromSeconds(5);
|
||||
|
||||
// Request to base address and check if various parts of the body are rendered & measure the cold startup time.
|
||||
var response = await RetryHelper.RetryRequest(() =>
|
||||
{
|
||||
return deploymentResult.HttpClient.GetAsync("LargeResponseBodyFromFile");
|
||||
}, logger, deploymentResult.HostShutdownToken, retryCount: 30);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
Assert.Equal(expected, responseText);
|
||||
}
|
||||
catch (XunitException)
|
||||
{
|
||||
logger.LogWarning(response.ToString());
|
||||
logger.LogWarning(responseText);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||
{
|
||||
public class ResponseInvalidOrderingTests : LoggedTest
|
||||
{
|
||||
public ResponseInvalidOrderingTests(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
}
|
||||
|
||||
[Theory(Skip = "See https://github.com/aspnet/IISIntegration/issues/424")]
|
||||
[InlineData("SetStatusCodeAfterWrite")]
|
||||
[InlineData("SetHeaderAfterWrite")]
|
||||
public Task ResponseInvalidOrderingTests_ExpectFailure(string path)
|
||||
{
|
||||
return SetResponseInvalidOperations(RuntimeFlavor.CoreClr, ApplicationType.Portable, path);
|
||||
}
|
||||
|
||||
private async Task SetResponseInvalidOperations(RuntimeFlavor runtimeFlavor, ApplicationType applicationType, string path)
|
||||
{
|
||||
var serverType = ServerType.IISExpress;
|
||||
var architecture = RuntimeArchitecture.x64;
|
||||
var testName = $"SetResponseInvalidOperations_{runtimeFlavor}";
|
||||
using (StartLog(out var loggerFactory, testName))
|
||||
{
|
||||
var logger = loggerFactory.CreateLogger("SetFeaturesTest");
|
||||
|
||||
var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(), serverType, runtimeFlavor, architecture)
|
||||
{
|
||||
EnvironmentName = "ResponseInvalidOrdering", // Will pick the Start class named 'StartupInvalidOrdering',
|
||||
ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("Http.config") : null,
|
||||
SiteName = "HttpTestSite", // This is configured in the Http.config
|
||||
TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0",
|
||||
ApplicationType = applicationType
|
||||
};
|
||||
|
||||
using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
|
||||
{
|
||||
var deploymentResult = await deployer.DeployAsync();
|
||||
deploymentResult.HttpClient.Timeout = TimeSpan.FromSeconds(5);
|
||||
|
||||
// Request to base address and check if various parts of the body are rendered & measure the cold startup time.
|
||||
var response = await RetryHelper.RetryRequest(() =>
|
||||
{
|
||||
return deploymentResult.HttpClient.GetAsync(path);
|
||||
}, logger, deploymentResult.HostShutdownToken, retryCount: 30);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
Assert.Equal($"Started_{path}Threw_Finished", responseText);
|
||||
}
|
||||
catch (XunitException)
|
||||
{
|
||||
logger.LogWarning(response.ToString());
|
||||
logger.LogWarning(responseText);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.AspNetCoreModule" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
|
||||
<PackageReference Include="xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.IIS;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IISTestSite
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.ConfigureLogging((_, factory) =>
|
||||
{
|
||||
factory.AddConsole();
|
||||
factory.AddFilter("Console", level => level >= LogLevel.Information);
|
||||
})
|
||||
.UseNativeIIS()
|
||||
.UseStartup("IISTestSite")
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:2418/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IISTestSite": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace IISTestSite
|
||||
{
|
||||
public class StartupFeatureCollection
|
||||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
app.Run(async context =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// Verify setting and getting each feature/ portion of the httpcontext works
|
||||
if (context.Request.Path.Equals("/SetRequestFeatures"))
|
||||
{
|
||||
|
||||
Assert.Equal("GET", context.Request.Method);
|
||||
context.Request.Method = "test";
|
||||
Assert.Equal("test", context.Request.Method);
|
||||
|
||||
Assert.Equal("http", context.Request.Scheme);
|
||||
context.Request.Scheme = "test";
|
||||
Assert.Equal("test", context.Request.Scheme);
|
||||
|
||||
Assert.Equal("", context.Request.PathBase);
|
||||
context.Request.PathBase = "/base";
|
||||
Assert.Equal("/base", context.Request.PathBase);
|
||||
|
||||
Assert.Equal("/SetRequestFeatures", context.Request.Path);
|
||||
context.Request.Path = "/path";
|
||||
Assert.Equal("/path", context.Request.Path);
|
||||
|
||||
Assert.Equal("?query", context.Request.QueryString.Value);
|
||||
context.Request.QueryString = QueryString.Empty;
|
||||
Assert.Equal("", context.Request.QueryString.Value);
|
||||
|
||||
Assert.Equal("HTTP/1.1", context.Request.Protocol);
|
||||
context.Request.Protocol = "HTTP/1.0";
|
||||
Assert.Equal("HTTP/1.0", context.Request.Protocol);
|
||||
|
||||
Assert.NotNull(context.Request.Headers);
|
||||
var headers = new HeaderDictionary();
|
||||
context.Features.Get<IHttpRequestFeature>().Headers = headers;
|
||||
Assert.Same(headers, context.Features.Get<IHttpRequestFeature>().Headers);
|
||||
|
||||
Assert.NotNull(context.Request.Body);
|
||||
var body = new MemoryStream();
|
||||
context.Request.Body = body;
|
||||
Assert.Same(body, context.Request.Body);
|
||||
|
||||
//Assert.NotNull(context.Features.Get<IHttpRequestIdentifierFeature>().TraceIdentifier);
|
||||
//Assert.NotEqual(CancellationToken.None, context.RequestAborted);
|
||||
//var token = new CancellationTokenSource().Token;
|
||||
//context.RequestAborted = token;
|
||||
//Assert.Equal(token, context.RequestAborted);
|
||||
|
||||
await context.Response.WriteAsync("Success");
|
||||
return;
|
||||
}
|
||||
else if (context.Request.Path.Equals("/SetResponseFeatures"))
|
||||
{
|
||||
Assert.Equal(200, context.Response.StatusCode);
|
||||
context.Response.StatusCode = 404;
|
||||
Assert.Equal(404, context.Response.StatusCode);
|
||||
|
||||
Assert.Null(context.Features.Get<IHttpResponseFeature>().ReasonPhrase);
|
||||
context.Features.Get<IHttpResponseFeature>().ReasonPhrase = "Set Response";
|
||||
Assert.Equal("Set Response", context.Features.Get<IHttpResponseFeature>().ReasonPhrase);
|
||||
|
||||
Assert.NotNull(context.Response.Headers);
|
||||
var headers = new HeaderDictionary();
|
||||
context.Features.Get<IHttpResponseFeature>().Headers = headers;
|
||||
Assert.Same(headers, context.Features.Get<IHttpResponseFeature>().Headers);
|
||||
|
||||
var originalBody = context.Response.Body;
|
||||
Assert.NotNull(originalBody);
|
||||
var body = new MemoryStream();
|
||||
context.Response.Body = body;
|
||||
Assert.Same(body, context.Response.Body);
|
||||
context.Response.Body = originalBody;
|
||||
|
||||
await context.Response.WriteAsync("Success");
|
||||
return;
|
||||
}
|
||||
else if (context.Request.Path.Equals("/SetConnectionFeatures"))
|
||||
{
|
||||
Assert.True(IPAddress.IsLoopback(context.Connection.LocalIpAddress));
|
||||
context.Connection.LocalIpAddress = IPAddress.IPv6Any;
|
||||
Assert.Equal(IPAddress.IPv6Any, context.Connection.LocalIpAddress);
|
||||
|
||||
Assert.True(IPAddress.IsLoopback(context.Connection.RemoteIpAddress));
|
||||
context.Connection.RemoteIpAddress = IPAddress.IPv6Any;
|
||||
Assert.Equal(IPAddress.IPv6Any, context.Connection.RemoteIpAddress);
|
||||
await context.Response.WriteAsync("Success");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
await context.Response.WriteAsync(exception.ToString());
|
||||
}
|
||||
await context.Response.WriteAsync("_Failure");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IISTestSite
|
||||
{
|
||||
public class StartupHelloWorld
|
||||
{
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
app.Run(async ctx =>
|
||||
{
|
||||
if (ctx.Request.Path.Value.StartsWith("/Path"))
|
||||
{
|
||||
await ctx.Response.WriteAsync(ctx.Request.Path.Value);
|
||||
return;
|
||||
}
|
||||
if (ctx.Request.Path.Value.StartsWith("/Query"))
|
||||
{
|
||||
await ctx.Response.WriteAsync(ctx.Request.QueryString.Value);
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.Response.WriteAsync("Hello World");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IISTestSite
|
||||
{
|
||||
public class StartupHttpsHelloWorld
|
||||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
app.Run(async ctx =>
|
||||
{
|
||||
if (ctx.Request.Path.Value.StartsWith("/ClientCertificate"))
|
||||
{
|
||||
await ctx.Response.WriteAsync($"{ ctx.Request.Scheme }Hello World, Cert: {ctx.Connection.ClientCertificate != null}");
|
||||
return;
|
||||
}
|
||||
await ctx.Response.WriteAsync(ctx.Request.Scheme + "Hello World");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IISTestSite
|
||||
{
|
||||
public class StartupLargeResponseBody
|
||||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
app.Run(async context =>
|
||||
{
|
||||
if (context.Request.Path.Equals("/LargeResponseBody"))
|
||||
{
|
||||
if (int.TryParse(context.Request.Query["length"], out var length))
|
||||
{
|
||||
await context.Response.WriteAsync(new string('a', length));
|
||||
}
|
||||
}
|
||||
else if (context.Request.Path.Equals("/LargeResponseBodyFromFile"))
|
||||
{
|
||||
var fileString = File.ReadAllText("Http.config");
|
||||
await context.Response.WriteAsync(fileString);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IISTestSite
|
||||
{
|
||||
public class StartupResponseInvalidOrdering
|
||||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
app.Run(async context =>
|
||||
{
|
||||
if (context.Request.Path.Equals("/SetStatusCodeAfterWrite"))
|
||||
{
|
||||
await context.Response.WriteAsync("Started_");
|
||||
try
|
||||
{
|
||||
context.Response.StatusCode = 200;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
await context.Response.WriteAsync("SetStatusCodeAfterWriteThrew_");
|
||||
}
|
||||
await context.Response.WriteAsync("Finished");
|
||||
return;
|
||||
}
|
||||
else if (context.Request.Path.Equals("/SetHeaderAfterWrite"))
|
||||
{
|
||||
await context.Response.WriteAsync("Started_");
|
||||
try
|
||||
{
|
||||
context.Response.Headers["This will fail"] = "some value";
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
await context.Response.WriteAsync("SetHeaderAfterWriteThrew_");
|
||||
}
|
||||
await context.Response.WriteAsync("Finished");
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" hostingModel="inprocess"/>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true" />
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
|
|
|||
Loading…
Reference in New Issue