Skip to content

Commit

Permalink
Include native underlying handler support in HttpClientHandler for iO…
Browse files Browse the repository at this point in the history
…S/tvOS/MacCatalyst and Android (#55384)

Completes the plan for net6 laid out in https://github.com/dotnet/designs/blob/main/accepted/2020/mono-convergence/platform-specific-httpclient.md#the-plan-for-net-5

This change supports using either the native HttpMessageHandler types that exist in the Xamarin repos (NSUrlSessionHandler for iOS/tvOS/Catalyst and AndroidMessageHandler for Android) or SocketsHttpHandler as the underlying handler in HttpClientHandler.

The behavior for new HttpClient() was established earlier in net6, but did not go all the way. For example, if the System.Net.Http.UseNativeHttpHandler feature switch was set to true, using HttpClient in different ways would lead to different underlying handlers.

Before this PR:

// System.Net.Http.UseNativeHttpHandler == true

new HttpClient();    // Chooses the native handler as the underlying handler

var handler = new HttpClientHandler();       // SocketsHttpHandler is the only choice 
new HttpClient(handler);

The change creates a handful of partial HttpClientHandler files in order to split out the platform specific parts. As you review the PR, you'll notice a bunch of if (IsSocketHandler) blocks. The intent of these are to make use of the linker and get linked out once the linker knows which handler is the active one.

get
{
    if (IsSocketHandler)
    {
        return _socketHandler!.UseCookies;
    }
    else
    {
        return GetUseCookies();
    }
}

Get and Set methods like GetUseCookies make it easier to tell the linker via DynamicDependency to preserve the reflection calls being made to the native underlying handler.

[DynamicDependency("get_UseCookies", "Xamarin.Android.Net.AndroidMessageHandler", "Mono.Android")]
private bool GetUseCookies() => (bool)InvokeNativeHandlerMethod("get_UseCookies");

It is important to point out that the underlying handler has to be derived from HttpMessageHandler. It cannot be HttpClientHandler or you'll end up with a circular dependency.
  • Loading branch information
steveisok authored Jul 15, 2021
1 parent a8926ba commit 44655fd
Show file tree
Hide file tree
Showing 21 changed files with 1,185 additions and 148 deletions.
1 change: 1 addition & 0 deletions eng/testing/tests.mobile.targets
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<EventSourceSupport Condition="'$(EventSourceSupport)' == ''">false</EventSourceSupport>
<HttpActivityPropagationSupport Condition="'$(HttpActivityPropagationSupport)' == ''">false</HttpActivityPropagationSupport>
<UseSystemResourceKeys Condition="'$(UseSystemResourceKeys)' == ''">false</UseSystemResourceKeys>
<UseNativeHttpHandler Condition="'$(UseNativeHttpHandler)' == ''">false</UseNativeHttpHandler>
</PropertyGroup>

<PropertyGroup>
Expand Down
63 changes: 63 additions & 0 deletions src/libraries/System.Net.Http/ref/System.Net.Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,35 +114,87 @@ public partial class HttpClientHandler : System.Net.Http.HttpMessageHandler
public HttpClientHandler() { }
public bool AllowAutoRedirect { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Net.DecompressionMethods AutomaticDecompression { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public bool CheckCertificateRevocationList { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Net.Http.ClientCertificateOption ClientCertificateOptions { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw null; } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
public System.Net.CookieContainer CookieContainer { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
public System.Net.ICredentials? Credentials { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public static System.Func<System.Net.Http.HttpRequestMessage, System.Security.Cryptography.X509Certificates.X509Certificate2?, System.Security.Cryptography.X509Certificates.X509Chain?, System.Net.Security.SslPolicyErrors, bool> DangerousAcceptAnyServerCertificateValidator { get { throw null; } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Net.ICredentials? DefaultProxyCredentials { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public int MaxAutomaticRedirections { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public int MaxConnectionsPerServer { get { throw null; } set { } }
public long MaxRequestContentBufferSize { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public int MaxResponseHeadersLength { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public bool PreAuthenticate { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Collections.Generic.IDictionary<string, object?> Properties { get { throw null; } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Net.IWebProxy? Proxy { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Func<System.Net.Http.HttpRequestMessage, System.Security.Cryptography.X509Certificates.X509Certificate2?, System.Security.Cryptography.X509Certificates.X509Chain?, System.Net.Security.SslPolicyErrors, bool>? ServerCertificateCustomValidationCallback { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public System.Security.Authentication.SslProtocols SslProtocols { get { throw null; } set { } }
public virtual bool SupportsAutomaticDecompression { get { throw null; } }
public virtual bool SupportsProxy { get { throw null; } }
Expand All @@ -152,9 +204,20 @@ public HttpClientHandler() { }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
public bool UseDefaultCredentials { get { throw null; } set { } }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("maccatalyst")]
public bool UseProxy { get { throw null; } set { } }
protected override void Dispose(bool disposing) { }
//
// Attributes are commented out due to https://github.com/dotnet/arcade/issues/7585
// API compat will fail until this is fixed
//
//[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
//[System.Runtime.Versioning.UnsupportedOSPlatformAttributeUnsupportedOSPlatform("ios")]
//[System.Runtime.Versioning.UnsupportedOSPlatformAttributeUnsupportedOSPlatform("tvos")]
//[System.Runtime.Versioning.UnsupportedOSPlatformAttributeUnsupportedOSPlatform("maccatalyst")]
protected internal override System.Net.Http.HttpResponseMessage Send(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
protected internal override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<type fullname="System.Net.Http.DiagnosticsHandler">
<method signature="System.Boolean IsGloballyEnabled()" body="stub" value="false" feature="System.Net.Http.EnableActivityPropagation" featurevalue="false" />
</type>
<type fullname="System.Net.Http.HttpClient">
<method signature="System.Boolean IsNativeHandlerEnabled()" body="stub" value="true" feature="System.Net.Http.UseNativeHttpHandler" featurevalue="true" />
<type fullname="System.Net.Http.HttpClientHandler">
<method signature="System.Boolean get_IsNativeHandlerEnabled()" body="stub" value="false" feature="System.Net.Http.UseNativeHttpHandler" featurevalue="false" />
</type>
</assembly>
</linker>
Loading

0 comments on commit 44655fd

Please sign in to comment.