Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs/class
diff options
context:
space:
mode:
authormonojenkins <jo.shields+jenkins@xamarin.com>2020-02-12 16:24:23 +0300
committerGitHub <noreply@github.com>2020-02-12 16:24:23 +0300
commit879f6699bb5e8bd684bcd0f0acc55401ad64991c (patch)
tree10aa254d7f0debb770b89e5448325caad582630a /mcs/class
parent688a178aa4b89e45d28d4a13c62e5d6051d474c2 (diff)
[2020-02] Allow users to switch to MonoWebRequestHandler on Android via UI (#18785)
* Bring back old HttpHandler for Android Co-authored-by: Egor Bogatov <egorbo@gmail.com>
Diffstat (limited to 'mcs/class')
-rw-r--r--mcs/class/System.Net.Http/HttpClientHandler.SocketsHandler.Android.cs20
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.csproj2
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http/HttpClient.android.cs41
-rw-r--r--mcs/class/System.Net.Http/UnitTests/HttpClientHandlerTests.Android.cs74
-rw-r--r--mcs/class/System.Net.Http/UnitTests/monodroid_System.Net.Http.UnitTests_xtest.dll.sources1
-rw-r--r--mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.exclude.sources1
-rw-r--r--mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.sources1
7 files changed, 123 insertions, 17 deletions
diff --git a/mcs/class/System.Net.Http/HttpClientHandler.SocketsHandler.Android.cs b/mcs/class/System.Net.Http/HttpClientHandler.SocketsHandler.Android.cs
new file mode 100644
index 00000000000..c483c28f03b
--- /dev/null
+++ b/mcs/class/System.Net.Http/HttpClientHandler.SocketsHandler.Android.cs
@@ -0,0 +1,20 @@
+namespace System.Net.Http
+{
+ partial class HttpClientHandler : HttpMessageHandler
+ {
+ static IMonoHttpClientHandler CreateDefaultHandler ()
+ {
+ string envvar = Environment.GetEnvironmentVariable ("XA_HTTP_CLIENT_HANDLER_TYPE")?.Trim ();
+ if (envvar?.StartsWith("System.Net.Http.MonoWebRequestHandler", StringComparison.InvariantCulture) == true)
+ return new MonoWebRequestHandler ();
+ // Ignore other types of handlers here (e.g. AndroidHttpHandler) to keep the old behavior
+ // and always create SocketsHttpHandler for code like this if MonoWebRequestHandler was not specified:
+ //
+ // var handler = new HttpClientHandler { Credentials = ... };
+ // var httpClient = new HttpClient (handler);
+ //
+ // AndroidHttpHandler is used only when we use the parameterless ctor of HttpClient
+ return new SocketsHttpHandler ();
+ }
+ }
+}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.csproj b/mcs/class/System.Net.Http/System.Net.Http.csproj
index ccd76ef08cf..554e2d19150 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.csproj
+++ b/mcs/class/System.Net.Http/System.Net.Http.csproj
@@ -1328,7 +1328,7 @@
<Compile Include="..\..\..\external\corefx\src\System.Net.Http\src\System\Net\Http\StreamContent.cs" />
<Compile Include="..\..\..\external\corefx\src\System.Net.Http\src\System\Net\Http\StreamToStreamCopy.cs" />
<Compile Include="..\..\..\external\corefx\src\System.Net.Http\src\System\Net\Http\StringContent.cs" />
- <Compile Include="HttpClientHandler.SocketsHandler.cs" />
+ <Compile Include="HttpClientHandler.SocketsHandler.Android.cs" />
<Compile Include="HttpClientHandler.cs" />
<Compile Include="HttpRequestMessage.Mono.cs" />
<Compile Include="IMonoHttpClientHandler.cs" />
diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.android.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.android.cs
index 1ef1af81b77..9b899bcffd8 100644
--- a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.android.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.android.cs
@@ -8,22 +8,31 @@ namespace System.Net.Http {
static HttpMessageHandler CreateDefaultHandler ()
{
- Type type = Type.GetType("Android.Runtime.AndroidEnvironment, Mono.Android");
- if (type == null)
- return GetFallback ("Invalid Mono.Android assembly? Cannot find Android.Runtime.AndroidEnvironment");
-
- MethodInfo method = type.GetMethod ("GetHttpMessageHandler", BindingFlags.Static | BindingFlags.NonPublic);
- if (method == null)
- return GetFallback ("Your Xamarin.Android version does not support obtaining of the custom HttpClientHandler");
-
- object ret = method.Invoke (null, null);
- if (ret == null)
- return GetFallback ("Xamarin.Android returned no custom HttpClientHandler");
-
- var handler = ret as HttpMessageHandler;
- if (handler == null)
- return GetFallback ($"{ret?.GetType()} is not a valid HttpMessageHandler");
- return handler;
+ string envvar = Environment.GetEnvironmentVariable ("XA_HTTP_CLIENT_HANDLER_TYPE")?.Trim ();
+
+ if (string.IsNullOrEmpty (envvar))
+ return GetFallback ($"XA_HTTP_CLIENT_HANDLER_TYPE is empty");
+
+ if (envvar?.StartsWith("System.Net.Http.MonoWebRequestHandler", StringComparison.InvariantCulture) == true)
+ return new HttpClientHandler (new MonoWebRequestHandler ());
+
+ Type handlerType = Type.GetType (envvar, false);
+ if (handlerType == null && !envvar.Contains (", "))
+ {
+ // if assembly was not specified - look for it in Mono.Android too
+ // (e.g. AndroidHttpHandler is there)
+ handlerType = Type.GetType (envvar + ", Mono.Android", false);
+ }
+
+ if (handlerType == null)
+ return GetFallback ($"'{envvar}' type was not found");
+
+ object handlerObj = Activator.CreateInstance (handlerType);
+
+ if (handlerObj is HttpMessageHandler msgHandler)
+ return msgHandler;
+
+ return GetFallback ($"{handlerObj?.GetType ()} is not a valid HttpMessageHandler or MonoWebRequestHandler");
}
static HttpMessageHandler GetFallback (string message)
diff --git a/mcs/class/System.Net.Http/UnitTests/HttpClientHandlerTests.Android.cs b/mcs/class/System.Net.Http/UnitTests/HttpClientHandlerTests.Android.cs
new file mode 100644
index 00000000000..00c1cda6405
--- /dev/null
+++ b/mcs/class/System.Net.Http/UnitTests/HttpClientHandlerTests.Android.cs
@@ -0,0 +1,74 @@
+// 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.Text;
+using System.Net.Http;
+using System.Reflection;
+
+using Xunit;
+using Xunit.Abstractions;
+
+namespace System.Net.Http.Tests
+{
+ public class HttpClientHandlerTestsAndroid
+ {
+ static Type GetInnerHandlerType (HttpClient httpClient)
+ {
+ BindingFlags bflasgs = BindingFlags.Instance | BindingFlags.NonPublic;
+ FieldInfo handlerField = typeof (HttpMessageInvoker).GetField("_handler", bflasgs);
+ Assert.NotNull (handlerField);
+ object handler = handlerField.GetValue (httpClient);
+ FieldInfo innerHandlerField = handler.GetType ().GetField ("_delegatingHandler", bflasgs);
+ Assert.NotNull (handlerField);
+ object innerHandler = innerHandlerField.GetValue (handler);
+ return innerHandler.GetType ();
+ }
+
+ [Fact]
+ public void TestEnvVarSwitchForInnerHttpHandler ()
+ {
+ const string xaHandlerKey = "XA_HTTP_CLIENT_HANDLER_TYPE";
+ var prevHandler = Environment.GetEnvironmentVariable (xaHandlerKey);
+
+ // ""
+ Environment.SetEnvironmentVariable (xaHandlerKey, "");
+ var httpClient1 = new HttpClient ();
+ Assert.Equal ("SocketsHttpHandler", GetInnerHandlerType (httpClient1).Name);
+
+ var handler2 = new HttpClientHandler ();
+ var httpClient2 = new HttpClient (handler2);
+ Assert.Equal ("SocketsHttpHandler", GetInnerHandlerType (httpClient2).Name);
+
+ // "System.Net.Http.MonoWebRequestHandler"
+ Environment.SetEnvironmentVariable (xaHandlerKey, "System.Net.Http.MonoWebRequestHandler");
+ var httpClient3 = new HttpClient ();
+ Assert.Equal ("MonoWebRequestHandler", GetInnerHandlerType (httpClient3).Name);
+
+ var handler4 = new HttpClientHandler ();
+ var httpClient4 = new HttpClient (handler4);
+ Assert.Equal ("MonoWebRequestHandler", GetInnerHandlerType (httpClient4).Name);
+
+ // "System.Net.Http.MonoWebRequestHandler, System.Net.Http"
+ Environment.SetEnvironmentVariable (xaHandlerKey, "System.Net.Http.MonoWebRequestHandler, System.Net.Http");
+ var httpClient5 = new HttpClient ();
+ Assert.Equal ("MonoWebRequestHandler", GetInnerHandlerType (httpClient5).Name);
+
+ var handler6 = new HttpClientHandler ();
+ var httpClient6 = new HttpClient (handler6);
+ Assert.Equal ("MonoWebRequestHandler", GetInnerHandlerType (httpClient6).Name);
+
+ // "System.Net.Http.HttpClientHandler"
+ Environment.SetEnvironmentVariable (xaHandlerKey, "System.Net.Http.HttpClientHandler");
+ var httpClient7 = new HttpClient ();
+ Assert.Equal ("SocketsHttpHandler", GetInnerHandlerType (httpClient7).Name);
+
+ var handler8 = new HttpClientHandler ();
+ var httpClient8 = new HttpClient (handler8);
+ Assert.Equal ("SocketsHttpHandler", GetInnerHandlerType (httpClient8).Name);
+
+ Environment.SetEnvironmentVariable (xaHandlerKey, prevHandler);
+ }
+ }
+}
diff --git a/mcs/class/System.Net.Http/UnitTests/monodroid_System.Net.Http.UnitTests_xtest.dll.sources b/mcs/class/System.Net.Http/UnitTests/monodroid_System.Net.Http.UnitTests_xtest.dll.sources
index ea8b52eca73..9334d2fcca4 100644
--- a/mcs/class/System.Net.Http/UnitTests/monodroid_System.Net.Http.UnitTests_xtest.dll.sources
+++ b/mcs/class/System.Net.Http/UnitTests/monodroid_System.Net.Http.UnitTests_xtest.dll.sources
@@ -1 +1,2 @@
#include unit-tests.sources
+HttpClientHandlerTests.Android.cs
diff --git a/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.exclude.sources b/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.exclude.sources
index c1788b13bf2..9164cfe38ef 100644
--- a/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.exclude.sources
+++ b/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.exclude.sources
@@ -1 +1,2 @@
HttpClient.DefaultHandler.cs
+HttpClientHandler.SocketsHandler.cs
diff --git a/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.sources
index eca4fd33a42..2397da00e5e 100644
--- a/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/monodroid_System.Net.Http.dll.sources
@@ -1,2 +1,3 @@
#include socketshandler.sources
System.Net.Http/HttpClient.android.cs
+HttpClientHandler.SocketsHandler.Android.cs