* Make WebRequest.GetSystemWebProxy() return a working proxy
Today it returns a singleton on .NET Core that throws PlatformNotSupportedExceptions, and is only used for its reference identity by the WebRequest implementation. This is problematic for existing code that's taking this proxy and passing it to, for example, ClientWebSocket's Proxy, as it will end up being an expensive nop. In fact, there's currently no way when targeting netstandard2.0 to tell ClientWebSocket to use a default proxy.
With this fix, WebRequest.DefaultWebProxy (which just defaults to GetSystemWebProxy()) will now return HttpClient.DefaultProxy, which is actually a working proxy implementation.
* Stop throwing NotSupportedException from HttpClient.DefaultProxy.set_Credentials
The OS and how the environment is configured determines what concrete type is returned from HttpClient's DefaultProxy property. And currently these different types behave differently from set_Credentials. Two of them are throwing NotSupportedException, which is not expected from the IWebProxy interface. We should just roundtrip the credentials set, even if they're not used.
Commit migrated from https://github.com/dotnet/corefx/commit/
8d21b79b924d29088dbde46d42737a657d466b5e
<Compile Include="uap\System\Net\CookieHelper.cs" />
<Compile Include="uap\System\Net\HttpHandlerToFilter.cs" />
<Compile Include="System\Net\Http\HttpClientHandler.Core.cs" />
+ <Compile Include="System\Net\Http\SocketsHttpHandler\HttpNoProxy.cs" />
<Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.uap.cs" />
<Compile Include="uap\System\Net\HttpClientHandler.cs" />
</ItemGroup>
private readonly Uri _httpProxyUri; // String URI for HTTP requests
private readonly Uri _httpsProxyUri; // String URI for HTTPS requests
private readonly string[] _bypass = null; // list of domains not to proxy
- private readonly ICredentials _credentials;
+ private ICredentials _credentials;
private HttpEnvironmentProxy(Uri httpProxy, Uri httpsProxy, string bypassList)
{
{
return _credentials;
}
- set { throw new NotSupportedException(); }
+ set
+ {
+ _credentials = value;
+ }
}
}
}
{
internal sealed class MacProxy : IWebProxy
{
- public ICredentials Credentials
- {
- get => null;
- set => throw new NotSupportedException();
- }
+ public ICredentials Credentials { get; set; }
private static Uri GetProxyUri(string scheme, CFProxy proxy)
{
{
internal static partial class SystemProxyInfo
{
- // For UAP this is currently not implemented.
public static IWebProxy ConstructSystemProxy()
{
- throw new PlatformNotSupportedException();
+ // For UAP this is currently not implemented.
+ return new HttpNoProxy();
}
}
}
}
[Fact]
+ public void DefaultProxy_Credentials_SetGet_Roundtrips()
+ {
+ RemoteExecutor.Invoke(() =>
+ {
+ IWebProxy proxy = HttpClient.DefaultProxy;
+ ICredentials nc = proxy.Credentials;
+
+ proxy.Credentials = null;
+ Assert.Null(proxy.Credentials);
+
+ proxy.Credentials = nc;
+ Assert.Same(nc, proxy.Credentials);
+
+ return RemoteExecutor.SuccessExitCode;
+ }).Dispose();
+ }
+
+ [Fact]
public async Task PatchAsync_Canceled_Throws()
{
using (var client = new HttpClient(new CustomResponseHandler((r, c) => WhenCanceled<HttpResponseMessage>(c))))
<Compile Include="System\Net\IWebRequestCreate.cs" />
<Compile Include="System\Net\ProtocolViolationException.cs" />
<Compile Include="System\Net\RequestStream.cs" />
- <Compile Include="System\Net\SystemWebProxy.cs" />
<Compile Include="System\Net\TaskExtensions.cs" />
<Compile Include="System\Net\WebException.cs" />
<Compile Include="System\Net\WebExceptionStatus.cs" />
+++ /dev/null
-// 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.Threading;
-
-namespace System.Net
-{
- // Singleton proxy object representing the System proxy
- // that is determined by per-user registry settings. These
- // are the proxy settings that Internet Explorer and Wininet
- // use to look up a suitable proxy server. This object is the
- // initial default value of WebRequest.DefaultWebProxy.
- //
- // This object is only used as a sentinel to provide backward
- // compatibility for developers using the WebRequest.DefaultWebProxy
- // object. Developers use the DefaultWebProxy object either explicitly
- // by referencing it or implicitly when expecting .NET Desktop behaviors
- // when used with HttpWebRequest or HttpClientHandler.
- internal class SystemWebProxy : IWebProxy
- {
- private static IWebProxy s_systemWebProxy = null;
- private static bool s_systemWebProxyInitialized = false;
- private static object s_lockObject = new object();
-
- private ICredentials _credentials = null;
-
- private SystemWebProxy()
- {
- }
-
- public static IWebProxy Get() => LazyInitializer.EnsureInitialized(ref s_systemWebProxy, ref s_systemWebProxyInitialized, ref s_lockObject, () => new SystemWebProxy());
-
- public ICredentials Credentials
- {
- get
- {
- return _credentials;
- }
- set
- {
- _credentials = value;
- }
- }
-
- // This is a sentinel object and can't support the GetProxy or IsBypassed
- // methods directly. Our .NET Core and .NET Native code will handle this exception
- // and call into WinInet/WinHttp as appropriate to use the system proxy.
- public Uri GetProxy(Uri destination)
- {
- throw new PlatformNotSupportedException();
- }
-
- public bool IsBypassed(Uri host)
- {
- throw new PlatformNotSupportedException();
- }
- }
-}
using System.Diagnostics;
using System.IO;
using System.Net.Cache;
+using System.Net.Http;
using System.Net.Security;
using System.Runtime.Serialization;
using System.Security.Principal;
throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException);
}
- // Default Web Proxy implementation.
private static IWebProxy s_DefaultWebProxy;
private static bool s_DefaultWebProxyInitialized;
- public static IWebProxy GetSystemWebProxy() => SystemWebProxy.Get();
+ public static IWebProxy GetSystemWebProxy() => HttpClient.DefaultProxy;
public static IWebProxy DefaultWebProxy
{
get
{
- return LazyInitializer.EnsureInitialized(ref s_DefaultWebProxy, ref s_DefaultWebProxyInitialized, ref s_internalSyncObject, () => SystemWebProxy.Get());
+ return LazyInitializer.EnsureInitialized(ref s_DefaultWebProxy, ref s_DefaultWebProxyInitialized, ref s_internalSyncObject, () => GetSystemWebProxy());
}
set
{