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-26 05:43:54 +0300
committerGitHub <noreply@github.com>2017-10-26 05:43:54 +0300
commit4b1137f8d46955904462acff7b2da34a9aa96d39 (patch)
treecb91221f14fb2379e1db7a4c4a27e39ac63d0d66 /src
parent789035424aa1d3940baa3acde7b78fd78641b5e4 (diff)
parent5ecea8ff47c03a073a77916a9c7d1d806f8c7ce3 (diff)
Merge pull request #24820 from stephentoub/fix_http_issues
Fix a few ManagedHandler issues
Diffstat (limited to 'src')
-rw-r--r--src/System.Net.Http/src/Resources/Strings.resx5
-rw-r--r--src/System.Net.Http/src/System/Net/Http/Managed/AutoRedirectHandler.cs3
-rw-r--r--src/System.Net.Http/src/System/Net/Http/Managed/DecompressionHandler.cs49
-rw-r--r--src/System.Net.Http/src/System/Net/Http/Managed/HttpConnectionHandler.cs37
-rw-r--r--src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs8
-rw-r--r--src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs73
-rw-r--r--src/System.Net.WebSockets.Client/tests/ConnectTest.cs6
7 files changed, 139 insertions, 42 deletions
diff --git a/src/System.Net.Http/src/Resources/Strings.resx b/src/System.Net.Http/src/Resources/Strings.resx
index 90a5d97b9c..129ef9fd5f 100644
--- a/src/System.Net.Http/src/Resources/Strings.resx
+++ b/src/System.Net.Http/src/Resources/Strings.resx
@@ -363,9 +363,6 @@
<data name="net_http_feature_UWPClientCertSupportRequiresCertInPersonalCertificateStore" xml:space="preserve">
<value>Client certificate was not found in the personal (\"MY\") certificate store. In UWP, client certificates are only supported if they have been added to that certificate store.</value>
</data>
- <data name="net_http_headers_missing_location" xml:space="preserve">
- <value>The response code indicates a redirect, but the 'Location' header is missing.</value>
- </data>
<data name="net_http_max_redirects" xml:space="preserve">
<value>The maximum number of redirects was exceeded.</value>
</data>
@@ -387,4 +384,4 @@
<data name="net_ssl_app_protocols_invalid" xml:space="preserve">
<value>The application protocol list is invalid.</value>
</data>
-</root> \ No newline at end of file
+</root>
diff --git a/src/System.Net.Http/src/System/Net/Http/Managed/AutoRedirectHandler.cs b/src/System.Net.Http/src/System/Net/Http/Managed/AutoRedirectHandler.cs
index a35175acaa..7605616781 100644
--- a/src/System.Net.Http/src/System/Net/Http/Managed/AutoRedirectHandler.cs
+++ b/src/System.Net.Http/src/System/Net/Http/Managed/AutoRedirectHandler.cs
@@ -72,7 +72,8 @@ namespace System.Net.Http
Uri location = response.Headers.Location;
if (location == null)
{
- throw new HttpRequestException(SR.net_http_headers_missing_location);
+ // No location header. Nothing to redirect to.
+ break;
}
if (!location.IsAbsoluteUri)
diff --git a/src/System.Net.Http/src/System/Net/Http/Managed/DecompressionHandler.cs b/src/System.Net.Http/src/System/Net/Http/Managed/DecompressionHandler.cs
index cd72dd3293..261ae26af7 100644
--- a/src/System.Net.Http/src/System/Net/Http/Managed/DecompressionHandler.cs
+++ b/src/System.Net.Http/src/System/Net/Http/Managed/DecompressionHandler.cs
@@ -47,30 +47,22 @@ namespace System.Net.Http
HttpResponseMessage response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false);
- while (true)
+ ICollection<string> contentEncodings = response.Content.Headers.ContentEncoding;
+ if (contentEncodings.Count > 0)
{
- // Get first encoding
- using (IEnumerator<string> e = response.Content.Headers.ContentEncoding.GetEnumerator())
+ string last = null;
+ foreach (string encoding in contentEncodings)
{
- if (!e.MoveNext())
- {
- break;
- }
+ last = encoding;
+ }
- string encoding = e.Current;
- if (GZipEnabled && encoding == s_gzip)
- {
- response.Content = new GZipDecompressedContent(response.Content);
- }
- else if (DeflateEnabled && encoding == s_deflate)
- {
- response.Content = new DeflateDecompressedContent(response.Content);
- }
- else
- {
- // Unknown content encoding. Stop processing.
- break;
- }
+ if (GZipEnabled && last == s_gzip)
+ {
+ response.Content = new GZipDecompressedContent(response.Content);
+ }
+ else if (DeflateEnabled && last == s_deflate)
+ {
+ response.Content = new DeflateDecompressedContent(response.Content);
}
}
@@ -99,21 +91,18 @@ namespace System.Net.Http
// Copy original response headers, but with the following changes:
// Content-Length is removed, since it no longer applies to the decompressed content
- // The first Content-Encoding is removed, since we are processing that here
+ // The last Content-Encoding is removed, since we are processing that here.
Headers.AddHeaders(originalContent.Headers);
Headers.ContentLength = null;
Headers.ContentEncoding.Clear();
- bool first = true;
- foreach (var encoding in originalContent.Headers.ContentEncoding)
+ string prevEncoding = null;
+ foreach (string encoding in originalContent.Headers.ContentEncoding)
{
- if (first)
- {
- first = false;
- }
- else
+ if (prevEncoding != null)
{
- Headers.ContentEncoding.Add(encoding);
+ Headers.ContentEncoding.Add(prevEncoding);
}
+ prevEncoding = encoding;
}
}
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/src/System/Net/Http/Managed/ManagedHandler.cs b/src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs
index cf1a1798f3..0945f400b5 100644
--- a/src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs
+++ b/src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs
@@ -269,14 +269,14 @@ namespace System.Net.Http
handler = new HttpProxyConnectionHandler(_settings, handler);
}
- if (_settings._credentials != null)
+ if (_settings._useCookies)
{
- handler = new AuthenticationHandler(_settings._preAuthenticate, _settings._credentials, handler);
+ handler = new CookieHandler(CookieContainer, handler);
}
- if (_settings._useCookies)
+ if (_settings._credentials != null)
{
- handler = new CookieHandler(CookieContainer, handler);
+ handler = new AuthenticationHandler(_settings._preAuthenticate, _settings._credentials, handler);
}
if (_settings._allowAutoRedirect)
diff --git a/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs b/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs
index 9f2aa8db2f..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]
@@ -635,6 +678,36 @@ namespace System.Net.Http.Functional.Tests
}
}
+ [Fact]
+ public async Task GetAsync_AllowAutoRedirectTrue_RedirectWithoutLocation_ReturnsOriginalResponse()
+ {
+ // [ActiveIssue(24819, TestPlatforms.Windows)]
+ if (PlatformDetection.IsWindows && PlatformDetection.IsNetCore && !UseManagedHandler)
+ {
+ return;
+ }
+
+ HttpClientHandler handler = CreateHttpClientHandler();
+ handler.AllowAutoRedirect = true;
+ using (var client = new HttpClient(handler))
+ {
+ await LoopbackServer.CreateServerAsync(async (server, url) =>
+ {
+ Task<HttpResponseMessage> getTask = client.GetAsync(url);
+ Task<List<string>> serverTask = LoopbackServer.ReadRequestAndSendResponseAsync(server,
+ $"HTTP/1.1 302 OK\r\n" +
+ $"Date: {DateTimeOffset.UtcNow:R}\r\n" +
+ "\r\n");
+ await TestHelper.WhenAllCompletedOrAnyFailed(getTask, serverTask);
+
+ using (HttpResponseMessage response = await getTask)
+ {
+ Assert.Equal(302, (int)response.StatusCode);
+ }
+ });
+ }
+ }
+
[OuterLoop] // TODO: Issue #11345
[Fact]
public async Task GetAsync_AllowAutoRedirectTrue_RedirectToUriWithParams_RequestMsgUriSet()
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"