HttpWebResponse and JIT on iOS

I am having JIT compiler issues with the following code on iOS. The code works in the editor (on a Mac), but not on an iOS device.
I am using .NET 2.0, iOS 5.1, No stripping, and slow and safe calls. I have not installed any additional libraries.

using UnityEngine;
using System.Collections;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Net;
using System.Net.Security;

void Start() {
  X509Certificate2 p12 = new X509Certificate2(p12FilePath, password);
  ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; //accept anything

  HttpWebRequest request = WebRequest.Create("https://www.example.com") as HttpWebRequest;
  request.ClientCertificates.Add(p12);

  HttpWebResponse response = request.GetResponse() as HttpWebResponse;
  print(response.StatusDescription);
  Stream dataStream = response.GetResponseStream ();
  StreamReader reader = new StreamReader (dataStream);
  string responseFromServer = reader.ReadToEnd ();
  print(responseFromServer);

  reader.Close();
  response.Close();
}

What the code is doing:

  1. Reading a p12 file off disk
  2. Accepting home rolled certificates
  3. Querying the secure website that requires a certificate to access
  4. Printing the response.

The line where it all goes wrong is

HttpWebResponse response = request.GetResponse() as HttpWebResponse;

giving the error

ExecutionEngineException: Attempting to JIT compile method 'System.Reflection.MonoProperty:GetterAdapterFrame<Mono.Security.Protocol.Tls.HttpsClientStream, bool> (System.Reflection.MonoProperty/Getter`2<Mono.Security.Protocol.Tls.HttpsClientStream, bool>,object)' while running with --aot-only.

  at System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[] index) [0x00000] in <filename unknown>:0 
  at System.Net.WebConnection.Write (System.Net.HttpWebRequest request, System.Byte[] buffer, Int32 offset, Int32 size, System.String& err_msg) [0x00000] in <filename unknown>:0 
  at System.Net.WebConnectionStream.WriteHeaders () [0x00000] in <filename unknown>:0 
  at System.Net.WebConnectionStream.SetHeaders (System.Byte[] buffer) [0x00000] in <filename unknown>:0 
  at System.Net.HttpWebRequest.SendRequestHeaders (Boolean propagate_error) [0x00000] in <filename unknown>:0 
Rethrow as WebException: Error: SendFailure (Attempting to JIT compile method 'System.Reflection.MonoProperty:GetterAdapterFrame<Mono.Security.Protocol.Tls.HttpsClientStream, bool> (System.Reflection.MonoProperty/Getter`2<Mono.Security.Protocol.Tls.HttpsClientStream, bool>,object)' while running with --aot-only.
)
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
  at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0 
  at SecureWebAccess.Start () [0x00000] in <filename unknown>:0 
  1. Is there any way to force the precompilation of this or other solutions to get around this issue on iOS?
  2. Or can anyone recommend another networking solution that will allow me to do the same thing?

Thanks.

If you don’t use home-rolled SSL certs, does Unity handle the https:// ok? Haven’t tried it myself, just suggesting :slight_smile:

I gave up trying to figure out if this was possible, and used AFNetworking for iOS instead. Handles everything i need and allows me to manage the download queue easily. Also using native Objective-C allows me to easily use the keychain to securely store the certificates.

The main thing this adventure taught me is this: When adding a new feature that uses a new bit of .Net test it on your target platform ASAP.

This handy compatibility guide is also worth reading if you are poking into the darker corners of Mono.