forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix SocketsHttpHandler system proxy usage logic (dotnet/corefx#37153)
SocketsHttpHandler was not using the proxy bypass list specified in IE settings in cases where there is a combination of both 'AutoDetect' and 'Manual' settings in the IE settings dialog. SocketsHttpHandler uses WinHttpHandler's WinInetProxyHelper class as part of the HttpSystemProxy class. But it was consuming it in an incorrect way. WinInetProxyHelper was originally written to be used only with the rest of the WinHTTP stack for WinHttpHandler. When WinHTTP GetProxyForUrl() was returning a ProxyBypass string, HttpSystemProxy was ignoring it. It was assuming that the string for Proxy was correct. But in cases where ProxyBypass is returned, the Proxy string is only used if the destination uri doesn't match any of the strings in the ProxyBypass list. That logic would normally be handled automatically by WinHttpHandler. But HttpSystemProxy was simply discarding the ProxyBypass string returned by WinHTTP GetProxyForUrl(). In order to address this fix, I added new tests for HttpSystemProxy. I utilized the existing mock layers for registry and WinHTTP interop that are contained in the WinHttpHandler Unit Tests. It might seem weird to have tests for the internal HttpSystemProxy class located in the WinHttpHandler folder. But, we already pull in the source code for WinInetProxyHelper from WinHttpHandler into the SocketsHttpHandler compilation. Using these Unit Tests with the mocking layers allows us to test a broad range of scenarios (registry settings and network failures) that are normally difficult to test. I have a plan, though, to refactor the system proxy code and tests as part of implementing dotnet/corefx#36553. That will result in the system proxy code and tests ending up in a more logical place. Fixes dotnet/corefx#33866 Commit migrated from dotnet/corefx@6da9a3b
- Loading branch information
Showing
5 changed files
with
163 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/Configurations.props
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
<Project DefaultTargets="Build"> | ||
<Project DefaultTargets="Build"> | ||
<PropertyGroup> | ||
<BuildConfigurations> | ||
netstandard-Windows_NT; | ||
netcoreapp-Windows_NT; | ||
</BuildConfigurations> | ||
</PropertyGroup> | ||
</Project> | ||
</Project> |
98 changes: 98 additions & 0 deletions
98
src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/HttpSystemProxyTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// 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 Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace System.Net.Http.WinHttpHandlerUnitTests | ||
{ | ||
public class HttpSystemProxyTest | ||
{ | ||
private const string ManualSettingsProxyHost = "myproxy.local"; | ||
private const string ManualSettingsProxyBypassList = "localhost;*.local"; | ||
|
||
private readonly ITestOutputHelper _output; | ||
|
||
public HttpSystemProxyTest(ITestOutputHelper output) | ||
{ | ||
_output = output; | ||
TestControl.ResetAll(); | ||
} | ||
|
||
public static IEnumerable<object[]> ManualSettingsMemberData() | ||
{ | ||
yield return new object[] { new Uri("http://example.org"), false }; | ||
yield return new object[] { new Uri("http://example.local"), true }; | ||
yield return new object[] { new Uri("http://localhost"), true }; | ||
} | ||
|
||
[Fact] | ||
public void TryCreate_WinInetProxySettingsAllOff_ReturnsFalse() | ||
{ | ||
Assert.False(HttpSystemProxy.TryCreate(out IWebProxy webProxy)); | ||
} | ||
|
||
[Theory] | ||
[MemberData(nameof(ManualSettingsMemberData))] | ||
public void GetProxy_BothAutoDetectAndManualSettingsButFailedAutoDetect_ManualSettingsUsed( | ||
Uri destination, bool bypassProxy) | ||
{ | ||
FakeRegistry.WinInetProxySettings.AutoDetect = true; | ||
FakeRegistry.WinInetProxySettings.Proxy = ManualSettingsProxyHost; | ||
FakeRegistry.WinInetProxySettings.ProxyBypass = ManualSettingsProxyBypassList; | ||
TestControl.PACFileNotDetectedOnNetwork = true; | ||
|
||
Assert.True(HttpSystemProxy.TryCreate(out IWebProxy webProxy)); | ||
|
||
// The first GetProxy() call will try using WinInetProxyHelper (and thus WinHTTP) since AutoDetect is on. | ||
Uri proxyUri1 = webProxy.GetProxy(destination); | ||
|
||
// The second GetProxy call will skip using WinHTTP since AutoDetect is on but | ||
// there was a recent AutoDetect failure. This tests the codepath in HttpSystemProxy | ||
// which queries WinInetProxyHelper.RecentAutoDetectionFailure. | ||
Uri proxyUri2 = webProxy.GetProxy(destination); | ||
|
||
if (bypassProxy) | ||
{ | ||
Assert.Null(proxyUri1); | ||
Assert.Null(proxyUri2); | ||
} | ||
else | ||
{ | ||
Assert.Equal(ManualSettingsProxyHost, proxyUri1.Host); | ||
Assert.Equal(ManualSettingsProxyHost, proxyUri2.Host); | ||
} | ||
} | ||
|
||
[Theory] | ||
[MemberData(nameof(ManualSettingsMemberData))] | ||
public void GetProxy_ManualSettingsOnly_ManualSettingsUsed( | ||
Uri destination, bool bypassProxy) | ||
{ | ||
FakeRegistry.WinInetProxySettings.Proxy = ManualSettingsProxyHost; | ||
FakeRegistry.WinInetProxySettings.ProxyBypass = ManualSettingsProxyBypassList; | ||
|
||
Assert.True(HttpSystemProxy.TryCreate(out IWebProxy webProxy)); | ||
Uri proxyUri = webProxy.GetProxy(destination); | ||
if (bypassProxy) | ||
{ | ||
Assert.Null(proxyUri); | ||
} | ||
else | ||
{ | ||
Assert.Equal(ManualSettingsProxyHost, proxyUri.Host); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void IsBypassed_ReturnsFalse() | ||
{ | ||
FakeRegistry.WinInetProxySettings.AutoDetect = true; | ||
Assert.True(HttpSystemProxy.TryCreate(out IWebProxy webProxy)); | ||
Assert.False(webProxy.IsBypassed(new Uri("http://www.microsoft.com/"))); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters