public Uri?ExecuteProxyAutoConfiguration(SafeCreateHandle cfurl, CFProxy proxy) { Uri? result = null; CFRunLoopRef runLoop = CFRunLoopGetCurrent(); // Callback that will be called after executing the configuration script CFProxyAutoConfigurationResultCallback cb = (IntPtr client, IntPtr proxyListHandle, IntPtr error) => { if (proxyListHandle != IntPtr.Zero) { using (var proxyList = new SafeCFArrayHandle(proxyListHandle, false)) { long proxyCount = CFArrayGetCount(proxyList); for (int i = 0; i < proxyCount; i++) { IntPtr proxyValue = CFArrayGetValueAtIndex(proxyList, i); using (SafeCFDictionaryHandle proxyDict = new SafeCFDictionaryHandle(proxyValue, false)) { CFProxy proxy = new CFProxy(proxyDict); if (proxy.ProxyType == CFProxy.kCFProxyTypeHTTP || proxy.ProxyType == CFProxy.kCFProxyTypeHTTPS) { result = GetProxyUri("http", proxy); break; } } } } } CFRunLoopStop(runLoop); }; CFStreamClientContext clientContext = default; CFRunLoopSourceRef loopSource = proxy.ProxyType == CFProxy.kCFProxyTypeAutoConfigurationURL ? CFNetworkExecuteProxyAutoConfigurationURL(proxy.AutoConfigurationURL, cfurl, cb, ref clientContext) : CFNetworkExecuteProxyAutoConfigurationScript(proxy.AutoConfigurationJavaScript, cfurl, cb, ref clientContext); using (var mode = CFStringCreateWithCString(typeof(MacProxy).FullName !)) { IntPtr modeHandle = mode.DangerousGetHandle(); CFRunLoopAddSource(runLoop, loopSource, modeHandle); CFRunLoopRunInMode(modeHandle, double.MaxValue, 0); CFRunLoopSourceInvalidate(loopSource); } GC.KeepAlive(cb); return(result); }
protected virtual bool SetCFClientFlags(CFStreamEventType inFlags, IntPtr inCallback, IntPtr inContextPtr) { CFStreamClientContext inContext; if (inContextPtr == IntPtr.Zero) { return(false); } inContext = (CFStreamClientContext)Marshal.PtrToStructure(inContextPtr, typeof(CFStreamClientContext)); if (inContext.Version != 0) { return(false); } context.Release(); context = inContext; context.Retain(); flags = inFlags; callback = inCallback; return(true); }
public static CFRunLoopSource ExecuteProxyAutoConfigurationURL (NSUrl proxyAutoConfigurationURL, NSUrl targetURL, CFProxyAutoConfigurationResultCallback resultCallback, CFStreamClientContext clientContext) { if (proxyAutoConfigurationURL == null) throw new ArgumentNullException ("proxyAutoConfigurationURL"); if (targetURL == null) throw new ArgumentNullException ("targetURL"); if (resultCallback == null) throw new ArgumentNullException ("resultCallback"); if (clientContext == null) throw new ArgumentNullException ("clientContext"); IntPtr source = CFNetworkExecuteProxyAutoConfigurationURL (proxyAutoConfigurationURL.Handle, targetURL.Handle, resultCallback, clientContext); if (source != IntPtr.Zero) return new CFRunLoopSource (source); return null; }
internal static partial CFRunLoopSourceRef CFNetworkExecuteProxyAutoConfigurationScript( IntPtr proxyAutoConfigurationScript, SafeCreateHandle targetURL, CFProxyAutoConfigurationResultCallback cb, ref CFStreamClientContext clientContext);
public void EnableEvents(CFRunLoop runLoop, NSString runLoopMode) { if (open || closed || (loop != null)) throw new InvalidOperationException (); CheckHandle (); loop = runLoop; loopMode = runLoopMode; var ctx = new CFStreamClientContext (); ctx.Info = GCHandle.ToIntPtr (gch); var args = CFStreamEventType.OpenCompleted | CFStreamEventType.CanAcceptBytes | CFStreamEventType.HasBytesAvailable | CFStreamEventType.CanAcceptBytes | CFStreamEventType.ErrorOccurred | CFStreamEventType.EndEncountered; var ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (CFStreamClientContext))); try { Marshal.StructureToPtr (ctx, ptr, false); if (!DoSetClient (OnCallback, (int)args, ptr)) throw new InvalidOperationException ("Stream does not support async events."); } finally { Marshal.FreeHGlobal (ptr); } ScheduleWithRunLoop (runLoop, runLoopMode); }
internal CFSocket (CFSocketNativeHandle sock) { var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack; gch = GCHandle.Alloc (this); var ctx = new CFStreamClientContext (); ctx.Info = GCHandle.ToIntPtr (gch); var ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof(CFStreamClientContext))); try { Marshal.StructureToPtr (ctx, ptr, false); handle = CFSocketCreateWithNative ( IntPtr.Zero, sock, cbTypes, OnCallback, ptr); } finally { Marshal.FreeHGlobal (ptr); } if (handle == IntPtr.Zero) throw new CFSocketException (CFSocketError.Error); var source = new CFRunLoopSource (CFSocketCreateRunLoopSource (IntPtr.Zero, handle, 0)); var loop = CFRunLoop.Current; loop.AddSource (source, CFRunLoop.CFDefaultRunLoopMode); }
CFSocket (int family, int type, int proto, CFRunLoop loop) { var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.ConnectCallBack; gch = GCHandle.Alloc (this); var ctx = new CFStreamClientContext (); ctx.Info = GCHandle.ToIntPtr (gch); var ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof(CFStreamClientContext))); try { Marshal.StructureToPtr (ctx, ptr, false); handle = CFSocketCreate ( IntPtr.Zero, family, type, proto, cbTypes, OnCallback, ptr); } finally { Marshal.FreeHGlobal (ptr); } if (handle == IntPtr.Zero) throw new CFSocketException (CFSocketError.Error); gch = GCHandle.Alloc (this); var source = new CFRunLoopSource (CFSocketCreateRunLoopSource (IntPtr.Zero, handle, 0)); loop.AddSource (source, CFRunLoop.CFDefaultRunLoopMode); }
public static CFProxy[] ExecuteProxyAutoConfigurationURL (IntPtr proxyAutoConfigURL, Uri targetURL) { CFUrl url = CFUrl.Create (targetURL.AbsoluteUri); if (url == null) return null; CFProxy[] proxies = null; var runLoop = CFRunLoop.CurrentRunLoop; // Callback that will be called after executing the configuration script CFProxyAutoConfigurationResultCallback cb = delegate (IntPtr client, IntPtr proxyList, IntPtr error) { if (proxyList != IntPtr.Zero) { var array = new CFArray (proxyList, false); proxies = new CFProxy [array.Count]; for (int i = 0; i < proxies.Length; i++) { CFDictionary dict = new CFDictionary (array[i], false); proxies[i] = new CFProxy (dict); } array.Dispose (); } runLoop.Stop (); }; var clientContext = new CFStreamClientContext (); var loopSource = CFNetworkExecuteProxyAutoConfigurationURL (proxyAutoConfigURL, url.Handle, cb, ref clientContext); // Create a private mode var mode = CFString.Create ("Mono.MacProxy"); runLoop.AddSource (loopSource, mode); runLoop.RunInMode (mode, double.MaxValue, false); runLoop.RemoveSource (loopSource, mode); return proxies; }
extern static IntPtr CFNetworkExecuteProxyAutoConfigurationURL (IntPtr proxyAutoConfigURL, IntPtr targetURL, CFProxyAutoConfigurationResultCallback cb, ref CFStreamClientContext clientContext);