Skip to content

Instantly share code, notes, and snippets.

@Eilon
Created June 15, 2022 23:06
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Eilon/49e3c5216abfa3eba81e453d45cba2d4 to your computer and use it in GitHub Desktop.
Save Eilon/49e3c5216abfa3eba81e453d45cba2d4 to your computer and use it in GitHub Desktop.
Dev helper for establishing SSL connections to localhost on various platforms
using System.Net.Security;
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";
#else
throw new PlatformNotSupportedException("Only Windows and Android currently supported.");
#endif
public string DevServerRootUrl { get; }
private Lazy<HttpClient> LazyHttpClient;
public HttpClient HttpClient => LazyHttpClient.Value;
public HttpMessageHandler? GetPlatformMessageHandler()
{
#if WINDOWS
return null;
#elif ANDROID
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;
#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
}
@simonrozsival
Copy link

FYI since xamarin/xamarin-android#7246 was merged, the CustomHostnameVerifier hack won't be necessary in .NET 7 on Android.

@Eilon
Copy link
Author

Eilon commented Sep 8, 2022

@simonrozsival ah I'll have to try this again and see what works!

@lungavazi
Copy link

This works for me!

@chandlerturner
Copy link

Thank you so much for sharing this!

@sgaccord
Copy link

Thanks!!!you are the best!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment