You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
78
external/corefx/src/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.sln
vendored
Normal file
78
external/corefx/src/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.sln
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22816.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{BB2D2F6C-0445-43D4-84A9-DF5B4931FA19}") = "System.Net.Http.WinHttpHandler.Unit.Tests", "tests\UnitTests\System.Net.Http.WinHttpHandler.Unit.Tests.csproj", "{A2ECDEDB-12B7-402C-9230-152B7601179F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{} = {}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{BB2D2F6C-0445-43D4-84A9-DF5B4931FA19}") = "System.Net.Http.WinHttpHandler.Functional.Tests", "tests\FunctionalTests\System.Net.Http.WinHttpHandler.Functional.Tests.csproj", "{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{} = {}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{BB2D2F6C-0445-43D4-84A9-DF5B4931FA19}") = "System.Net.Http.WinHttpHandler.Functional.Tests", "tests\FunctionalTests\System.Net.Http.WinHttpHandler.Functional.Tests.csproj", "{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E} = {F75E3008-0562-42DF-BE72-C1384F12157E}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{BB2D2F6C-0445-43D4-84A9-DF5B4931FA19}") = "System.Net.Http.WinHttpHandler.Unit.Tests", "tests\UnitTests\System.Net.Http.WinHttpHandler.Unit.Tests.csproj", "{A2ECDEDB-12B7-402C-9230-152B7601179F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E} = {F75E3008-0562-42DF-BE72-C1384F12157E}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{BB2D2F6C-0445-43D4-84A9-DF5B4931FA19}") = "System.Net.Http.WinHttpHandler", "src\System.Net.Http.WinHttpHandler.csproj", "{F75E3008-0562-42DF-BE72-C1384F12157E}"
|
||||
EndProject
|
||||
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU = DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU = ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU
|
||||
DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU = DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU = ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU
|
||||
DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU = DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU
|
||||
ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU = ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{17D5CC82-F72C-4DD2-B6DB-DE7FB2F19C34}.ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{A2ECDEDB-12B7-402C-9230-152B7601179F}.ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.DebugNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Debug|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.ReleaseNETCoreAppnetstandard1.3-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Windows_NT-Release|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Unix-Debug|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.DebugNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Unix-Debug|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = netstandard1.3-Unix-Release|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.ReleaseNETCoreAppnetstandard1.3-Unixnetstandard1.3-Windows_NT|AnyCPU.Build.0 = netstandard1.3-Unix-Release|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = net46-Windows_NT-Debug|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.DebugNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = net46-Windows_NT-Debug|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.ActiveCfg = net46-Windows_NT-Release|Any CPU
|
||||
{F75E3008-0562-42DF-BE72-C1384F12157E}.ReleaseNETCoreAppnet46-Windows_NTnetstandard1.3-Windows_NT|AnyCPU.Build.0 = net46-Windows_NT-Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
7
external/corefx/src/System.Net.Http.WinHttpHandler/dir.props
vendored
Normal file
7
external/corefx/src/System.Net.Http.WinHttpHandler/dir.props
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\dir.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>4.0.2.0</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
8
external/corefx/src/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.builds
vendored
Normal file
8
external/corefx/src/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.builds
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<ItemGroup>
|
||||
<Project Include="System.Net.Http.WinHttpHandler.pkgproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
|
||||
</Project>
|
||||
14
external/corefx/src/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.pkgproj
vendored
Normal file
14
external/corefx/src/System.Net.Http.WinHttpHandler/pkg/System.Net.Http.WinHttpHandler.pkgproj
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ref\System.Net.Http.WinHttpHandler.csproj">
|
||||
<SupportedFramework>net46;netcoreapp1.0</SupportedFramework>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\src\System.Net.Http.WinHttpHandler.builds" />
|
||||
<NotSupportedOnTargetFramework Include="netcore50">
|
||||
<PackageTargetRuntime>win</PackageTargetRuntime>
|
||||
</NotSupportedOnTargetFramework>
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
8
external/corefx/src/System.Net.Http.WinHttpHandler/ref/Configurations.props
vendored
Normal file
8
external/corefx/src/System.Net.Http.WinHttpHandler/ref/Configurations.props
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netstandard;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
52
external/corefx/src/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.cs
vendored
Normal file
52
external/corefx/src/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.cs
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
// ------------------------------------------------------------------------------
|
||||
// Changes to this file must follow the http://aka.ms/api-review process.
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
public enum CookieUsePolicy
|
||||
{
|
||||
IgnoreCookies = 0,
|
||||
UseInternalCookieStoreOnly = 1,
|
||||
UseSpecifiedCookieContainer = 2,
|
||||
}
|
||||
public enum WindowsProxyUsePolicy
|
||||
{
|
||||
DoNotUseProxy = 0,
|
||||
UseCustomProxy = 3,
|
||||
UseWinHttpProxy = 1,
|
||||
UseWinInetProxy = 2,
|
||||
}
|
||||
public partial class WinHttpHandler : System.Net.Http.HttpMessageHandler
|
||||
{
|
||||
public WinHttpHandler() { }
|
||||
public System.Net.DecompressionMethods AutomaticDecompression { get { throw null; } set { } }
|
||||
public bool AutomaticRedirection { get { throw null; } set { } }
|
||||
public bool CheckCertificateRevocationList { get { throw null; } set { } }
|
||||
public System.Net.Http.ClientCertificateOption ClientCertificateOption { get { throw null; } set { } }
|
||||
public System.Security.Cryptography.X509Certificates.X509Certificate2Collection ClientCertificates { get { throw null; } }
|
||||
public System.Net.CookieContainer CookieContainer { get { throw null; } set { } }
|
||||
public System.Net.Http.CookieUsePolicy CookieUsePolicy { get { throw null; } set { } }
|
||||
public System.Net.ICredentials DefaultProxyCredentials { get { throw null; } set { } }
|
||||
public int MaxAutomaticRedirections { get { throw null; } set { } }
|
||||
public int MaxConnectionsPerServer { get { throw null; } set { } }
|
||||
public int MaxResponseDrainSize { get { throw null; } set { } }
|
||||
public int MaxResponseHeadersLength { get { throw null; } set { } }
|
||||
public bool PreAuthenticate { get { throw null; } set { } }
|
||||
public System.Collections.Generic.IDictionary<string, object> Properties { get { throw null; } }
|
||||
public System.Net.IWebProxy Proxy { get { throw null; } set { } }
|
||||
public System.TimeSpan ReceiveDataTimeout { get { throw null; } set { } }
|
||||
public System.TimeSpan ReceiveHeadersTimeout { get { throw null; } set { } }
|
||||
public System.TimeSpan SendTimeout { get { throw null; } set { } }
|
||||
public System.Func<System.Net.Http.HttpRequestMessage, System.Security.Cryptography.X509Certificates.X509Certificate2, System.Security.Cryptography.X509Certificates.X509Chain, System.Net.Security.SslPolicyErrors, bool> ServerCertificateValidationCallback { get { throw null; } set { } }
|
||||
public System.Net.ICredentials ServerCredentials { get { throw null; } set { } }
|
||||
public System.Security.Authentication.SslProtocols SslProtocols { get { throw null; } set { } }
|
||||
public System.Net.Http.WindowsProxyUsePolicy WindowsProxyUsePolicy { get { throw null; } set { } }
|
||||
protected override void Dispose(bool disposing) { }
|
||||
protected override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
|
||||
}
|
||||
}
|
||||
10
external/corefx/src/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.csproj
vendored
Normal file
10
external/corefx/src/System.Net.Http.WinHttpHandler/ref/System.Net.Http.WinHttpHandler.csproj
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="System.Net.Http.WinHttpHandler.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
12
external/corefx/src/System.Net.Http.WinHttpHandler/src/Configurations.props
vendored
Normal file
12
external/corefx/src/System.Net.Http.WinHttpHandler/src/Configurations.props
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netstandard1.3-Windows_NT;
|
||||
netstandard1.3-Unix;
|
||||
netstandard-Windows_NT;
|
||||
netstandard-Unix;
|
||||
net46-Windows_NT;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
183
external/corefx/src/System.Net.Http.WinHttpHandler/src/Resources/Strings.resx
vendored
Normal file
183
external/corefx/src/System.Net.Http.WinHttpHandler/src/Resources/Strings.resx
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="net_securityprotocolnotsupported" xml:space="preserve">
|
||||
<value>The requested security protocol is not supported.</value>
|
||||
</data>
|
||||
<data name="net_http_invalid_cookiecontainer" xml:space="preserve">
|
||||
<value>When using CookieUsePolicy.UseSpecifiedCookieContainer, the CookieContainer property must not be null.</value>
|
||||
</data>
|
||||
<data name="net_http_invalid_proxyusepolicy" xml:space="preserve">
|
||||
<value>When using a non-null Proxy, the WindowsProxyUsePolicy property must be set to WindowsProxyUsePolicy.UseCustomProxy.</value>
|
||||
</data>
|
||||
<data name="net_http_invalid_proxy" xml:space="preserve">
|
||||
<value>When using WindowsProxyUsePolicy.UseCustomProxy, the Proxy property must not be null.</value>
|
||||
</data>
|
||||
<data name="net_http_content_buffersize_limit" xml:space="preserve">
|
||||
<value>Buffering more than {0} bytes is not supported.</value>
|
||||
</data>
|
||||
<data name="net_http_handler_norequest" xml:space="preserve">
|
||||
<value>A request message must be provided. It cannot be null.</value>
|
||||
</data>
|
||||
<data name="net_http_operation_started" xml:space="preserve">
|
||||
<value>This instance has already started one or more requests. Properties can only be modified before sending the first request.</value>
|
||||
</data>
|
||||
<data name="net_http_client_execution_error" xml:space="preserve">
|
||||
<value>An error occurred while sending the request.</value>
|
||||
</data>
|
||||
<data name="net_http_io_read" xml:space="preserve">
|
||||
<value>The read operation failed, see inner exception.</value>
|
||||
</data>
|
||||
<data name="net_http_io_read_incomplete" xml:space="preserve">
|
||||
<value>Unable to read data from the transport connection. The connection was closed before all data could be read. Expected {0} bytes, read {1} bytes.</value>
|
||||
</data>
|
||||
<data name="net_http_io_write" xml:space="preserve">
|
||||
<value>The write operation failed, see inner exception.</value>
|
||||
</data>
|
||||
<data name="net_http_chunked_not_allowed_with_empty_content" xml:space="preserve">
|
||||
<value>'Transfer-Encoding: chunked' header can not be used when content object is not specified.</value>
|
||||
</data>
|
||||
<data name="net_http_value_must_be_greater_than" xml:space="preserve">
|
||||
<value>The specified value must be greater than {0}.</value>
|
||||
</data>
|
||||
<data name="net_http_username_empty_string" xml:space="preserve">
|
||||
<value>The username for a credential object cannot be null or empty.</value>
|
||||
</data>
|
||||
<data name="net_http_no_concurrent_io_allowed" xml:space="preserve">
|
||||
<value>The stream does not support concurrent I/O read or write operations.</value>
|
||||
</data>
|
||||
<data name="net_http_buffer_insufficient_length" xml:space="preserve">
|
||||
<value>The buffer was not long enough.</value>
|
||||
</data>
|
||||
<data name="ArgumentOutOfRange_NeedPosNum" xml:space="preserve">
|
||||
<value>Positive number required.</value>
|
||||
</data>
|
||||
<data name="NotSupported_UnreadableStream" xml:space="preserve">
|
||||
<value>Stream does not support reading.</value>
|
||||
</data>
|
||||
<data name="NotSupported_UnwritableStream" xml:space="preserve">
|
||||
<value>Stream does not support writing.</value>
|
||||
</data>
|
||||
<data name="ObjectDisposed_StreamClosed" xml:space="preserve">
|
||||
<value>Can not access a closed Stream.</value>
|
||||
</data>
|
||||
<data name="net_http_content_stream_already_read" xml:space="preserve">
|
||||
<value>The stream was already consumed. It cannot be read again.</value>
|
||||
</data>
|
||||
</root>
|
||||
66
external/corefx/src/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj
vendored
Normal file
66
external/corefx/src/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{F75E3008-0562-42DF-BE72-C1384F12157E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AssemblyName>System.Net.Http.WinHttpHandler</AssemblyName>
|
||||
<GeneratePlatformNotSupportedAssembly Condition="'$(TargetsUnix)' == 'true'">true</GeneratePlatformNotSupportedAssembly>
|
||||
</PropertyGroup>
|
||||
<!-- Help VS understand available configurations -->
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard1.3-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard1.3-Windows_NT-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard1.3-Unix-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard1.3-Unix-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard-Windows_NT-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard-Unix-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard-Unix-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net46-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='net46-Windows_NT-Release|AnyCPU'" />
|
||||
<Import Project="System.Net.Http.WinHttpHandler.msbuild" Condition="'$(TargetsWindows)' == 'true'" />
|
||||
<ItemGroup Condition="'$(TargetGroup)' == 'net46'">
|
||||
<!-- Need to compile it here since the NET46 target here is building against System.Runtime whereas the
|
||||
the list of other files in System.Net.Http.WinHttpHandler.msbuild is also used by System.Net.Http
|
||||
library and the NET46 target there uses framework assembly references instead. -->
|
||||
<CompileItem Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeHandleZeroOrMinusOneIsInvalid.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\HttpStatusDescription.cs" />
|
||||
</ItemGroup>
|
||||
<!-- For source files to be shown within the visual tree in Solution Explorer, the items must be
|
||||
included directly in the project file. We have the *.msbuild define the Compile items in a made
|
||||
up item called CompileItem and then just include it here. -->
|
||||
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' ">
|
||||
<Compile Include="@(CompileItem)" />
|
||||
<Compile Include="$(CommonPath)\System\IO\StreamHelpers.CopyValidation.cs">
|
||||
<Link>Common\System\IO\StreamHelpers.CopyValidation.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\HttpVersionInternal.cs">
|
||||
<Link>Common\System\Net\HttpVersionInternal.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Buffers" />
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)' == 'netstandard1.3'">
|
||||
<Reference Include="Microsoft.Win32.Primitives" />
|
||||
<Reference Include="System.Collections" />
|
||||
<Reference Include="System.Collections.NonGeneric" />
|
||||
<Reference Include="System.Diagnostics.Debug" />
|
||||
<Reference Include="System.IO" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Primitives" />
|
||||
<Reference Include="System.Resources.ResourceManager" />
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.Extensions" />
|
||||
<Reference Include="System.Runtime.Handles" />
|
||||
<Reference Include="System.Runtime.InteropServices" />
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates" />
|
||||
<Reference Include="System.Text.Encoding" />
|
||||
<Reference Include="System.Threading" />
|
||||
<Reference Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
47
external/corefx/src/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.msbuild
vendored
Normal file
47
external/corefx/src/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.msbuild
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\Crypt32\Interop.certificates_types.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\Crypt32\Interop.certificates.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\kernel32\Interop.FormatMessage.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\kernel32\Interop.GetModuleHandle.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\Interop.HRESULT_FROM_WIN32.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\winhttp\Interop.SafeWinHttpHandle.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\winhttp\Interop.winhttp_types.cs" />
|
||||
<CompileItem Include="$(CommonPath)\Interop\Windows\winhttp\Interop.winhttp.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\CharArrayHelpers.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\StringExtensions.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Diagnostics\ExceptionExtensions.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\HttpKnownHeaderNames.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\HttpKnownHeaderNames.TryGetHeaderName.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\UriScheme.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\SecurityProtocol.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\Http\HttpHandlerDefaults.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\Http\HttpHandlerDiagnosticListenerExtensions.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\Http\HttpHandlerLoggingStrings.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\Http\NoWriteNoSeekStreamContent.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Net\Http\WinHttpException.cs" />
|
||||
<CompileItem Include="$(CommonPath)\System\Threading\Tasks\RendezvousAwaitable.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpAuthHelper.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpCertificateHelper.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpChannelBinding.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpCookieContainerAdapter.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpHandler.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpRequestCallback.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpRequestState.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpRequestStream.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpResponseHeaderReader.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpResponseParser.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpResponseStream.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpTraceHelper.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinHttpTransportContext.cs" />
|
||||
<CompileItem Include="$(MSBuildThisFileDirectory)\System\Net\Http\WinInetProxyHelper.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)' != 'net46'">
|
||||
<CompileItem Include="$(CommonPath)\System\Net\HttpStatusDescription.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
387
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpAuthHelper.cs
vendored
Normal file
387
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpAuthHelper.cs
vendored
Normal file
@@ -0,0 +1,387 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
internal class WinHttpAuthHelper
|
||||
{
|
||||
// TODO: Issue #2165. This looks messy but it is fast. Research a cleaner way
|
||||
// to do this which keeps high performance lookup.
|
||||
//
|
||||
// Fast lookup table to convert WINHTTP_AUTH constants to strings.
|
||||
// WINHTTP_AUTH_SCHEME_BASIC = 0x00000001;
|
||||
// WINHTTP_AUTH_SCHEME_NTLM = 0x00000002;
|
||||
// WINHTTP_AUTH_SCHEME_DIGEST = 0x00000008;
|
||||
// WINHTTP_AUTH_SCHEME_NEGOTIATE = 0x00000010;
|
||||
private static readonly string[] s_authSchemeStringMapping =
|
||||
{
|
||||
null,
|
||||
"Basic",
|
||||
"NTLM",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"Digest",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"Negotiate"
|
||||
};
|
||||
|
||||
private static readonly uint[] s_authSchemePriorityOrder =
|
||||
{
|
||||
Interop.WinHttp.WINHTTP_AUTH_SCHEME_NEGOTIATE,
|
||||
Interop.WinHttp.WINHTTP_AUTH_SCHEME_NTLM,
|
||||
Interop.WinHttp.WINHTTP_AUTH_SCHEME_DIGEST,
|
||||
Interop.WinHttp.WINHTTP_AUTH_SCHEME_BASIC
|
||||
};
|
||||
|
||||
// TODO: Issue #2165. This current design uses a handler-wide lock to Add/Retrieve
|
||||
// from the cache. Need to improve this for next iteration in order
|
||||
// to boost performance and scalability.
|
||||
private readonly CredentialCache _credentialCache = new CredentialCache();
|
||||
private readonly object _credentialCacheLock = new object();
|
||||
|
||||
public void CheckResponseForAuthentication(
|
||||
WinHttpRequestState state,
|
||||
ref uint proxyAuthScheme,
|
||||
ref uint serverAuthScheme)
|
||||
{
|
||||
uint supportedSchemes = 0;
|
||||
uint firstSchemeIgnored = 0;
|
||||
uint authTarget = 0;
|
||||
Uri uri = state.RequestMessage.RequestUri;
|
||||
|
||||
state.RetryRequest = false;
|
||||
|
||||
// Check the status code and retry the request applying credentials if needed.
|
||||
var statusCode = (HttpStatusCode)WinHttpResponseParser.GetResponseHeaderNumberInfo(
|
||||
state.RequestHandle,
|
||||
Interop.WinHttp.WINHTTP_QUERY_STATUS_CODE);
|
||||
|
||||
switch (statusCode)
|
||||
{
|
||||
case HttpStatusCode.Unauthorized:
|
||||
if (state.ServerCredentials == null || state.LastStatusCode == HttpStatusCode.Unauthorized)
|
||||
{
|
||||
// Either we don't have server credentials or we already tried
|
||||
// to set the credentials and it failed before.
|
||||
// So we will let the 401 be the final status code returned.
|
||||
break;
|
||||
}
|
||||
|
||||
state.LastStatusCode = statusCode;
|
||||
|
||||
// Determine authorization scheme to use. We ignore the firstScheme
|
||||
// parameter which is included in the supportedSchemes flags already.
|
||||
// We pass the schemes to ChooseAuthScheme which will pick the scheme
|
||||
// based on most secure scheme to least secure scheme ordering.
|
||||
if (!Interop.WinHttp.WinHttpQueryAuthSchemes(
|
||||
state.RequestHandle,
|
||||
out supportedSchemes,
|
||||
out firstSchemeIgnored,
|
||||
out authTarget))
|
||||
{
|
||||
// WinHTTP returns an error for schemes it doesn't handle.
|
||||
// So, we need to ignore the error and just let it stay at 401.
|
||||
break;
|
||||
}
|
||||
|
||||
// WinHTTP returns the proper authTarget based on the status code (401, 407).
|
||||
// But we can validate with assert.
|
||||
Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_SERVER);
|
||||
|
||||
serverAuthScheme = ChooseAuthScheme(supportedSchemes);
|
||||
if (serverAuthScheme != 0)
|
||||
{
|
||||
if (SetWinHttpCredential(
|
||||
state.RequestHandle,
|
||||
state.ServerCredentials,
|
||||
uri,
|
||||
serverAuthScheme,
|
||||
authTarget))
|
||||
{
|
||||
state.RetryRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HttpStatusCode.ProxyAuthenticationRequired:
|
||||
if (state.LastStatusCode == HttpStatusCode.ProxyAuthenticationRequired)
|
||||
{
|
||||
// We tried already to set the credentials.
|
||||
break;
|
||||
}
|
||||
|
||||
state.LastStatusCode = statusCode;
|
||||
|
||||
// If we don't have any proxy credentials to try, then we end up with 407.
|
||||
ICredentials proxyCreds = state.Proxy == null ?
|
||||
state.DefaultProxyCredentials :
|
||||
state.Proxy.Credentials;
|
||||
if (proxyCreds == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine authorization scheme to use. We ignore the firstScheme
|
||||
// parameter which is included in the supportedSchemes flags already.
|
||||
// We pass the schemes to ChooseAuthScheme which will pick the scheme
|
||||
// based on most secure scheme to least secure scheme ordering.
|
||||
if (!Interop.WinHttp.WinHttpQueryAuthSchemes(
|
||||
state.RequestHandle,
|
||||
out supportedSchemes,
|
||||
out firstSchemeIgnored,
|
||||
out authTarget))
|
||||
{
|
||||
// WinHTTP returns an error for schemes it doesn't handle.
|
||||
// So, we need to ignore the error and just let it stay at 401.
|
||||
break;
|
||||
}
|
||||
|
||||
// WinHTTP returns the proper authTarget based on the status code (401, 407).
|
||||
// But we can validate with assert.
|
||||
Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY);
|
||||
|
||||
proxyAuthScheme = ChooseAuthScheme(supportedSchemes);
|
||||
state.RetryRequest = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (state.PreAuthenticate && serverAuthScheme != 0)
|
||||
{
|
||||
SaveServerCredentialsToCache(uri, serverAuthScheme, state.ServerCredentials);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void PreAuthenticateRequest(WinHttpRequestState state, uint proxyAuthScheme)
|
||||
{
|
||||
// Set proxy credentials if we have them.
|
||||
// If a proxy authentication challenge was responded to, reset
|
||||
// those credentials before each SendRequest, because the proxy
|
||||
// may require re-authentication after responding to a 401 or
|
||||
// to a redirect. If you don't, you can get into a
|
||||
// 407-401-407-401- loop.
|
||||
if (proxyAuthScheme != 0)
|
||||
{
|
||||
ICredentials proxyCredentials;
|
||||
Uri proxyUri;
|
||||
if (state.Proxy != null)
|
||||
{
|
||||
proxyCredentials = state.Proxy.Credentials;
|
||||
proxyUri = state.Proxy.GetProxy(state.RequestMessage.RequestUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyCredentials = state.DefaultProxyCredentials;
|
||||
proxyUri = state.RequestMessage.RequestUri;
|
||||
}
|
||||
|
||||
SetWinHttpCredential(
|
||||
state.RequestHandle,
|
||||
proxyCredentials,
|
||||
proxyUri,
|
||||
proxyAuthScheme,
|
||||
Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY);
|
||||
}
|
||||
|
||||
// Apply pre-authentication headers for server authentication?
|
||||
if (state.PreAuthenticate)
|
||||
{
|
||||
uint authScheme;
|
||||
NetworkCredential serverCredentials;
|
||||
if (GetServerCredentialsFromCache(
|
||||
state.RequestMessage.RequestUri,
|
||||
out authScheme,
|
||||
out serverCredentials))
|
||||
{
|
||||
SetWinHttpCredential(
|
||||
state.RequestHandle,
|
||||
serverCredentials,
|
||||
state.RequestMessage.RequestUri,
|
||||
authScheme,
|
||||
Interop.WinHttp.WINHTTP_AUTH_TARGET_SERVER);
|
||||
state.LastStatusCode = HttpStatusCode.Unauthorized; // Remember we already set the creds.
|
||||
}
|
||||
|
||||
// No cached credential to use at this time. The request will first go out with no
|
||||
// 'Authorization' header. Later, if a 401 occurs, we will be able to cache the credential
|
||||
// since we will then know the proper auth scheme to use.
|
||||
//
|
||||
// TODO: Issue #2165. Adding logging to highlight the 'cache miss'.
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Issue #2165. Consider refactoring cache logic in separate class and avoid out parameters.
|
||||
public bool GetServerCredentialsFromCache(
|
||||
Uri uri,
|
||||
out uint serverAuthScheme,
|
||||
out NetworkCredential serverCredentials)
|
||||
{
|
||||
serverAuthScheme = 0;
|
||||
serverCredentials = null;
|
||||
|
||||
NetworkCredential cred = null;
|
||||
|
||||
lock (_credentialCacheLock)
|
||||
{
|
||||
foreach (uint authScheme in s_authSchemePriorityOrder)
|
||||
{
|
||||
cred = _credentialCache.GetCredential(uri, s_authSchemeStringMapping[authScheme]);
|
||||
if (cred != null)
|
||||
{
|
||||
serverAuthScheme = authScheme;
|
||||
serverCredentials = cred;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SaveServerCredentialsToCache(Uri uri, uint authScheme, ICredentials serverCredentials)
|
||||
{
|
||||
string authType = s_authSchemeStringMapping[authScheme];
|
||||
Debug.Assert(!string.IsNullOrEmpty(authType));
|
||||
|
||||
NetworkCredential cred = serverCredentials.GetCredential(uri, authType);
|
||||
if (cred != null)
|
||||
{
|
||||
lock (_credentialCacheLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
_credentialCache.Add(uri, authType, cred);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
// The credential was already added.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeDefaultCredentialsPolicy(
|
||||
SafeWinHttpHandle requestHandle,
|
||||
uint authTarget,
|
||||
bool allowDefaultCredentials)
|
||||
{
|
||||
Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY ||
|
||||
authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_SERVER);
|
||||
|
||||
uint optionData = allowDefaultCredentials ?
|
||||
(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY ?
|
||||
Interop.WinHttp.WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM :
|
||||
Interop.WinHttp.WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW) :
|
||||
Interop.WinHttp.WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH;
|
||||
|
||||
if (!Interop.WinHttp.WinHttpSetOption(
|
||||
requestHandle,
|
||||
Interop.WinHttp.WINHTTP_OPTION_AUTOLOGON_POLICY,
|
||||
ref optionData))
|
||||
{
|
||||
WinHttpException.ThrowExceptionUsingLastError();
|
||||
}
|
||||
}
|
||||
|
||||
private bool SetWinHttpCredential(
|
||||
SafeWinHttpHandle requestHandle,
|
||||
ICredentials credentials,
|
||||
Uri uri,
|
||||
uint authScheme,
|
||||
uint authTarget)
|
||||
{
|
||||
string userName;
|
||||
string password;
|
||||
|
||||
Debug.Assert(credentials != null);
|
||||
Debug.Assert(authScheme != 0);
|
||||
Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY ||
|
||||
authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_SERVER);
|
||||
|
||||
NetworkCredential networkCredential = credentials.GetCredential(uri, s_authSchemeStringMapping[authScheme]);
|
||||
|
||||
if (networkCredential == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (networkCredential == CredentialCache.DefaultNetworkCredentials)
|
||||
{
|
||||
// Only Negotiate and NTLM can use default credentials. Otherwise,
|
||||
// behave as-if there were no credentials.
|
||||
if (authScheme == Interop.WinHttp.WINHTTP_AUTH_SCHEME_NEGOTIATE ||
|
||||
authScheme == Interop.WinHttp.WINHTTP_AUTH_SCHEME_NTLM)
|
||||
{
|
||||
// Allow WinHTTP to transmit the default credentials.
|
||||
ChangeDefaultCredentialsPolicy(requestHandle, authTarget, allowDefaultCredentials:true);
|
||||
userName = null;
|
||||
password = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
userName = networkCredential.UserName;
|
||||
password = networkCredential.Password;
|
||||
string domain = networkCredential.Domain;
|
||||
|
||||
// WinHTTP does not support a blank username. So, we will throw an exception.
|
||||
if (string.IsNullOrEmpty(userName))
|
||||
{
|
||||
throw new InvalidOperationException(SR.net_http_username_empty_string);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(domain))
|
||||
{
|
||||
userName = domain + "\\" + userName;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Interop.WinHttp.WinHttpSetCredentials(
|
||||
requestHandle,
|
||||
authTarget,
|
||||
authScheme,
|
||||
userName,
|
||||
password,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
WinHttpException.ThrowExceptionUsingLastError();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static uint ChooseAuthScheme(uint supportedSchemes)
|
||||
{
|
||||
foreach (uint authScheme in s_authSchemePriorityOrder)
|
||||
{
|
||||
if ((supportedSchemes & authScheme) != 0)
|
||||
{
|
||||
return authScheme;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
126
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCertificateHelper.cs
vendored
Normal file
126
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCertificateHelper.cs
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
internal static class WinHttpCertificateHelper
|
||||
{
|
||||
private const string ClientAuthenticationOID = "1.3.6.1.5.5.7.3.2";
|
||||
|
||||
// TODO: Issue #2165. Merge with similar code used in System.Net.Security move to Common/src//System/Net.
|
||||
public static void BuildChain(
|
||||
X509Certificate2 certificate,
|
||||
string hostName,
|
||||
bool checkCertificateRevocationList,
|
||||
out X509Chain chain,
|
||||
out SslPolicyErrors sslPolicyErrors)
|
||||
{
|
||||
chain = null;
|
||||
sslPolicyErrors = SslPolicyErrors.None;
|
||||
|
||||
// Build the chain.
|
||||
chain = new X509Chain();
|
||||
chain.ChainPolicy.RevocationMode =
|
||||
checkCertificateRevocationList ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
|
||||
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
|
||||
if (!chain.Build(certificate))
|
||||
{
|
||||
sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
|
||||
}
|
||||
|
||||
// Verify the hostName matches the certificate.
|
||||
unsafe
|
||||
{
|
||||
var cppStruct = new Interop.Crypt32.CERT_CHAIN_POLICY_PARA();
|
||||
cppStruct.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_PARA>();
|
||||
cppStruct.dwFlags = 0;
|
||||
|
||||
var eppStruct = new Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA();
|
||||
eppStruct.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA>();
|
||||
eppStruct.dwAuthType = Interop.Crypt32.AuthType.AUTHTYPE_CLIENT;
|
||||
|
||||
cppStruct.pvExtraPolicyPara = &eppStruct;
|
||||
|
||||
fixed (char* namePtr = hostName)
|
||||
{
|
||||
eppStruct.pwszServerName = namePtr;
|
||||
cppStruct.dwFlags =
|
||||
Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL &
|
||||
~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG;
|
||||
|
||||
var status = new Interop.Crypt32.CERT_CHAIN_POLICY_STATUS();
|
||||
status.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_STATUS>();
|
||||
if (Interop.Crypt32.CertVerifyCertificateChainPolicy(
|
||||
(IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
|
||||
chain.SafeHandle,
|
||||
ref cppStruct,
|
||||
ref status))
|
||||
{
|
||||
if (status.dwError == Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH)
|
||||
{
|
||||
sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failure checking the policy. This is a rare error. We will assume the name check failed.
|
||||
// TODO: Issue #2165. Log this error or perhaps throw an exception instead.
|
||||
sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static X509Certificate2 GetEligibleClientCertificate()
|
||||
{
|
||||
// Get initial list of client certificates from the MY store.
|
||||
X509Certificate2Collection candidateCerts;
|
||||
using (var myStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
|
||||
{
|
||||
myStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
|
||||
candidateCerts = myStore.Certificates;
|
||||
}
|
||||
|
||||
return GetEligibleClientCertificate(candidateCerts);
|
||||
}
|
||||
|
||||
// TODO: Issue #3891. Get the Trusted Issuers List from WinHTTP and use that to help narrow down
|
||||
// the list of eligible client certificates.
|
||||
public static X509Certificate2 GetEligibleClientCertificate(X509Certificate2Collection candidateCerts)
|
||||
{
|
||||
if (candidateCerts.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Reduce the set of certificates to match the proper 'Client Authentication' criteria.
|
||||
candidateCerts = candidateCerts.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, false);
|
||||
candidateCerts = candidateCerts.Find(X509FindType.FindByApplicationPolicy, ClientAuthenticationOID, false);
|
||||
|
||||
// Build a new collection with certs that have a private key. Need to do this
|
||||
// manually because there is no X509FindType to match this criteria.
|
||||
var eligibleCerts = new X509Certificate2Collection();
|
||||
foreach (X509Certificate2 cert in candidateCerts)
|
||||
{
|
||||
if (cert.HasPrivateKey)
|
||||
{
|
||||
eligibleCerts.Add(cert);
|
||||
}
|
||||
}
|
||||
|
||||
if (eligibleCerts.Count > 0)
|
||||
{
|
||||
return eligibleCerts[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpChannelBinding.cs
vendored
Normal file
79
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpChannelBinding.cs
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Text;
|
||||
|
||||
using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
internal class WinHttpChannelBinding : ChannelBinding
|
||||
{
|
||||
private int _size = 0;
|
||||
private string _cachedToString = null;
|
||||
|
||||
internal WinHttpChannelBinding(SafeWinHttpHandle requestHandle)
|
||||
{
|
||||
IntPtr data = IntPtr.Zero;
|
||||
uint dataSize = 0;
|
||||
|
||||
if (!Interop.WinHttp.WinHttpQueryOption(requestHandle, Interop.WinHttp.WINHTTP_OPTION_SERVER_CBT, null, ref dataSize))
|
||||
{
|
||||
if (Marshal.GetLastWin32Error() == Interop.WinHttp.ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
data = Marshal.AllocHGlobal((int)dataSize);
|
||||
|
||||
if (Interop.WinHttp.WinHttpQueryOption(requestHandle, Interop.WinHttp.WINHTTP_OPTION_SERVER_CBT, data, ref dataSize))
|
||||
{
|
||||
SetHandle(data);
|
||||
_size = (int)dataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.FreeHGlobal(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get
|
||||
{
|
||||
return _size == 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (_cachedToString == null && !IsInvalid)
|
||||
{
|
||||
var bytes = new byte[_size];
|
||||
Marshal.Copy(this.handle, bytes, 0, _size);
|
||||
_cachedToString = BitConverter.ToString(bytes).Replace('-', ' ');
|
||||
}
|
||||
|
||||
return _cachedToString;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
Marshal.FreeHGlobal(this.handle);
|
||||
SetHandle(IntPtr.Zero);
|
||||
_size = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
internal static class WinHttpCookieContainerAdapter
|
||||
{
|
||||
private const string CookieHeaderNameWithColon = "Cookie" + ":";
|
||||
|
||||
public static void AddResponseCookiesToContainer(WinHttpRequestState state)
|
||||
{
|
||||
HttpRequestMessage request = state.RequestMessage;
|
||||
SafeWinHttpHandle requestHandle = state.RequestHandle;
|
||||
CookieContainer cookieContainer = state.Handler.CookieContainer;
|
||||
|
||||
Debug.Assert(state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer);
|
||||
Debug.Assert(cookieContainer != null);
|
||||
|
||||
// Get 'Set-Cookie' headers from response.
|
||||
char[] buffer = null;
|
||||
uint index = 0;
|
||||
string cookieHeader;
|
||||
WinHttpTraceHelper.Trace("WINHTTP_QUERY_SET_COOKIE");
|
||||
while (WinHttpResponseParser.GetResponseHeader(
|
||||
requestHandle, Interop.WinHttp.WINHTTP_QUERY_SET_COOKIE, ref buffer, ref index, out cookieHeader))
|
||||
{
|
||||
WinHttpTraceHelper.Trace(cookieHeader);
|
||||
try
|
||||
{
|
||||
cookieContainer.SetCookies(request.RequestUri, cookieHeader);
|
||||
WinHttpTraceHelper.Trace(cookieHeader);
|
||||
}
|
||||
catch (CookieException)
|
||||
{
|
||||
// We ignore malformed cookies in the response.
|
||||
WinHttpTraceHelper.Trace("Ignoring invalid cookie: {0}", cookieHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ResetCookieRequestHeaders(WinHttpRequestState state, Uri redirectUri)
|
||||
{
|
||||
SafeWinHttpHandle requestHandle = state.RequestHandle;
|
||||
|
||||
Debug.Assert(state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer);
|
||||
|
||||
// Clear cookies.
|
||||
if (!Interop.WinHttp.WinHttpAddRequestHeaders(
|
||||
requestHandle,
|
||||
CookieHeaderNameWithColon,
|
||||
(uint)CookieHeaderNameWithColon.Length,
|
||||
Interop.WinHttp.WINHTTP_ADDREQ_FLAG_REPLACE))
|
||||
{
|
||||
int lastError = Marshal.GetLastWin32Error();
|
||||
if (lastError != Interop.WinHttp.ERROR_WINHTTP_HEADER_NOT_FOUND)
|
||||
{
|
||||
throw WinHttpException.CreateExceptionUsingError(lastError);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-add cookies. The GetCookieHeader() method will return the correct set of
|
||||
// cookies based on the redirectUri.
|
||||
string cookieHeader = GetCookieHeader(redirectUri, state.Handler.CookieContainer);
|
||||
if (!string.IsNullOrEmpty(cookieHeader))
|
||||
{
|
||||
if (!Interop.WinHttp.WinHttpAddRequestHeaders(
|
||||
requestHandle,
|
||||
cookieHeader,
|
||||
(uint)cookieHeader.Length,
|
||||
Interop.WinHttp.WINHTTP_ADDREQ_FLAG_ADD))
|
||||
{
|
||||
WinHttpException.ThrowExceptionUsingLastError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetCookieHeader(Uri uri, CookieContainer cookies)
|
||||
{
|
||||
string cookieHeader = null;
|
||||
|
||||
Debug.Assert(cookies != null);
|
||||
|
||||
string cookieValues = cookies.GetCookieHeader(uri);
|
||||
if (!string.IsNullOrEmpty(cookieValues))
|
||||
{
|
||||
cookieHeader = CookieHeaderNameWithColon + " " + cookieValues;
|
||||
}
|
||||
|
||||
return cookieHeader;
|
||||
}
|
||||
}
|
||||
}
|
||||
1375
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
vendored
Normal file
1375
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
396
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestCallback.cs
vendored
Normal file
396
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestCallback.cs
vendored
Normal file
@@ -0,0 +1,396 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class containing the WinHttp global callback and associated routines.
|
||||
/// </summary>
|
||||
internal static class WinHttpRequestCallback
|
||||
{
|
||||
public static Interop.WinHttp.WINHTTP_STATUS_CALLBACK StaticCallbackDelegate =
|
||||
new Interop.WinHttp.WINHTTP_STATUS_CALLBACK(WinHttpCallback);
|
||||
|
||||
public static void WinHttpCallback(
|
||||
IntPtr handle,
|
||||
IntPtr context,
|
||||
uint internetStatus,
|
||||
IntPtr statusInformation,
|
||||
uint statusInformationLength)
|
||||
{
|
||||
WinHttpTraceHelper.TraceCallbackStatus("WinHttpCallback", handle, context, internetStatus);
|
||||
|
||||
if (Environment.HasShutdownStarted)
|
||||
{
|
||||
WinHttpTraceHelper.Trace("WinHttpCallback: Environment.HasShutdownStarted returned True");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WinHttpRequestState state = WinHttpRequestState.FromIntPtr(context);
|
||||
Debug.Assert(state != null, "WinHttpCallback must have a non-null state object");
|
||||
|
||||
RequestCallback(handle, state, internetStatus, statusInformation, statusInformationLength);
|
||||
}
|
||||
|
||||
private static void RequestCallback(
|
||||
IntPtr handle,
|
||||
WinHttpRequestState state,
|
||||
uint internetStatus,
|
||||
IntPtr statusInformation,
|
||||
uint statusInformationLength)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (internetStatus)
|
||||
{
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING:
|
||||
OnRequestHandleClosing(state);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
|
||||
OnRequestSendRequestComplete(state);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE:
|
||||
Debug.Assert(statusInformationLength == Marshal.SizeOf<int>());
|
||||
int bytesAvailable = Marshal.ReadInt32(statusInformation);
|
||||
OnRequestDataAvailable(state, bytesAvailable);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
|
||||
OnRequestReadComplete(state, statusInformationLength);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE:
|
||||
OnRequestWriteComplete(state);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
|
||||
OnRequestReceiveResponseHeadersComplete(state);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REDIRECT:
|
||||
string redirectUriString = Marshal.PtrToStringUni(statusInformation);
|
||||
var redirectUri = new Uri(redirectUriString);
|
||||
OnRequestRedirect(state, redirectUri);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_SENDING_REQUEST:
|
||||
OnRequestSendingRequest(state);
|
||||
return;
|
||||
|
||||
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
|
||||
Debug.Assert(
|
||||
statusInformationLength == Marshal.SizeOf<Interop.WinHttp.WINHTTP_ASYNC_RESULT>(),
|
||||
"RequestCallback: statusInformationLength=" + statusInformationLength +
|
||||
" must be sizeof(WINHTTP_ASYNC_RESULT)=" + Marshal.SizeOf<Interop.WinHttp.WINHTTP_ASYNC_RESULT>());
|
||||
|
||||
var asyncResult = Marshal.PtrToStructure<Interop.WinHttp.WINHTTP_ASYNC_RESULT>(statusInformation);
|
||||
OnRequestError(state, asyncResult);
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Interop.WinHttp.WinHttpCloseHandle(handle);
|
||||
state.SavedException = ex;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRequestHandleClosing(WinHttpRequestState state)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestSendRequestComplete: state is null");
|
||||
|
||||
// This is the last notification callback that WinHTTP will send. Therefore, we can
|
||||
// now explicitly dispose the state object which will free its corresponding GCHandle.
|
||||
// This will then allow the state object to be garbage collected.
|
||||
state.Dispose();
|
||||
}
|
||||
|
||||
private static void OnRequestSendRequestComplete(WinHttpRequestState state)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestSendRequestComplete: state is null");
|
||||
Debug.Assert(state.LifecycleAwaitable != null, "OnRequestSendRequestComplete: LifecycleAwaitable is null");
|
||||
|
||||
state.LifecycleAwaitable.SetResult(1);
|
||||
}
|
||||
|
||||
private static void OnRequestDataAvailable(WinHttpRequestState state, int bytesAvailable)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestDataAvailable: state is null");
|
||||
|
||||
state.LifecycleAwaitable.SetResult(bytesAvailable);
|
||||
}
|
||||
|
||||
private static void OnRequestReadComplete(WinHttpRequestState state, uint bytesRead)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestReadComplete: state is null");
|
||||
|
||||
// If we read to the end of the stream and we're using 'Content-Length' semantics on the response body,
|
||||
// then verify we read at least the number of bytes required.
|
||||
if (bytesRead == 0
|
||||
&& state.ExpectedBytesToRead.HasValue
|
||||
&& state.CurrentBytesRead < state.ExpectedBytesToRead.Value)
|
||||
{
|
||||
state.LifecycleAwaitable.SetException(new IOException(string.Format(
|
||||
SR.net_http_io_read_incomplete,
|
||||
state.ExpectedBytesToRead.Value,
|
||||
state.CurrentBytesRead)));
|
||||
}
|
||||
else
|
||||
{
|
||||
state.CurrentBytesRead += (long)bytesRead;
|
||||
state.LifecycleAwaitable.SetResult((int)bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRequestWriteComplete(WinHttpRequestState state)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestWriteComplete: state is null");
|
||||
Debug.Assert(state.TcsInternalWriteDataToRequestStream != null, "TcsInternalWriteDataToRequestStream is null");
|
||||
Debug.Assert(!state.TcsInternalWriteDataToRequestStream.Task.IsCompleted, "TcsInternalWriteDataToRequestStream.Task is completed");
|
||||
|
||||
state.TcsInternalWriteDataToRequestStream.TrySetResult(true);
|
||||
}
|
||||
|
||||
private static void OnRequestReceiveResponseHeadersComplete(WinHttpRequestState state)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestReceiveResponseHeadersComplete: state is null");
|
||||
Debug.Assert(state.LifecycleAwaitable != null, "LifecycleAwaitable is null");
|
||||
|
||||
state.LifecycleAwaitable.SetResult(1);
|
||||
}
|
||||
|
||||
private static void OnRequestRedirect(WinHttpRequestState state, Uri redirectUri)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestRedirect: state is null");
|
||||
Debug.Assert(redirectUri != null, "OnRequestRedirect: redirectUri is null");
|
||||
|
||||
// If we're manually handling cookies, we need to reset them based on the new URI.
|
||||
if (state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer)
|
||||
{
|
||||
// Add any cookies that may have arrived with redirect response.
|
||||
WinHttpCookieContainerAdapter.AddResponseCookiesToContainer(state);
|
||||
|
||||
// Reset cookie request headers based on redirectUri.
|
||||
WinHttpCookieContainerAdapter.ResetCookieRequestHeaders(state, redirectUri);
|
||||
}
|
||||
|
||||
state.RequestMessage.RequestUri = redirectUri;
|
||||
|
||||
// Redirection to a new uri may require a new connection through a potentially different proxy.
|
||||
// If so, we will need to respond to additional 407 proxy auth demands and re-attach any
|
||||
// proxy credentials. The ProcessResponse() method looks at the state.LastStatusCode
|
||||
// before attaching proxy credentials and marking the HTTP request to be re-submitted.
|
||||
// So we need to reset the LastStatusCode remembered. Otherwise, it will see additional 407
|
||||
// responses as an indication that proxy auth failed and won't retry the HTTP request.
|
||||
if (state.LastStatusCode == HttpStatusCode.ProxyAuthenticationRequired)
|
||||
{
|
||||
state.LastStatusCode = 0;
|
||||
}
|
||||
|
||||
// For security reasons, we drop the server credential if it is a
|
||||
// NetworkCredential. But we allow credentials in a CredentialCache
|
||||
// since they are specifically tied to URI's.
|
||||
if (!(state.ServerCredentials is CredentialCache))
|
||||
{
|
||||
state.ServerCredentials = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRequestSendingRequest(WinHttpRequestState state)
|
||||
{
|
||||
Debug.Assert(state != null, "OnRequestSendingRequest: state is null");
|
||||
Debug.Assert(state.RequestHandle != null, "OnRequestSendingRequest: state.RequestHandle is null");
|
||||
|
||||
if (state.RequestMessage.RequestUri.Scheme != UriScheme.Https)
|
||||
{
|
||||
// Not SSL/TLS.
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the channel binding token (CBT) information from the request handle and put it into
|
||||
// the TransportContext object.
|
||||
state.TransportContext.SetChannelBinding(state.RequestHandle);
|
||||
|
||||
if (state.ServerCertificateValidationCallback != null)
|
||||
{
|
||||
IntPtr certHandle = IntPtr.Zero;
|
||||
uint certHandleSize = (uint)IntPtr.Size;
|
||||
|
||||
if (!Interop.WinHttp.WinHttpQueryOption(
|
||||
state.RequestHandle,
|
||||
Interop.WinHttp.WINHTTP_OPTION_SERVER_CERT_CONTEXT,
|
||||
ref certHandle,
|
||||
ref certHandleSize))
|
||||
{
|
||||
int lastError = Marshal.GetLastWin32Error();
|
||||
WinHttpTraceHelper.Trace(
|
||||
"OnRequestSendingRequest: Error getting WINHTTP_OPTION_SERVER_CERT_CONTEXT, {0}",
|
||||
lastError);
|
||||
|
||||
if (lastError == Interop.WinHttp.ERROR_WINHTTP_INCORRECT_HANDLE_STATE)
|
||||
{
|
||||
// Not yet an SSL/TLS connection. This occurs while connecting thru a proxy where the
|
||||
// CONNECT verb hasn't yet been processed due to the proxy requiring authentication.
|
||||
// We need to ignore this notification. Another notification will be sent once the final
|
||||
// connection thru the proxy is completed.
|
||||
return;
|
||||
}
|
||||
|
||||
throw WinHttpException.CreateExceptionUsingError(lastError);
|
||||
}
|
||||
|
||||
// Create a managed wrapper around the certificate handle. Since this results in duplicating
|
||||
// the handle, we will close the original handle after creating the wrapper.
|
||||
var serverCertificate = new X509Certificate2(certHandle);
|
||||
Interop.Crypt32.CertFreeCertificateContext(certHandle);
|
||||
|
||||
X509Chain chain = null;
|
||||
SslPolicyErrors sslPolicyErrors;
|
||||
|
||||
try
|
||||
{
|
||||
WinHttpCertificateHelper.BuildChain(
|
||||
serverCertificate,
|
||||
state.RequestMessage.RequestUri.Host,
|
||||
state.CheckCertificateRevocationList,
|
||||
out chain,
|
||||
out sslPolicyErrors);
|
||||
|
||||
bool result = state.ServerCertificateValidationCallback(
|
||||
state.RequestMessage,
|
||||
serverCertificate,
|
||||
chain,
|
||||
sslPolicyErrors);
|
||||
if (!result)
|
||||
{
|
||||
throw WinHttpException.CreateExceptionUsingError(
|
||||
(int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (chain != null)
|
||||
{
|
||||
chain.Dispose();
|
||||
}
|
||||
|
||||
serverCertificate.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRequestError(WinHttpRequestState state, Interop.WinHttp.WINHTTP_ASYNC_RESULT asyncResult)
|
||||
{
|
||||
WinHttpTraceHelper.TraceAsyncError("OnRequestError", asyncResult);
|
||||
|
||||
Debug.Assert(state != null, "OnRequestError: state is null");
|
||||
|
||||
Exception innerException = WinHttpException.CreateExceptionUsingError((int)asyncResult.dwError);
|
||||
|
||||
switch ((uint)asyncResult.dwResult.ToInt32())
|
||||
{
|
||||
case Interop.WinHttp.API_SEND_REQUEST:
|
||||
state.LifecycleAwaitable.SetException(innerException);
|
||||
break;
|
||||
|
||||
case Interop.WinHttp.API_RECEIVE_RESPONSE:
|
||||
if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_RESEND_REQUEST)
|
||||
{
|
||||
state.RetryRequest = true;
|
||||
state.LifecycleAwaitable.SetResult(0);
|
||||
}
|
||||
else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED)
|
||||
{
|
||||
// WinHttp will automatically drop any client SSL certificates that we
|
||||
// have pre-set into the request handle including the NULL certificate
|
||||
// (which means we have no certs to send). For security reasons, we don't
|
||||
// allow the certificate to be re-applied. But we need to tell WinHttp
|
||||
// explicitly that we don't have any certificate to send.
|
||||
Debug.Assert(state.RequestHandle != null, "OnRequestError: state.RequestHandle is null");
|
||||
WinHttpHandler.SetNoClientCertificate(state.RequestHandle);
|
||||
state.RetryRequest = true;
|
||||
state.LifecycleAwaitable.SetResult(0);
|
||||
}
|
||||
else if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
|
||||
{
|
||||
state.LifecycleAwaitable.SetCanceled(state.CancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.LifecycleAwaitable.SetException(innerException);
|
||||
}
|
||||
break;
|
||||
|
||||
case Interop.WinHttp.API_QUERY_DATA_AVAILABLE:
|
||||
if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
|
||||
{
|
||||
// TODO: Issue #2165. We need to pass in the cancellation token from the
|
||||
// user's ReadAsync() call into the TrySetCanceled().
|
||||
Debug.WriteLine("RequestCallback: QUERY_DATA_AVAILABLE - ERROR_WINHTTP_OPERATION_CANCELLED");
|
||||
state.LifecycleAwaitable.SetCanceled();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.LifecycleAwaitable.SetException(
|
||||
new IOException(SR.net_http_io_read, innerException));
|
||||
}
|
||||
break;
|
||||
|
||||
case Interop.WinHttp.API_READ_DATA:
|
||||
if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
|
||||
{
|
||||
// TODO: Issue #2165. We need to pass in the cancellation token from the
|
||||
// user's ReadAsync() call into the TrySetCanceled().
|
||||
Debug.WriteLine("RequestCallback: API_READ_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
|
||||
state.LifecycleAwaitable.SetCanceled();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.LifecycleAwaitable.SetException(new IOException(SR.net_http_io_read, innerException));
|
||||
}
|
||||
break;
|
||||
|
||||
case Interop.WinHttp.API_WRITE_DATA:
|
||||
if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
|
||||
{
|
||||
// TODO: Issue #2165. We need to pass in the cancellation token from the
|
||||
// user's WriteAsync() call into the TrySetCanceled().
|
||||
Debug.WriteLine("RequestCallback: API_WRITE_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
|
||||
state.TcsInternalWriteDataToRequestStream.TrySetCanceled();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.TcsInternalWriteDataToRequestStream.TrySetException(
|
||||
new IOException(SR.net_http_io_write, innerException));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Fail(
|
||||
"OnRequestError: Result (" + asyncResult.dwResult + ") is not expected.",
|
||||
"Error code: " + asyncResult.dwError + " (" + innerException.Message + ")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
229
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs
vendored
Normal file
229
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
internal sealed class WinHttpRequestState : IDisposable
|
||||
{
|
||||
#if DEBUG
|
||||
private static int s_dbg_allocated = 0;
|
||||
private static int s_dbg_pin = 0;
|
||||
private static int s_dbg_clearSendRequestState = 0;
|
||||
private static int s_dbg_callDispose = 0;
|
||||
private static int s_dbg_operationHandleFree = 0;
|
||||
|
||||
private IntPtr s_dbg_requestHandle;
|
||||
#endif
|
||||
|
||||
// A GCHandle for this operation object.
|
||||
// This is owned by the callback and will be deallocated when the sessionHandle has been closed.
|
||||
private GCHandle _operationHandle;
|
||||
private WinHttpTransportContext _transportContext;
|
||||
private volatile bool _disposed = false; // To detect redundant calls.
|
||||
|
||||
public WinHttpRequestState()
|
||||
{
|
||||
#if DEBUG
|
||||
Interlocked.Increment(ref s_dbg_allocated);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Pin()
|
||||
{
|
||||
if (!_operationHandle.IsAllocated)
|
||||
{
|
||||
#if DEBUG
|
||||
Interlocked.Increment(ref s_dbg_pin);
|
||||
#endif
|
||||
_operationHandle = GCHandle.Alloc(this);
|
||||
}
|
||||
}
|
||||
|
||||
public static WinHttpRequestState FromIntPtr(IntPtr gcHandle)
|
||||
{
|
||||
GCHandle stateHandle = GCHandle.FromIntPtr(gcHandle);
|
||||
return (WinHttpRequestState)stateHandle.Target;
|
||||
}
|
||||
|
||||
public IntPtr ToIntPtr()
|
||||
{
|
||||
return GCHandle.ToIntPtr(_operationHandle);
|
||||
}
|
||||
|
||||
// TODO (Issue 2506): The current locking mechanism doesn't allow any two WinHttp functions executing at
|
||||
// the same time for the same handle. Enhance locking to prevent only WinHttpCloseHandle being called
|
||||
// during other API execution. E.g. using a Reader/Writer model or, even better, Interlocked functions.
|
||||
// The lock object must be used during the execution of any WinHttp function to ensure no race conditions with
|
||||
// calling WinHttpCloseHandle.
|
||||
public object Lock => this;
|
||||
|
||||
public void ClearSendRequestState()
|
||||
{
|
||||
#if DEBUG
|
||||
Interlocked.Increment(ref s_dbg_clearSendRequestState);
|
||||
#endif
|
||||
// Since WinHttpRequestState has a self-referenced strong GCHandle, we
|
||||
// need to clear out object references to break cycles and prevent leaks.
|
||||
Tcs = null;
|
||||
TcsInternalWriteDataToRequestStream = null;
|
||||
CancellationToken = default(CancellationToken);
|
||||
RequestMessage = null;
|
||||
Handler = null;
|
||||
ServerCertificateValidationCallback = null;
|
||||
TransportContext = null;
|
||||
Proxy = null;
|
||||
ServerCredentials = null;
|
||||
DefaultProxyCredentials = null;
|
||||
|
||||
if (RequestHandle != null)
|
||||
{
|
||||
RequestHandle.Dispose();
|
||||
RequestHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
public TaskCompletionSource<HttpResponseMessage> Tcs { get; set; }
|
||||
|
||||
public CancellationToken CancellationToken { get; set; }
|
||||
|
||||
public HttpRequestMessage RequestMessage { get; set; }
|
||||
|
||||
public WinHttpHandler Handler { get; set; }
|
||||
|
||||
SafeWinHttpHandle _requestHandle;
|
||||
public SafeWinHttpHandle RequestHandle
|
||||
{
|
||||
get
|
||||
{
|
||||
return _requestHandle;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
#if DEBUG
|
||||
if (value != null)
|
||||
{
|
||||
s_dbg_requestHandle = value.DangerousGetHandle();
|
||||
}
|
||||
#endif
|
||||
_requestHandle = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Exception SavedException { get; set; }
|
||||
|
||||
public bool CheckCertificateRevocationList { get; set; }
|
||||
|
||||
public Func<
|
||||
HttpRequestMessage,
|
||||
X509Certificate2,
|
||||
X509Chain,
|
||||
SslPolicyErrors,
|
||||
bool> ServerCertificateValidationCallback { get; set; }
|
||||
|
||||
public WinHttpTransportContext TransportContext
|
||||
{
|
||||
get { return _transportContext ?? (_transportContext = new WinHttpTransportContext()); }
|
||||
set { _transportContext = value; }
|
||||
}
|
||||
|
||||
public WindowsProxyUsePolicy WindowsProxyUsePolicy { get; set; }
|
||||
|
||||
public IWebProxy Proxy { get; set; }
|
||||
|
||||
public ICredentials ServerCredentials { get; set; }
|
||||
|
||||
public ICredentials DefaultProxyCredentials { get; set; }
|
||||
|
||||
public bool PreAuthenticate { get; set; }
|
||||
|
||||
public HttpStatusCode LastStatusCode { get; set; }
|
||||
|
||||
public bool RetryRequest { get; set; }
|
||||
|
||||
public RendezvousAwaitable<int> LifecycleAwaitable { get; set; } = new RendezvousAwaitable<int>();
|
||||
public TaskCompletionSource<bool> TcsInternalWriteDataToRequestStream { get; set; }
|
||||
public bool AsyncReadInProgress { get; set; }
|
||||
|
||||
// WinHttpResponseStream state.
|
||||
public long? ExpectedBytesToRead { get; set; }
|
||||
public long CurrentBytesRead { get; set; }
|
||||
|
||||
// TODO (Issue 2505): temporary pinned buffer caches of 1 item. Will be replaced by PinnableBufferCache.
|
||||
private GCHandle _cachedReceivePinnedBuffer;
|
||||
|
||||
public void PinReceiveBuffer(byte[] buffer)
|
||||
{
|
||||
if (!_cachedReceivePinnedBuffer.IsAllocated || _cachedReceivePinnedBuffer.Target != buffer)
|
||||
{
|
||||
if (_cachedReceivePinnedBuffer.IsAllocated)
|
||||
{
|
||||
_cachedReceivePinnedBuffer.Free();
|
||||
}
|
||||
|
||||
_cachedReceivePinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
#if DEBUG
|
||||
Interlocked.Increment(ref s_dbg_callDispose);
|
||||
#endif
|
||||
if (WinHttpTraceHelper.IsTraceEnabled())
|
||||
{
|
||||
WinHttpTraceHelper.Trace(
|
||||
"WinHttpRequestState.Dispose, GCHandle=0x{0:X}, disposed={1}, disposing={2}",
|
||||
ToIntPtr(),
|
||||
_disposed,
|
||||
disposing);
|
||||
}
|
||||
|
||||
// Since there is no finalizer and this class is sealed, the disposing parameter should be TRUE.
|
||||
Debug.Assert(disposing, "WinHttpRequestState.Dispose() should have disposing=TRUE");
|
||||
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
|
||||
if (_operationHandle.IsAllocated)
|
||||
{
|
||||
// This method only gets called when the WinHTTP request handle is fully closed and thus all
|
||||
// async operations are done. So, it is safe at this point to unpin the buffers and release
|
||||
// the strong GCHandle for this object.
|
||||
if (_cachedReceivePinnedBuffer.IsAllocated)
|
||||
{
|
||||
_cachedReceivePinnedBuffer.Free();
|
||||
_cachedReceivePinnedBuffer = default(GCHandle);
|
||||
}
|
||||
#if DEBUG
|
||||
Interlocked.Increment(ref s_dbg_operationHandleFree);
|
||||
#endif
|
||||
_operationHandle.Free();
|
||||
_operationHandle = default(GCHandle);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// No need to suppress finalization since the finalizer is not overridden and the class is sealed.
|
||||
Dispose(true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
254
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs
vendored
Normal file
254
external/corefx/src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
internal class WinHttpRequestStream : Stream
|
||||
{
|
||||
private static byte[] s_crLfTerminator = new byte[] { 0x0d, 0x0a }; // "\r\n"
|
||||
private static byte[] s_endChunk = new byte[] { 0x30, 0x0d, 0x0a, 0x0d, 0x0a }; // "0\r\n\r\n"
|
||||
|
||||
private volatile bool _disposed;
|
||||
private WinHttpRequestState _state;
|
||||
private bool _chunkedMode;
|
||||
|
||||
// TODO (Issue 2505): temporary pinned buffer caches of 1 item. Will be replaced by PinnableBufferCache.
|
||||
private GCHandle _cachedSendPinnedBuffer;
|
||||
|
||||
internal WinHttpRequestStream(WinHttpRequestState state, bool chunkedMode)
|
||||
{
|
||||
_state = state;
|
||||
_chunkedMode = chunkedMode;
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return !_disposed;
|
||||
}
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDisposed();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDisposed();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
CheckDisposed();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return cancellationToken.IsCancellationRequested ?
|
||||
Task.FromCanceled(cancellationToken) :
|
||||
Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token)
|
||||
{
|
||||
if (buffer == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(buffer));
|
||||
}
|
||||
|
||||
if (offset < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(offset));
|
||||
}
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(count));
|
||||
}
|
||||
|
||||
if (count > buffer.Length - offset)
|
||||
{
|
||||
throw new ArgumentException(SR.net_http_buffer_insufficient_length, nameof(buffer));
|
||||
}
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<int>();
|
||||
tcs.TrySetCanceled(token);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
CheckDisposed();
|
||||
|
||||
if (_state.TcsInternalWriteDataToRequestStream != null &&
|
||||
!_state.TcsInternalWriteDataToRequestStream.Task.IsCompleted)
|
||||
{
|
||||
throw new InvalidOperationException(SR.net_http_no_concurrent_io_allowed);
|
||||
}
|
||||
|
||||
return InternalWriteAsync(buffer, offset, count, token);
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
CheckDisposed();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
CheckDisposed();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
CheckDisposed();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
internal async Task EndUploadAsync(CancellationToken token)
|
||||
{
|
||||
if (_chunkedMode)
|
||||
{
|
||||
await InternalWriteDataAsync(s_endChunk, 0, s_endChunk.Length, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
// TODO (Issue 2508): Pinned buffers must be released in the callback, when it is guaranteed no further
|
||||
// operations will be made to the send/receive buffers.
|
||||
if (_cachedSendPinnedBuffer.IsAllocated)
|
||||
{
|
||||
_cachedSendPinnedBuffer.Free();
|
||||
}
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void CheckDisposed()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(this.GetType().FullName);
|
||||
}
|
||||
}
|
||||
|
||||
private Task InternalWriteAsync(byte[] buffer, int offset, int count, CancellationToken token)
|
||||
{
|
||||
return _chunkedMode ?
|
||||
InternalWriteChunkedModeAsync(buffer, offset, count, token) :
|
||||
InternalWriteDataAsync(buffer, offset, count, token);
|
||||
}
|
||||
|
||||
private async Task InternalWriteChunkedModeAsync(byte[] buffer, int offset, int count, CancellationToken token)
|
||||
{
|
||||
// WinHTTP does not fully support chunked uploads. It simply allows one to omit the 'Content-Length' header
|
||||
// and instead use the 'Transfer-Encoding: chunked' header. The caller is still required to encode the
|
||||
// request body according to chunking rules.
|
||||
Debug.Assert(_chunkedMode);
|
||||
|
||||
string chunkSizeString = String.Format("{0:x}\r\n", count);
|
||||
byte[] chunkSize = Encoding.UTF8.GetBytes(chunkSizeString);
|
||||
|
||||
await InternalWriteDataAsync(chunkSize, 0, chunkSize.Length, token).ConfigureAwait(false);
|
||||
|
||||
await InternalWriteDataAsync(buffer, offset, count, token).ConfigureAwait(false);
|
||||
await InternalWriteDataAsync(s_crLfTerminator, 0, s_crLfTerminator.Length, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private Task<bool> InternalWriteDataAsync(byte[] buffer, int offset, int count, CancellationToken token)
|
||||
{
|
||||
Debug.Assert(count >= 0);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
return Task.FromResult<bool>(true);
|
||||
}
|
||||
|
||||
// TODO (Issue 2505): replace with PinnableBufferCache.
|
||||
if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer)
|
||||
{
|
||||
if (_cachedSendPinnedBuffer.IsAllocated)
|
||||
{
|
||||
_cachedSendPinnedBuffer.Free();
|
||||
}
|
||||
|
||||
_cachedSendPinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
|
||||
}
|
||||
|
||||
_state.TcsInternalWriteDataToRequestStream =
|
||||
new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
lock (_state.Lock)
|
||||
{
|
||||
if (!Interop.WinHttp.WinHttpWriteData(
|
||||
_state.RequestHandle,
|
||||
Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset),
|
||||
(uint)count,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
_state.TcsInternalWriteDataToRequestStream.TrySetException(
|
||||
new IOException(SR.net_http_io_write, WinHttpException.CreateExceptionUsingLastError().InitializeStackTrace()));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Issue #2165. Register callback on cancellation token to cancel WinHTTP operation.
|
||||
|
||||
return _state.TcsInternalWriteDataToRequestStream.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to read header lines of an HTTP response, where each line is separated by "\r\n".
|
||||
/// </summary>
|
||||
internal struct WinHttpResponseHeaderReader
|
||||
{
|
||||
private const string Gzip = "gzip";
|
||||
private const string Deflate = "deflate";
|
||||
|
||||
private readonly char[] _buffer;
|
||||
private readonly int _length;
|
||||
private int _position;
|
||||
|
||||
public WinHttpResponseHeaderReader(char[] buffer, int startIndex, int length)
|
||||
{
|
||||
CharArrayHelpers.DebugAssertArrayInputs(buffer, startIndex, length);
|
||||
|
||||
_buffer = buffer;
|
||||
_position = startIndex;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a header line.
|
||||
/// Empty header lines are skipped, as are malformed header lines that are missing a colon character.
|
||||
/// </summary>
|
||||
/// <returns>true if the next header was read successfully, or false if all characters have been read.</returns>
|
||||
public bool ReadHeader(out string name, out string value)
|
||||
{
|
||||
int startIndex;
|
||||
int length;
|
||||
while (ReadLine(out startIndex, out length))
|
||||
{
|
||||
// Skip empty lines.
|
||||
if (length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int colonIndex = Array.IndexOf(_buffer, ':', startIndex, length);
|
||||
|
||||
// Skip malformed header lines that are missing the colon character.
|
||||
if (colonIndex == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int nameLength = colonIndex - startIndex;
|
||||
|
||||
// If it's a known header name, use the known name instead of allocating a new string.
|
||||
if (!HttpKnownHeaderNames.TryGetHeaderName(_buffer, startIndex, nameLength, out name))
|
||||
{
|
||||
name = new string(_buffer, startIndex, nameLength);
|
||||
}
|
||||
|
||||
// Normalize header value by trimming white space.
|
||||
int valueStartIndex = colonIndex + 1;
|
||||
int valueLength = startIndex + length - colonIndex - 1;
|
||||
CharArrayHelpers.Trim(_buffer, ref valueStartIndex, ref valueLength);
|
||||
|
||||
value = GetHeaderValue(name, _buffer, valueStartIndex, valueLength);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
name = null;
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads lines separated by "\r\n".
|
||||
/// </summary>
|
||||
/// <returns>true if the next line was read successfully, or false if all characters have been read.</returns>
|
||||
public bool ReadLine()
|
||||
{
|
||||
int startIndex;
|
||||
int length;
|
||||
return ReadLine(out startIndex, out length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads lines separated by "\r\n".
|
||||
/// </summary>
|
||||
/// <param name="startIndex">The start of the line segment.</param>
|
||||
/// <param name="length">The length of the line segment.</param>
|
||||
/// <returns>true if the next line was read successfully, or false if all characters have been read.</returns>
|
||||
private bool ReadLine(out int startIndex, out int length)
|
||||
{
|
||||
Debug.Assert(_buffer != null);
|
||||
|
||||
int i = _position;
|
||||
|
||||
while (i < _length)
|
||||
{
|
||||
char ch = _buffer[i];
|
||||
if (ch == '\r')
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next < _length && _buffer[next] == '\n')
|
||||
{
|
||||
startIndex = _position;
|
||||
length = i - _position;
|
||||
_position = i + 2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i > _position)
|
||||
{
|
||||
startIndex = _position;
|
||||
length = i - _position;
|
||||
_position = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
startIndex = 0;
|
||||
length = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GetHeaderValue(string name, char[] array, int startIndex, int length)
|
||||
{
|
||||
Debug.Assert(name != null);
|
||||
CharArrayHelpers.DebugAssertArrayInputs(array, startIndex, length);
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// If it's a known header value, use the known value instead of allocating a new string.
|
||||
|
||||
// Do a really quick reference equals check to see if name is the same object as
|
||||
// HttpKnownHeaderNames.ContentEncoding, in which case the value is very likely to
|
||||
// be either "gzip" or "deflate".
|
||||
if (object.ReferenceEquals(name, HttpKnownHeaderNames.ContentEncoding))
|
||||
{
|
||||
if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(Gzip, array, startIndex, length))
|
||||
{
|
||||
return Gzip;
|
||||
}
|
||||
else if (CharArrayHelpers.EqualsOrdinalAsciiIgnoreCase(Deflate, array, startIndex, length))
|
||||
{
|
||||
return Deflate;
|
||||
}
|
||||
}
|
||||
|
||||
return new string(array, startIndex, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user