- Home /
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:
Reading a p12 file off disk
Accepting home rolled certificates
Querying the secure website that requires a certificate to access
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
Is there any way to force the precompilation of this or other solutions to get around this issue on iOS?
Or can anyone recommend another networking solution that will allow me to do the same thing?
Thanks.
Ugh you may be in trouble there. $$anonymous$$ono has some weird GetValue implementation that causes a JIT - when you do it yourself you use GetGet$$anonymous$$ethod off the reflected class and call that. I can't figure if this will help (and you could take a look at the link off that article too).
Really not sure if you can register that signature as we don't really know what it is. If you can find it then the stuff in my article may work.
An excellent article, that whydoidoit linked to. Reflection doesn't play nicely with $$anonymous$$ono AOT on iOS. But I'm not sure it's possible to back-engineer the stack trace into Register* and FastInvoke calls as suggested in the article. Because it's part of System.Net.Security or somesuch :(
Thanks. That is what I thought. WebRequest is no go on iOS. Time to dig into Apple's Networking and Security frameworks, and write significantly more code to reproduce the 5 key lines here. Sigh.
Well it is certainly possible to convince the compiler to emit the code so there is no JIT - just it's damn hard to work out what it is actually trying to access!
$$anonymous$$aybe someone has found a better solution for this?
Answer by Robert-Castle · Aug 10, 2012 at 08:05 PM
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.
Answer by mindlube · Jul 21, 2012 at 04:17 AM
If you don't use home-rolled SSL certs, does Unity handle the https:// ok? Haven't tried it myself, just suggesting :)
WWW is fine with regular https requests, where the server provides the certificate. Here I need to provide a certificate to the server to gain access, and I cannot find any information that shows this scenario is possible with the WWW class.