Last active
January 19, 2024 10:41
-
-
Save yurkinh/e14a3ea8724e186df5dc7b4b37bb6511 to your computer and use it in GitHub Desktop.
Dev helper for establishing SSL connections to localhost on various platformsL ios, Android, Windows, Mac
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Net.Security; | |
using System.Net; | |
public class DevHttpsConnectionHelper | |
{ | |
public DevHttpsConnectionHelper(int sslPort) | |
{ | |
SslPort = sslPort; | |
DevServerRootUrl = FormattableString.Invariant($"https://{DevServerName}:{SslPort}"); | |
_lazyHttpClient = new Lazy<HttpClient>(() => new HttpClient(GetPlatformMessageHandler())); | |
} | |
public int SslPort { get; } | |
public string DevServerName => | |
#if WINDOWS | |
"localhost"; | |
#elif ANDROID | |
"10.0.2.2"; | |
#elif IOS || MACCATALYST | |
"localhost"; | |
#else | |
throw new PlatformNotSupportedException("Only Windows and Android currently supported."); | |
#endif | |
public string DevServerRootUrl { get; } | |
private readonly Lazy<HttpClient> _lazyHttpClient; | |
public HttpClient HttpClient => _lazyHttpClient.Value; | |
public HttpMessageHandler GetPlatformMessageHandler() | |
{ | |
#if WINDOWS | |
return null; | |
#elif ANDROID | |
var handler = new CustomAndroidMessageHandler | |
{ | |
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => | |
{ | |
if (cert != null && cert.Issuer.Equals("CN=localhost")) | |
{ | |
return true; | |
} | |
return errors == SslPolicyErrors.None; | |
} | |
}; | |
return handler; | |
#elif IOS || MACCATALYST | |
var handler = new NSUrlSessionHandler | |
{ | |
TrustOverrideForUrl = IsHttpsLocalhost, | |
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | |
}; | |
return handler; | |
#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 | |
#if IOS || MACCATALYST | |
public static bool IsHttpsLocalhost(NSUrlSessionHandler sender, string url, Security.SecTrust trust) | |
{ | |
if (url.StartsWith("https://localhost")) | |
{ | |
return true; | |
} | |
return false; | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment