-
Notifications
You must be signed in to change notification settings - Fork 3
/
DevHttpClientHelperExtensions.cs
96 lines (87 loc) · 3.47 KB
/
DevHttpClientHelperExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Text;
using System.Threading.Tasks;
namespace BlazorHybridApp.HttpDev
{
public static class DevHttpClientHelperExtensions
{
/// <summary>
/// Adds the <see cref="IHttpClientFactory"/> and related services to the <see cref="IServiceCollection"/> and configures
/// a named <see cref="HttpClient"/> to use localhost or 10.0.2.2 and bypass certificate checking on Android.
/// </summary>
/// <param name="name">name</param>
/// <param name="sslPort">Development server port</param>
/// <returns>The IServiceCollection</returns>
/// <remarks>
/// <para>
/// https://github.com/dotnet/maui/discussions/8131
/// </para>
/// <para>
/// https://gist.github.com/Eilon/49e3c5216abfa3eba81e453d45cba2d4
/// by https://gist.github.com/Eilon
/// </para>
/// <para>
/// https://gist.github.com/EdCharbeneau/ed3d44d8298319c201f276de7a0580f1
/// by https://gist.github.com/EdCharbeneau
/// </para>
/// </remarks>
public static IServiceCollection AddDevHttpClient(this IServiceCollection services, string name, int sslPort)
{
var devServerRootUrl = new UriBuilder("https", DevServerName, sslPort).Uri.ToString();
#if WINDOWS
services.AddHttpClient(name, client =>
{
client.BaseAddress = new UriBuilder("https", DevServerName, sslPort).Uri;
});
return services;
#endif
#if ANDROID
services.AddHttpClient(name, client =>
{
client.BaseAddress = new UriBuilder("https", DevServerName, sslPort).Uri;
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new CustomAndroidMessageHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert != null && cert.Issuer.Equals("CN=localhost"))
return true;
return errors == SslPolicyErrors.None;
};
return handler;
});
return services;
#else
throw new PlatformNotSupportedException("Only Windows and Android currently supported.");
#endif
}
public static string DevServerName =>
#if WINDOWS
"localhost";
#elif ANDROID
"10.0.2.2";
#else
throw new PlatformNotSupportedException("Only Windows and Android currently supported.");
#endif
#if ANDROID
internal sealed class CustomAndroidMessageHandler : Xamarin.Android.Net.AndroidMessageHandler
{
protected override Javax.Net.Ssl.IHostnameVerifier GetSSLHostnameVerifier(Javax.Net.Ssl.HttpsURLConnection connection)
=> new CustomHostnameVerifier();
private sealed class CustomHostnameVerifier : Java.Lang.Object, Javax.Net.Ssl.IHostnameVerifier
{
public bool Verify(string hostname, Javax.Net.Ssl.ISSLSession session)
{
return
Javax.Net.Ssl.HttpsURLConnection.DefaultHostnameVerifier.Verify(hostname, session)
|| hostname == "10.0.2.2" && session.PeerPrincipal?.Name == "CN=localhost";
}
}
}
#endif
}
}