From 582ac0ac78bc13f4928039b1c044cf97e90d8e21 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Mon, 29 Jul 2019 05:23:33 -0400 Subject: [PATCH] [d16-3] [CFNetwork] Expose methods that were ignored until the dependencies were present. (#6668) We can know expose the methods. Bindings had to be updated considering the fact that we have a scrut and the type of callbacks. Fixes: https://github.com/xamarin/xamarin-macios/issues/6195 --- src/CoreFoundation/CFProxySupport.cs | 275 +++++++++++++++--- .../CoreFoundation/ProxyTest.cs | 212 ++++++++++++++ tests/monotouch-test/example.pac | 9 + tests/monotouch-test/monotouch-test.csproj | 1 + tests/xtro-sharpie/common-CFNetwork.ignore | 2 - 5 files changed, 459 insertions(+), 40 deletions(-) create mode 100644 tests/monotouch-test/example.pac diff --git a/src/CoreFoundation/CFProxySupport.cs b/src/CoreFoundation/CFProxySupport.cs index a4bc893c66..52ee5ce7ca 100644 --- a/src/CoreFoundation/CFProxySupport.cs +++ b/src/CoreFoundation/CFProxySupport.cs @@ -30,6 +30,8 @@ using System; using System.Net; using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; using ObjCRuntime; using Foundation; @@ -579,62 +581,259 @@ namespace CoreFoundation { dict.DangerousRelease (); return new CFProxySettings (dict); } - -#if notyet - // FIXME: These require bindings for CFRunLoopSource and CFStreamClientContext - - public delegate void CFProxyAutoConfigurationResultCallback (IntPtr client, NSArray proxyList, NSError error); - + + delegate void CFProxyAutoConfigurationResultCallbackInternal (IntPtr client, IntPtr proxyList, IntPtr error); + // helper delegate to reuse code + delegate IntPtr CreatePACCFRunLoopSource (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context); + + static CFProxy[] ParseProxies (IntPtr proxyList) + { + CFProxy[] proxies = null; + if (proxyList != IntPtr.Zero) { + // it was retained in the cbs. + using (var array = new CFArray (proxyList, false)) { + proxies = new CFProxy [array.Count]; + for (int i = 0; i < proxies.Length; i++) { + var dict = Runtime.GetNSObject (array.GetValue (i)); + proxies[i] = new CFProxy (dict); + } + } + } + return proxies; + } + + // helper struct to contain all the data that was used in the callback + struct PACProxyCallbackData + { + public IntPtr ProxyListPtr; // Pointer to a CFArray to later be parsed + public IntPtr ErrorPtr; // Pointer to the Error + public IntPtr CFRunLoopPtr; // Pointer to the runloop, needed to be stopped + + public CFProxy [] ProxyList { + get { + if (ProxyListPtr != IntPtr.Zero) + return ParseProxies (ProxyListPtr); + return null; + } + } + + public NSError Error { + get { + if (ErrorPtr != IntPtr.Zero) + return Runtime.GetNSObject (ErrorPtr); + return null; + } + } + } + + // callback that will sent the client info + [MonoPInvokeCallback (typeof (CFProxyAutoConfigurationResultCallbackInternal))] + static void ExecutePacCallback (IntPtr client, IntPtr proxyList, IntPtr error) + { + // grab the required structure and set the data, according apple docs: + // client + // The client reference originally passed in the clientContext parameter of the + // CFNetworkExecuteProxyAutoConfigurationScript or CFNetworkExecuteProxyAutoConfigurationURL call + // that triggered this callback. + // Well, that is NOT TRUE, the client passed is the client.Info pointer not the client. + var pacCbData = (PACProxyCallbackData) Marshal.PtrToStructure (client, typeof (PACProxyCallbackData)); + // make sure is not released, will be released by the parsing method. + if (proxyList != IntPtr.Zero) { + CFObject.CFRetain (proxyList); + pacCbData.ProxyListPtr = proxyList; + } + if (error != IntPtr.Zero) { + NSObject.DangerousRetain (error); + pacCbData.ErrorPtr = error; + } + // stop the CFRunLoop + var runLoop = new CFRunLoop (pacCbData.CFRunLoopPtr); + Marshal.StructureToPtr (pacCbData, client, false); + runLoop.Stop (); + } + + static async Task<(CFProxy[] proxies, NSError error)> ExecutePacCFRunLoopSourceAsync (CreatePACCFRunLoopSource factory, CancellationToken cancellationToken) + { + CFProxy[] proxies = null; + NSError outError = null; + if (cancellationToken.IsCancellationRequested) + throw new OperationCanceledException ("Operation was cancelled."); + + await Task.Run (() => { + // we need the runloop of THIS thread, so it is important to get it in the correct context + var runLoop = CFRunLoop.Current; + + // build a struct that will have all the needed info for the callback + var pacCbData = new PACProxyCallbackData (); + pacCbData.CFRunLoopPtr = runLoop.Handle; + var pacDataPtr = Marshal.AllocHGlobal (Marshal.SizeOf (pacCbData)); + try { + Marshal.StructureToPtr (pacCbData, pacDataPtr, false); + + var clientContext = new CFStreamClientContext (); + clientContext.Info = pacDataPtr; + + using (var loopSource = new CFRunLoopSource (factory (ExecutePacCallback, ref clientContext))) + using (var mode = new NSString ("Xamarin.iOS.Proxy")) { + + if (cancellationToken.IsCancellationRequested) + throw new OperationCanceledException ("Operation was cancelled."); + + cancellationToken.Register (() => { + //if user cancels, we invalidte the source, stop the runloop and remove the source + loopSource.Invalidate (); + runLoop.RemoveSource (loopSource, mode); + runLoop.Stop (); + }); + runLoop.AddSource (loopSource, mode); + // blocks until stop is called, will be done in the cb set previously + runLoop.RunInMode (mode, double.MaxValue, false); + // does not raise an error if source is not longer present, so no need to worry + runLoop.RemoveSource (loopSource, mode); + } + + if (cancellationToken.IsCancellationRequested) + throw new OperationCanceledException ("Operation was cancelled."); + + pacCbData = (PACProxyCallbackData) Marshal.PtrToStructure (pacDataPtr, typeof (PACProxyCallbackData)); + // get data from the struct + proxies = pacCbData.ProxyList; + outError = pacCbData.Error; + } finally { + // clean resources + if (pacCbData.ProxyListPtr != IntPtr.Zero) + CFObject.CFRelease (pacCbData.ProxyListPtr); + if (pacCbData.ErrorPtr != IntPtr.Zero) + NSObject.DangerousRelease (pacCbData.ErrorPtr); + Marshal.FreeHGlobal (pacDataPtr); + } + }, cancellationToken).ConfigureAwait (false); + + if (cancellationToken.IsCancellationRequested) + throw new OperationCanceledException ("Operation was cancelled."); + return (proxies: proxies, error: outError); + } + + static CFProxy[] ExecutePacCFRunLoopSourceBlocking (CreatePACCFRunLoopSource factory, out NSError outError) + { + var runLoop = CFRunLoop.Current; + outError = null; + + // build a struct that will have all the needed info for the callback + var pacCbData = new PACProxyCallbackData (); + pacCbData.CFRunLoopPtr = runLoop.Handle; + var pacDataPtr = Marshal.AllocHGlobal (Marshal.SizeOf (pacCbData)); + try { + Marshal.StructureToPtr (pacCbData, pacDataPtr, false); + + var clientContext = new CFStreamClientContext (); + clientContext.Info = pacDataPtr; + + using (var loopSource = new CFRunLoopSource (factory (ExecutePacCallback, ref clientContext))) + using (var mode = new NSString ("Xamarin.iOS.Proxy")) { + runLoop.AddSource (loopSource, mode); + runLoop.RunInMode (mode, double.MaxValue, false); + runLoop.RemoveSource (loopSource, mode); + } + pacCbData = (PACProxyCallbackData) Marshal.PtrToStructure (pacDataPtr, typeof (PACProxyCallbackData)); + // get data from the struct + outError = pacCbData.Error; + return pacCbData.ProxyList; + } finally { + if (pacCbData.ProxyListPtr != IntPtr.Zero) + CFObject.CFRelease (pacCbData.ProxyListPtr); + if (pacCbData.ErrorPtr != IntPtr.Zero) + NSObject.DangerousRelease (pacCbData.ErrorPtr); + Marshal.FreeHGlobal (pacDataPtr); + } + } + [DllImport (Constants.CFNetworkLibrary)] extern static /* CFRunLoopSourceRef __nonnull */ IntPtr CFNetworkExecuteProxyAutoConfigurationScript ( /* CFStringRef __nonnull */ IntPtr proxyAutoConfigurationScript, /* CFURLRef __nonnull */ IntPtr targetURL, - /* CFProxyAutoConfigurationResultCallback __nonnull */ IntPtr cb, - /* CFStreamClientContext * __nonnull */ IntPtr clientContext); - - public static CFRunLoopSource ExecuteProxyAutoConfigurationScript (NSString proxyAutoConfigurationScript, NSUrl targetURL, CFProxyAutoConfigurationResultCallback resultCallback, CFStreamClientContext clientContext) + /* CFProxyAutoConfigurationResultCallback __nonnull */ CFProxyAutoConfigurationResultCallbackInternal cb, + /* CFStreamClientContext * __nonnull */ ref CFStreamClientContext clientContext); + + public static CFProxy[] ExecuteProxyAutoConfigurationScript (string proxyAutoConfigurationScript, Uri targetUrl, out NSError outError) { + outError = null; if (proxyAutoConfigurationScript == null) - throw new ArgumentNullException ("proxyAutoConfigurationScript"); + throw new ArgumentNullException (nameof (proxyAutoConfigurationScript)); - if (targetURL == null) - throw new ArgumentNullException ("targetURL"); + if (targetUrl == null) + throw new ArgumentNullException (nameof (targetUrl)); - if (resultCallback == null) - throw new ArgumentNullException ("resultCallback"); - - if (clientContext == null) - throw new ArgumentNullException ("clientContext"); - - IntPtr source = CFNetworkExecuteProxyAutoConfigurationScript (proxyAutoConfigurationScript.Handle, targetURL.Handle, resultCallback, clientContext); - return (source == IntPtr.Zero) ? null : new CFRunLoopSource (source); + using (var pacScript = new NSString (proxyAutoConfigurationScript)) + using (var url = new NSUrl (targetUrl.AbsoluteUri)) { + CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context) { + return CFNetworkExecuteProxyAutoConfigurationScript (pacScript.Handle, url.Handle, cb, ref context); + }; + return ExecutePacCFRunLoopSourceBlocking (factory, out outError); + } } + public static async Task<(CFProxy[] proxies, NSError error)> ExecuteProxyAutoConfigurationScriptAsync (string proxyAutoConfigurationScript, Uri targetUrl, CancellationToken cancellationToken) + { + if (proxyAutoConfigurationScript == null) + throw new ArgumentNullException (nameof (proxyAutoConfigurationScript)); + + if (targetUrl == null) + throw new ArgumentNullException (nameof (targetUrl)); + + using (var pacScript = new NSString (proxyAutoConfigurationScript)) + using (var url = new NSUrl (targetUrl.AbsoluteUri)) { + CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context) { + return CFNetworkExecuteProxyAutoConfigurationScript (pacScript.Handle, url.Handle, cb, ref context); + }; + // use the helper task with a factory for this method + return await ExecutePacCFRunLoopSourceAsync (factory, cancellationToken).ConfigureAwait (false); + } + } + [DllImport (Constants.CFNetworkLibrary)] extern static /* CFRunLoopSourceRef __nonnull */ IntPtr CFNetworkExecuteProxyAutoConfigurationURL ( /* CFURLRef __nonnull */ IntPtr proxyAutoConfigurationURL, /* CFURLRef __nonnull */ IntPtr targetURL, - /* CFProxyAutoConfigurationResultCallback __nonnull */ IntPtr cb, - /* CFStreamClientContext * __nonnull */ IntPtr clientContext); + /* CFProxyAutoConfigurationResultCallback __nonnull */ CFProxyAutoConfigurationResultCallbackInternal cb, + /* CFStreamClientContext * __nonnull */ ref CFStreamClientContext clientContext); - public static CFRunLoopSource ExecuteProxyAutoConfigurationURL (NSUrl proxyAutoConfigurationURL, NSUrl targetURL, CFProxyAutoConfigurationResultCallback resultCallback, CFStreamClientContext clientContext) - { - if (proxyAutoConfigurationURL == null) - throw new ArgumentNullException ("proxyAutoConfigurationURL"); + public static CFProxy[] ExecuteProxyAutoConfigurationUrl (Uri proxyAutoConfigurationUrl, Uri targetUrl, out NSError outError) + { + outError = null; + if (proxyAutoConfigurationUrl == null) + throw new ArgumentNullException (nameof (proxyAutoConfigurationUrl)); - if (targetURL == null) - throw new ArgumentNullException ("targetURL"); + if (targetUrl == null) + throw new ArgumentNullException (nameof (targetUrl)); - if (resultCallback == null) - throw new ArgumentNullException ("resultCallback"); - - if (clientContext == null) - throw new ArgumentNullException ("clientContext"); - - IntPtr source = CFNetworkExecuteProxyAutoConfigurationURL (proxyAutoConfigurationURL.Handle, targetURL.Handle, resultCallback, clientContext); - return (source == IntPtr.Zero) ? null : new CFRunLoopSource (source); + using (var pacUrl = new NSUrl (proxyAutoConfigurationUrl.AbsoluteUri)) // toll free bridge to CFUrl + using (var url = new NSUrl (targetUrl.AbsoluteUri)) { + CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context) { + return CFNetworkExecuteProxyAutoConfigurationURL (pacUrl.Handle, url.Handle, cb, ref context); + }; + return ExecutePacCFRunLoopSourceBlocking (factory, out outError); + } + } + + public static async Task<(CFProxy[] proxies, NSError error)> ExecuteProxyAutoConfigurationUrlAsync (Uri proxyAutoConfigurationUrl, Uri targetUrl, CancellationToken cancellationToken) + { + // similar to the sync method, but we will spawn a thread and wait in an async manner to an autoreset event to be fired + if (proxyAutoConfigurationUrl == null) + throw new ArgumentNullException (nameof (proxyAutoConfigurationUrl)); + + if (targetUrl == null) + throw new ArgumentNullException (nameof (targetUrl)); + + using (var pacUrl = new NSUrl (proxyAutoConfigurationUrl.AbsoluteUri)) // toll free bridge to CFUrl + using (var url = new NSUrl (targetUrl.AbsoluteUri)) { + CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context) { + return CFNetworkExecuteProxyAutoConfigurationURL (pacUrl.Handle, url.Handle, cb, ref context); + }; + // use the helper task with a factory for this method + return await ExecutePacCFRunLoopSourceAsync (factory, cancellationToken).ConfigureAwait (false); + } } -#endif class CFWebProxy : IWebProxy { ICredentials credentials; diff --git a/tests/monotouch-test/CoreFoundation/ProxyTest.cs b/tests/monotouch-test/CoreFoundation/ProxyTest.cs index 0f0347ab3c..a2fc32f15e 100644 --- a/tests/monotouch-test/CoreFoundation/ProxyTest.cs +++ b/tests/monotouch-test/CoreFoundation/ProxyTest.cs @@ -8,6 +8,8 @@ // using System; +using System.Threading; +using System.IO; #if XAMCORE_2_0 using Foundation; using CoreFoundation; @@ -42,5 +44,215 @@ namespace MonoTouchFixtures.CoreFoundation { Dlfcn.dlclose (lib); } } +#if !__WATCHOS__ && !MONOMAC + [Test] + public void TestPACParsingScript () + { + // get the path for the pac file, try to parse it and ensure that + // our cb was called + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + NSError error = null; + var script = File.ReadAllText (pacPath); + var targetUri = new Uri ("http://docs.xamarin.com"); + var proxies = CFNetwork.ExecuteProxyAutoConfigurationScript (script, targetUri, out error); + Assert.IsNull (error, "Null error"); + Assert.AreEqual (1, proxies.Length, "Length"); + // assert the data of the proxy, although we are really testing the js used + Assert.AreEqual (8080, proxies [0].Port, "Port"); + } + + [Test] + public void TestPACParsingScriptNoProxy () + { + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + NSError error = null; + var script = File.ReadAllText (pacPath); + var targetUri = new Uri ("http://google.com"); + var proxies = CFNetwork.ExecuteProxyAutoConfigurationScript (script, targetUri, out error); + Assert.IsNull (error, "Null error"); + Assert.IsNotNull (proxies, "Not null proxies"); + Assert.AreEqual (1, proxies.Length, "Proxies length"); + Assert.AreEqual (CFProxyType.None, proxies [0].ProxyType); + } + + [Test] + public void TestPACParsingScriptError () + { + NSError error = null; + var script = "Not VALID js"; + var targetUri = new Uri ("http://google.com"); + var proxies = CFNetwork.ExecuteProxyAutoConfigurationScript (script, targetUri, out error); + Assert.IsNotNull (error, "Not null error"); + Assert.IsNull (proxies, "Null proxies"); + } + + [Test] + public void TestPACParsingAsync () + { + CFProxy [] proxies = null; + NSError error = null; + NSObject cbClient = null; + bool done = false; + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + + var script = File.ReadAllText (pacPath); + var targetUri = new Uri ("http://docs.xamarin.com"); + + Exception ex; + bool foundProxies; + // similar to the other tests, but we want to ensure that the async/await API works + TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => { + try { + CancellationTokenSource cancelSource = new CancellationTokenSource (); + CancellationToken cancelToken = cancelSource.Token; + var result = await CFNetwork.ExecuteProxyAutoConfigurationScriptAsync (script, targetUri, cancelToken); + proxies = result.proxies; + error = result.error; + } catch (Exception e) { + ex = e; + } finally { + done = true; + } + }, () => done); + Assert.IsNull (cbClient, "Null client"); + Assert.IsNull (error, "Null error"); + Assert.IsNotNull (proxies, "Not null proxies"); + Assert.AreEqual (1, proxies.Length, "Length"); + // assert the data of the proxy, although we are really testing the js used + Assert.AreEqual (8080, proxies [0].Port, "Port"); + } + + [Test] + public void TestPACParsingAsyncNoProxy () + { + CFProxy [] proxies = null; + NSError error = null; + NSObject cbClient = null; + bool done = false; + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + + var script = File.ReadAllText (pacPath); + var targetUri = new Uri ("http://docs.xamarin.com"); + + Exception ex; + bool foundProxies; + // similar to the other tests, but we want to ensure that the async/await API works + TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => { + try { + CancellationTokenSource cancelSource = new CancellationTokenSource (); + CancellationToken cancelToken = cancelSource.Token; + var result = await CFNetwork.ExecuteProxyAutoConfigurationScriptAsync (script, targetUri, cancelToken); + proxies = result.proxies; + error = result.error; + } catch (Exception e) { + ex = e; + } finally { + done = true; + } + }, () => done); + Assert.IsNull (cbClient, "Null client"); + Assert.IsNull (error, "Null error"); + Assert.IsNotNull (proxies, "Not null proxies"); + Assert.AreEqual (1, proxies.Length, "Proxies length"); + Assert.AreEqual (CFProxyType.None, proxies [0].ProxyType); + } + + [Test] + public void TestPACParsingUrl () + { + NSError error; + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + var pacUri = new Uri (pacPath); + var targetUri = new Uri ("http://docs.xamarin.com"); + var proxies = CFNetwork.ExecuteProxyAutoConfigurationUrl (pacUri, targetUri, out error); + Assert.IsNull (error, "Null error"); + Assert.AreEqual (1, proxies.Length, "Length"); + // assert the data of the proxy, although we are really testing the js used + Assert.AreEqual (8080, proxies [0].Port, "Port"); + } + + [Test] + public void TestPacParsingUrlNoProxy () + { + NSError error; + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + var pacUri = new Uri (pacPath); + var targetUri = new Uri ("http://google.com"); + var proxies = CFNetwork.ExecuteProxyAutoConfigurationUrl (pacUri, targetUri, out error); + Assert.IsNull (error, "Null error"); + Assert.IsNotNull (proxies, "Not null proxies"); + Assert.AreEqual (1, proxies.Length, "Proxies length"); + Assert.AreEqual (CFProxyType.None, proxies [0].ProxyType); + } + + [Test] + public void TestPACParsingUrlAsync () + { + CFProxy [] proxies = null; + NSError error = null; + NSObject cbClient = null; + bool done = false; + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + var pacUri = new Uri (pacPath); + var targetUri = new Uri ("http://docs.xamarin.com"); + + Exception ex; + bool foundProxies; + // similar to the other tests, but we want to ensure that the async/await API works + TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => { + try { + CancellationTokenSource cancelSource = new CancellationTokenSource (); + CancellationToken cancelToken = cancelSource.Token; + var result = await CFNetwork.ExecuteProxyAutoConfigurationUrlAsync (pacUri, targetUri, cancelToken); + proxies = result.proxies; + error = result.error; + } catch (Exception e) { + ex = e; + } finally { + done = true; + } + }, () => done); + Assert.IsNull (cbClient, "Null client"); + Assert.IsNull (error, "Null error"); + Assert.IsNotNull (proxies, "Not null proxies"); + Assert.AreEqual (1, proxies.Length, "Length"); + // assert the data of the proxy, although we are really testing the js used + Assert.AreEqual (8080, proxies [0].Port, "Port"); + } + + [Test] + public void TestPACParsingUrlAsyncNoProxy () + { + CFProxy [] proxies = null; + NSError error = null; + NSObject cbClient = null; + bool done = false; + string pacPath = Path.Combine (NSBundle.MainBundle.BundlePath, "example.pac"); + var pacUri = new Uri (pacPath); + var targetUri = new Uri ("http://docs.google.com"); + + Exception ex; + bool foundProxies; + // similar to the other tests, but we want to ensure that the async/await API works + TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () => { + try { + CancellationTokenSource cancelSource = new CancellationTokenSource (); + CancellationToken cancelToken = cancelSource.Token; + var result = await CFNetwork.ExecuteProxyAutoConfigurationUrlAsync (pacUri, targetUri, cancelToken); + proxies = result.proxies; + error = result.error; + } catch (Exception e) { + ex = e; + } finally { + done = true; + } + }, () => done); + Assert.IsNull (cbClient, "Null client"); + Assert.IsNull (error, "Null error"); + Assert.IsNotNull (proxies, "Not null proxies"); + Assert.AreEqual (1, proxies.Length, "Proxies length"); + Assert.AreEqual (CFProxyType.None, proxies [0].ProxyType); + } +#endif } } diff --git a/tests/monotouch-test/example.pac b/tests/monotouch-test/example.pac new file mode 100644 index 0000000000..2ab322021a --- /dev/null +++ b/tests/monotouch-test/example.pac @@ -0,0 +1,9 @@ +// Exmaple PAC file that returns a proxy for the urls that have the +// xamarin domain name. +function FindProxyForURL(url, host) { + if (dnsDomainIs(host, "xamarin.com")) + return "PROXY example.com:8080"; + + if (dnsDomainIs(host, "google.com")) + return "DIRECT"; +} diff --git a/tests/monotouch-test/monotouch-test.csproj b/tests/monotouch-test/monotouch-test.csproj index ab13fd0c99..5634da93cf 100644 --- a/tests/monotouch-test/monotouch-test.csproj +++ b/tests/monotouch-test/monotouch-test.csproj @@ -321,6 +321,7 @@ + diff --git a/tests/xtro-sharpie/common-CFNetwork.ignore b/tests/xtro-sharpie/common-CFNetwork.ignore index 3fa2539605..729912c1e5 100644 --- a/tests/xtro-sharpie/common-CFNetwork.ignore +++ b/tests/xtro-sharpie/common-CFNetwork.ignore @@ -150,8 +150,6 @@ !missing-pinvoke! CFNetServiceSetClient is not bound !missing-pinvoke! CFNetServiceSetTXTData is not bound !missing-pinvoke! CFNetServiceUnscheduleFromRunLoop is not bound -!missing-pinvoke! CFNetworkExecuteProxyAutoConfigurationScript is not bound -!missing-pinvoke! CFNetworkExecuteProxyAutoConfigurationURL is not bound !missing-pinvoke! CFReadStreamCreateWithFTPURL is not bound !missing-pinvoke! CFStreamCreatePairWithSocketToNetService is not bound !missing-pinvoke! CFWriteStreamCreateWithFTPURL is not bound