Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2017-10-23 22:32:19 +0300
committerStephen Toub <stoub@microsoft.com>2017-10-25 20:40:03 +0300
commit5ecea8ff47c03a073a77916a9c7d1d806f8c7ce3 (patch)
tree92ef3d177468477114e3edf73c9c99d28341ba01 /src
parentddfab940fcc2d571c2da85250c13e457ab1933a2 (diff)
Use the Host header for the SSL handshake
Diffstat (limited to 'src')
-rw-r--r--src/System.Net.Http/src/System/Net/Http/Managed/HttpConnectionHandler.cs37
-rw-r--r--src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs43
-rw-r--r--src/System.Net.WebSockets.Client/tests/ConnectTest.cs6
3 files changed, 83 insertions, 3 deletions
diff --git a/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnectionHandler.cs b/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnectionHandler.cs
index c0635480de..6a5a0723cf 100644
--- a/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnectionHandler.cs
+++ b/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnectionHandler.cs
@@ -91,7 +91,42 @@ namespace System.Net.Http
if (HttpUtilities.IsSupportedSecureScheme(uri.Scheme))
{
- SslStream sslStream = await EstablishSslConnection(uri.IdnHost, request, stream).ConfigureAwait(false);
+ // Get the appropriate host name to use for the SSL connection, allowing a host header to override.
+ string host = request.Headers.Host;
+ if (host == null)
+ {
+ // No host header, use the host from the Uri.
+ host = uri.IdnHost;
+ }
+ else
+ {
+ // There is a host header. Use it, but first see if we need to trim off a port.
+ int colonPos = host.IndexOf(':');
+ if (colonPos >= 0)
+ {
+ // There is colon, which could either be a port separator or a separator in
+ // an IPv6 address. See if this is an IPv6 address; if it's not, use everything
+ // before the colon as the host name, and if it is, use everything before the last
+ // colon iff the last colon is after the end of the IPv6 address (otherwise it's a
+ // part of the address).
+ int ipV6AddressEnd = host.IndexOf(']');
+ if (ipV6AddressEnd == -1)
+ {
+ host = host.Substring(0, colonPos);
+ }
+ else
+ {
+ colonPos = host.LastIndexOf(':');
+ if (colonPos > ipV6AddressEnd)
+ {
+ host = host.Substring(0, colonPos);
+ }
+ }
+ }
+ }
+
+ // Establish the connection using the parsed host name.
+ SslStream sslStream = await EstablishSslConnection(host, request, stream).ConfigureAwait(false);
stream = sslStream;
transportContext = sslStream.TransportContext;
}
diff --git a/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs b/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs
index 107918623f..3e3993ca53 100644
--- a/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs
+++ b/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs
@@ -285,6 +285,49 @@ namespace System.Net.Http.Functional.Tests
}
}
+ [OuterLoop] // TODO: Issue #11345
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public async Task SendAsync_GetWithValidHostHeader_Success(bool withPort)
+ {
+ var m = new HttpRequestMessage(HttpMethod.Get, Configuration.Http.SecureRemoteEchoServer);
+ m.Headers.Host = withPort ? Configuration.Http.SecureHost + ":123" : Configuration.Http.SecureHost;
+
+ using (HttpClient client = CreateHttpClient())
+ using (HttpResponseMessage response = await client.SendAsync(m))
+ {
+ string responseContent = await response.Content.ReadAsStringAsync();
+ _output.WriteLine(responseContent);
+ TestHelper.VerifyResponseBody(
+ responseContent,
+ response.Content.Headers.ContentMD5,
+ false,
+ null);
+ }
+ }
+
+ [OuterLoop] // TODO: Issue #11345
+ [Fact]
+ public async Task SendAsync_GetWithInvalidHostHeader_ThrowsException()
+ {
+ if (PlatformDetection.IsNetCore && !UseManagedHandler)
+ {
+ // [ActiveIssue(24862)]
+ // WinHttpHandler and CurlHandler do not use the Host header to influence the SSL auth.
+ // .NET Framework and ManagedHandler do.
+ return;
+ }
+
+ var m = new HttpRequestMessage(HttpMethod.Get, Configuration.Http.SecureRemoteEchoServer);
+ m.Headers.Host = "hostheaderthatdoesnotmatch";
+
+ using (HttpClient client = CreateHttpClient())
+ {
+ await Assert.ThrowsAsync<HttpRequestException>(() => client.SendAsync(m));
+ }
+ }
+
[ActiveIssue(22158, TargetFrameworkMonikers.Uap)]
[OuterLoop] // TODO: Issue #11345
[Fact]
diff --git a/src/System.Net.WebSockets.Client/tests/ConnectTest.cs b/src/System.Net.WebSockets.Client/tests/ConnectTest.cs
index cde6c660c5..0c5645f000 100644
--- a/src/System.Net.WebSockets.Client/tests/ConnectTest.cs
+++ b/src/System.Net.WebSockets.Client/tests/ConnectTest.cs
@@ -86,9 +86,11 @@ namespace System.Net.WebSockets.Client.Tests
[ActiveIssue(18784, TargetFrameworkMonikers.NetFramework)]
[OuterLoop]
- [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoHeadersServers))]
- public async Task ConnectAsync_AddHostHeader_Success(Uri server)
+ [ConditionalTheory(nameof(WebSocketsSupported))]
+ public async Task ConnectAsync_AddHostHeader_Success()
{
+ Uri server = System.Net.Test.Common.Configuration.WebSockets.RemoteEchoServer;
+
// Send via the physical address such as "corefx-net.cloudapp.net"
// Set the Host header to logical address like "subdomain.corefx-net.cloudapp.net"
// Verify the scenario works and the remote server received "Host: subdomain.corefx-net.cloudapp.net"