public Uri?GetProxy(Uri targetUri) { using (SafeCFDictionaryHandle systemProxySettings = CFNetworkCopySystemProxySettings()) using (SafeCreateHandle cfurl = CFURLCreateWithString(targetUri.AbsoluteUri)) using (SafeCFArrayHandle proxies = CFNetworkCopyProxiesForURL(cfurl, systemProxySettings)) { long proxyCount = CFArrayGetCount(proxies); for (int i = 0; i < proxyCount; i++) { IntPtr proxyValue = CFArrayGetValueAtIndex(proxies, i); using (SafeCFDictionaryHandle proxyDict = new SafeCFDictionaryHandle(proxyValue, false)) { CFProxy proxy = new CFProxy(proxyDict); if (proxy.ProxyType == CFProxy.kCFProxyTypeAutoConfigurationURL || proxy.ProxyType == CFProxy.kCFProxyTypeAutoConfigurationJavaScript) { Uri?result = ExecuteProxyAutoConfiguration(cfurl, proxy); if (result != null) { return(result); } } else if (proxy.ProxyType == CFProxy.kCFProxyTypeHTTP || proxy.ProxyType == CFProxy.kCFProxyTypeHTTPS) { return(GetProxyUri("http", proxy)); } } } } return(null); }
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); }
internal static partial SafeCFArrayHandle CFNetworkCopyProxiesForURL(SafeCreateHandle url, SafeCFDictionaryHandle proxySettings);
#pragma warning restore CA1810 public CFProxy(SafeCFDictionaryHandle dictionary) { _dictionary = dictionary; }
internal static extern IntPtr CFDictionaryGetValue(SafeCFDictionaryHandle handle, IntPtr key);