Internal Http SystemProxyInfo object should never be null (dotnet/corefx#37306)
authorDavid Shulman <david.shulman@microsoft.com>
Wed, 1 May 2019 04:14:02 +0000 (21:14 -0700)
committerGitHub <noreply@github.com>
Wed, 1 May 2019 04:14:02 +0000 (21:14 -0700)
In order to provide a consistent experience with the HttpClient IWebProxy objects,
the returned internal proxy object which represent the system/platform proxy settings
should never be null. If the platform's settings indicate that no proxy is being used,
then return an instance of the internal HttpNoProxy object.

Note that even if the platform settings indicate that a proxy could be used, any
particular Http request might still not go thru a proxy. The final determination of
what proxy is being used for a request is still governed by the return of the
IWebProxy.IsBypassed and IWebProxy.GetProxy methods.

Contributes to dotnet/corefx#36553

Commit migrated from https://github.com/dotnet/corefx/commit/830bf7fc0346d9453d85ad4ec726c92ac3e72998

src/libraries/System.Net.Http/src/System.Net.Http.csproj
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs [new file with mode: 0644]
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Unix.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Windows.cs
src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj
src/libraries/System.Net.Http/tests/UnitTests/SystemProxyInfoTest.cs

index fde227d..c0e1bac 100644 (file)
     </Compile>
   </ItemGroup>
   <ItemGroup Condition=" '$(TargetsUnix)' == 'true' And '$(TargetsOSX)' != 'true' And '$(TargetGroup)' == 'netcoreapp'">
+    <Compile Include="System\Net\Http\SocketsHttpHandler\HttpNoProxy.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.Unix.cs" />
   </ItemGroup>
   <ItemGroup Condition=" '$(TargetsOSX)' == 'true' And '$(TargetGroup)' == 'netcoreapp'">
     <Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.Windows.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\HttpEnvironmentProxy.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\HttpEnvironmentProxy.Windows.cs" />
+    <Compile Include="System\Net\Http\SocketsHttpHandler\HttpNoProxy.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\HttpSystemProxy.cs" />
     <Compile Include="$(CommonPath)\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs">
       <Link>Common\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs</Link>
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs
new file mode 100644 (file)
index 0000000..bc33faf
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Net.Http
+{
+    internal sealed class HttpNoProxy : IWebProxy
+    {
+        public ICredentials Credentials { get; set; }
+        public Uri GetProxy(Uri destination) => null;
+        public bool IsBypassed(Uri host) => true;
+    }
+}
index 6d93ee1..572322a 100644 (file)
@@ -6,10 +6,12 @@ namespace System.Net.Http
 {
     internal static class SystemProxyInfo
     {
-        // On Unix (except for OSX) we get default proxy configuration from environment variables.
+        // On Unix (except for OSX) we get default proxy configuration from environment variables. If the
+        // environment variables are not defined, we return an IWebProxy object that effectively is
+        // the "no proxy" object.
         public static IWebProxy ConstructSystemProxy()
         {
-            return HttpEnvironmentProxy.TryCreate(out IWebProxy proxy) ? proxy : null;
+            return HttpEnvironmentProxy.TryCreate(out IWebProxy proxy) ? proxy : new HttpNoProxy();
         }
     }
 }
index dde91ba..51480b5 100644 (file)
@@ -14,7 +14,7 @@ namespace System.Net.Http
                 HttpSystemProxy.TryCreate(out proxy);
             }
 
-            return proxy;
+            return proxy ?? new HttpNoProxy();
         }
     }
 }
index e07d99e..03c3bad 100644 (file)
     <Compile Include="HttpEnvironmentProxyTest.cs" />
     <Compile Include="HttpSystemProxyTest.cs" />
     <Compile Include="SystemProxyInfoTest.cs" />
+    <Compile Include="..\..\src\System\Net\Http\SocketsHttpHandler\HttpNoProxy.cs">
+      <Link>ProductionCode\System\Net\Http\HttpNoProxy.cs</Link>
+    </Compile>
     <Compile Include="..\..\src\System\Net\Http\SocketsHttpHandler\HttpSystemProxy.cs">
       <Link>ProductionCode\System\Net\Http\HttpSystemProxy.cs</Link>
     </Compile>
index 33943c5..ca012e4 100644 (file)
@@ -38,6 +38,8 @@ namespace System.Net.Http.Tests
             RemoteExecutor.Invoke(() =>
             {
                 IWebProxy proxy = SystemProxyInfo.ConstructSystemProxy();
+                Assert.NotNull(proxy);
+
                 HttpEnvironmentProxy envProxy = proxy as HttpEnvironmentProxy;
                 Assert.Null(envProxy);