Xamarin Public Jenkins (auto-signing) e19d552987 Imported Upstream version 5.18.0.161
Former-commit-id: 4db48158d3a35497b8f118ab21b5f08ac3d86d98
2018-10-19 08:34:24 +00:00

784 lines
23 KiB
C#

//
// MacProxy.cs
//
// Author: Jeffrey Stedfast <jeff@xamarin.com>
//
// Copyright (c) 2012-2014 Xamarin Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
using System;
using System.Net;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using ObjCRuntimeInternal;
namespace Mono.Net
{
internal struct CFStreamClientContext {
public IntPtr Version;
public IntPtr Info;
public IntPtr Retain;
public IntPtr Release;
public IntPtr CopyDescription;
}
internal class CFUrl : CFObject
{
public CFUrl (IntPtr handle, bool own) : base (handle, own) { }
[DllImport (CoreFoundationLibrary)]
extern static IntPtr CFURLCreateWithString (IntPtr allocator, IntPtr str, IntPtr baseURL);
public static CFUrl Create (string absolute)
{
if (string.IsNullOrEmpty (absolute))
return null;
CFString str = CFString.Create (absolute);
IntPtr handle = CFURLCreateWithString (IntPtr.Zero, str.Handle, IntPtr.Zero);
str.Dispose ();
if (handle == IntPtr.Zero)
return null;
return new CFUrl (handle, true);
}
}
internal class CFRunLoop : CFObject
{
[DllImport (CFObject.CoreFoundationLibrary)]
static extern void CFRunLoopAddSource (IntPtr rl, IntPtr source, IntPtr mode);
[DllImport (CFObject.CoreFoundationLibrary)]
static extern void CFRunLoopRemoveSource (IntPtr rl, IntPtr source, IntPtr mode);
[DllImport (CFObject.CoreFoundationLibrary)]
static extern int CFRunLoopRunInMode (IntPtr mode, double seconds, bool returnAfterSourceHandled);
[DllImport (CFObject.CoreFoundationLibrary)]
static extern IntPtr CFRunLoopGetCurrent ();
[DllImport (CFObject.CoreFoundationLibrary)]
static extern void CFRunLoopStop (IntPtr rl);
public CFRunLoop (IntPtr handle, bool own): base (handle, own)
{
}
public static CFRunLoop CurrentRunLoop {
get { return new CFRunLoop (CFRunLoopGetCurrent (), false); }
}
public void AddSource (IntPtr source, CFString mode)
{
CFRunLoopAddSource (Handle, source, mode.Handle);
}
public void RemoveSource (IntPtr source, CFString mode)
{
CFRunLoopRemoveSource (Handle, source, mode.Handle);
}
public int RunInMode (CFString mode, double seconds, bool returnAfterSourceHandled)
{
return CFRunLoopRunInMode (mode.Handle, seconds, returnAfterSourceHandled);
}
public void Stop ()
{
CFRunLoopStop (Handle);
}
}
internal enum CFProxyType {
None,
AutoConfigurationUrl,
AutoConfigurationJavaScript,
FTP,
HTTP,
HTTPS,
SOCKS
}
internal class CFProxy {
//static IntPtr kCFProxyAutoConfigurationHTTPResponseKey;
static IntPtr kCFProxyAutoConfigurationJavaScriptKey;
static IntPtr kCFProxyAutoConfigurationURLKey;
static IntPtr kCFProxyHostNameKey;
static IntPtr kCFProxyPasswordKey;
static IntPtr kCFProxyPortNumberKey;
static IntPtr kCFProxyTypeKey;
static IntPtr kCFProxyUsernameKey;
//static IntPtr kCFProxyTypeNone;
static IntPtr kCFProxyTypeAutoConfigurationURL;
static IntPtr kCFProxyTypeAutoConfigurationJavaScript;
static IntPtr kCFProxyTypeFTP;
static IntPtr kCFProxyTypeHTTP;
static IntPtr kCFProxyTypeHTTPS;
static IntPtr kCFProxyTypeSOCKS;
static CFProxy ()
{
IntPtr handle = CFObject.dlopen (CFNetwork.CFNetworkLibrary, 0);
//kCFProxyAutoConfigurationHTTPResponseKey = CFObject.GetCFObjectHandle (handle, "kCFProxyAutoConfigurationHTTPResponseKey");
kCFProxyAutoConfigurationJavaScriptKey = CFObject.GetCFObjectHandle (handle, "kCFProxyAutoConfigurationJavaScriptKey");
kCFProxyAutoConfigurationURLKey = CFObject.GetCFObjectHandle (handle, "kCFProxyAutoConfigurationURLKey");
kCFProxyHostNameKey = CFObject.GetCFObjectHandle (handle, "kCFProxyHostNameKey");
kCFProxyPasswordKey = CFObject.GetCFObjectHandle (handle, "kCFProxyPasswordKey");
kCFProxyPortNumberKey = CFObject.GetCFObjectHandle (handle, "kCFProxyPortNumberKey");
kCFProxyTypeKey = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeKey");
kCFProxyUsernameKey = CFObject.GetCFObjectHandle (handle, "kCFProxyUsernameKey");
//kCFProxyTypeNone = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeNone");
kCFProxyTypeAutoConfigurationURL = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeAutoConfigurationURL");
kCFProxyTypeAutoConfigurationJavaScript = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeAutoConfigurationJavaScript");
kCFProxyTypeFTP = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeFTP");
kCFProxyTypeHTTP = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeHTTP");
kCFProxyTypeHTTPS = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeHTTPS");
kCFProxyTypeSOCKS = CFObject.GetCFObjectHandle (handle, "kCFProxyTypeSOCKS");
CFObject.dlclose (handle);
}
CFDictionary settings;
internal CFProxy (CFDictionary settings)
{
this.settings = settings;
}
static CFProxyType CFProxyTypeToEnum (IntPtr type)
{
if (type == kCFProxyTypeAutoConfigurationJavaScript)
return CFProxyType.AutoConfigurationJavaScript;
if (type == kCFProxyTypeAutoConfigurationURL)
return CFProxyType.AutoConfigurationUrl;
if (type == kCFProxyTypeFTP)
return CFProxyType.FTP;
if (type == kCFProxyTypeHTTP)
return CFProxyType.HTTP;
if (type == kCFProxyTypeHTTPS)
return CFProxyType.HTTPS;
if (type == kCFProxyTypeSOCKS)
return CFProxyType.SOCKS;
//in OSX 10.13 pointer comparison didn't work for kCFProxyTypeAutoConfigurationURL
if (CFString.Compare (type, kCFProxyTypeAutoConfigurationJavaScript) == 0)
return CFProxyType.AutoConfigurationJavaScript;
if (CFString.Compare (type, kCFProxyTypeAutoConfigurationURL) == 0)
return CFProxyType.AutoConfigurationUrl;
if (CFString.Compare (type, kCFProxyTypeFTP) == 0)
return CFProxyType.FTP;
if (CFString.Compare (type, kCFProxyTypeHTTP) == 0)
return CFProxyType.HTTP;
if (CFString.Compare (type, kCFProxyTypeHTTPS) == 0)
return CFProxyType.HTTPS;
if (CFString.Compare (type, kCFProxyTypeSOCKS) == 0)
return CFProxyType.SOCKS;
return CFProxyType.None;
}
#if false
// AFAICT these get used with CFNetworkExecuteProxyAutoConfiguration*()
// TODO: bind CFHTTPMessage so we can return the proper type here.
public IntPtr AutoConfigurationHTTPResponse {
get { return settings[kCFProxyAutoConfigurationHTTPResponseKey]; }
}
#endif
public IntPtr AutoConfigurationJavaScript {
get {
if (kCFProxyAutoConfigurationJavaScriptKey == IntPtr.Zero)
return IntPtr.Zero;
return settings[kCFProxyAutoConfigurationJavaScriptKey];
}
}
public IntPtr AutoConfigurationUrl {
get {
if (kCFProxyAutoConfigurationURLKey == IntPtr.Zero)
return IntPtr.Zero;
return settings[kCFProxyAutoConfigurationURLKey];
}
}
public string HostName {
get {
if (kCFProxyHostNameKey == IntPtr.Zero)
return null;
return CFString.AsString (settings[kCFProxyHostNameKey]);
}
}
public string Password {
get {
if (kCFProxyPasswordKey == IntPtr.Zero)
return null;
return CFString.AsString (settings[kCFProxyPasswordKey]);
}
}
public int Port {
get {
if (kCFProxyPortNumberKey == IntPtr.Zero)
return 0;
return CFNumber.AsInt32 (settings[kCFProxyPortNumberKey]);
}
}
public CFProxyType ProxyType {
get {
if (kCFProxyTypeKey == IntPtr.Zero)
return CFProxyType.None;
return CFProxyTypeToEnum (settings[kCFProxyTypeKey]);
}
}
public string Username {
get {
if (kCFProxyUsernameKey == IntPtr.Zero)
return null;
return CFString.AsString (settings[kCFProxyUsernameKey]);
}
}
}
internal class CFProxySettings {
static IntPtr kCFNetworkProxiesHTTPEnable;
static IntPtr kCFNetworkProxiesHTTPPort;
static IntPtr kCFNetworkProxiesHTTPProxy;
static IntPtr kCFNetworkProxiesProxyAutoConfigEnable;
static IntPtr kCFNetworkProxiesProxyAutoConfigJavaScript;
static IntPtr kCFNetworkProxiesProxyAutoConfigURLString;
static CFProxySettings ()
{
IntPtr handle = CFObject.dlopen (CFNetwork.CFNetworkLibrary, 0);
kCFNetworkProxiesHTTPEnable = CFObject.GetCFObjectHandle (handle, "kCFNetworkProxiesHTTPEnable");
kCFNetworkProxiesHTTPPort = CFObject.GetCFObjectHandle (handle, "kCFNetworkProxiesHTTPPort");
kCFNetworkProxiesHTTPProxy = CFObject.GetCFObjectHandle (handle, "kCFNetworkProxiesHTTPProxy");
kCFNetworkProxiesProxyAutoConfigEnable = CFObject.GetCFObjectHandle (handle, "kCFNetworkProxiesProxyAutoConfigEnable");
kCFNetworkProxiesProxyAutoConfigJavaScript = CFObject.GetCFObjectHandle (handle, "kCFNetworkProxiesProxyAutoConfigJavaScript");
kCFNetworkProxiesProxyAutoConfigURLString = CFObject.GetCFObjectHandle (handle, "kCFNetworkProxiesProxyAutoConfigURLString");
CFObject.dlclose (handle);
}
CFDictionary settings;
public CFProxySettings (CFDictionary settings)
{
this.settings = settings;
}
public CFDictionary Dictionary {
get { return settings; }
}
public bool HTTPEnable {
get {
if (kCFNetworkProxiesHTTPEnable == IntPtr.Zero)
return false;
return CFNumber.AsBool (settings[kCFNetworkProxiesHTTPEnable]);
}
}
public int HTTPPort {
get {
if (kCFNetworkProxiesHTTPPort == IntPtr.Zero)
return 0;
return CFNumber.AsInt32 (settings[kCFNetworkProxiesHTTPPort]);
}
}
public string HTTPProxy {
get {
if (kCFNetworkProxiesHTTPProxy == IntPtr.Zero)
return null;
return CFString.AsString (settings[kCFNetworkProxiesHTTPProxy]);
}
}
public bool ProxyAutoConfigEnable {
get {
if (kCFNetworkProxiesProxyAutoConfigEnable == IntPtr.Zero)
return false;
return CFNumber.AsBool (settings[kCFNetworkProxiesProxyAutoConfigEnable]);
}
}
public string ProxyAutoConfigJavaScript {
get {
if (kCFNetworkProxiesProxyAutoConfigJavaScript == IntPtr.Zero)
return null;
return CFString.AsString (settings[kCFNetworkProxiesProxyAutoConfigJavaScript]);
}
}
public string ProxyAutoConfigURLString {
get {
if (kCFNetworkProxiesProxyAutoConfigURLString == IntPtr.Zero)
return null;
return CFString.AsString (settings[kCFNetworkProxiesProxyAutoConfigURLString]);
}
}
}
internal static class CFNetwork {
#if !MONOTOUCH
public const string CFNetworkLibrary = "/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork";
#else
public const string CFNetworkLibrary = "/System/Library/Frameworks/CFNetwork.framework/CFNetwork";
#endif
[DllImport (CFNetworkLibrary, EntryPoint = "CFNetworkCopyProxiesForAutoConfigurationScript")]
// CFArrayRef CFNetworkCopyProxiesForAutoConfigurationScript (CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL, CFErrorRef* error);
extern static IntPtr CFNetworkCopyProxiesForAutoConfigurationScriptSequential (IntPtr proxyAutoConfigurationScript, IntPtr targetURL, out IntPtr error);
[DllImport (CFNetworkLibrary)]
extern static IntPtr CFNetworkExecuteProxyAutoConfigurationURL (IntPtr proxyAutoConfigURL, IntPtr targetURL, CFProxyAutoConfigurationResultCallback cb, ref CFStreamClientContext clientContext);
class GetProxyData : IDisposable {
public IntPtr script;
public IntPtr targetUri;
public IntPtr error;
public IntPtr result;
public ManualResetEvent evt = new ManualResetEvent (false);
public void Dispose ()
{
evt.Close ();
}
}
static object lock_obj = new object ();
static Queue<GetProxyData> get_proxy_queue;
static AutoResetEvent proxy_event;
static void CFNetworkCopyProxiesForAutoConfigurationScriptThread ()
{
GetProxyData data;
var data_left = true;
while (true) {
proxy_event.WaitOne ();
do {
lock (lock_obj) {
if (get_proxy_queue.Count == 0)
break;
data = get_proxy_queue.Dequeue ();
data_left = get_proxy_queue.Count > 0;
}
data.result = CFNetworkCopyProxiesForAutoConfigurationScriptSequential (data.script, data.targetUri, out data.error);
data.evt.Set ();
} while (data_left);
}
}
static IntPtr CFNetworkCopyProxiesForAutoConfigurationScript (IntPtr proxyAutoConfigurationScript, IntPtr targetURL, out IntPtr error)
{
// This method must only be called on only one thread during an application's life time.
// Note that it's not enough to use a lock to make calls sequential across different threads,
// it has to be one thread. Also note that that thread can't be the main thread, because the
// main thread might be blocking waiting for this network request to finish.
// Another possibility would be to use JavaScriptCore to execute this piece of
// javascript ourselves, but unfortunately it's not available before iOS7.
// See bug #7923 comment #21+.
using (var data = new GetProxyData ()) {
data.script = proxyAutoConfigurationScript;
data.targetUri = targetURL;
lock (lock_obj) {
if (get_proxy_queue == null) {
get_proxy_queue = new Queue<GetProxyData> ();
proxy_event = new AutoResetEvent (false);
new Thread (CFNetworkCopyProxiesForAutoConfigurationScriptThread) {
IsBackground = true,
}.Start ();
}
get_proxy_queue.Enqueue (data);
proxy_event.Set ();
}
data.evt.WaitOne ();
error = data.error;
return data.result;
}
}
static CFArray CopyProxiesForAutoConfigurationScript (IntPtr proxyAutoConfigurationScript, CFUrl targetURL)
{
IntPtr err = IntPtr.Zero;
IntPtr native = CFNetworkCopyProxiesForAutoConfigurationScript (proxyAutoConfigurationScript, targetURL.Handle, out err);
if (native == IntPtr.Zero)
return null;
return new CFArray (native, true);
}
public static CFProxy[] GetProxiesForAutoConfigurationScript (IntPtr proxyAutoConfigurationScript, CFUrl targetURL)
{
if (proxyAutoConfigurationScript == IntPtr.Zero)
throw new ArgumentNullException ("proxyAutoConfigurationScript");
if (targetURL == null)
throw new ArgumentNullException ("targetURL");
CFArray array = CopyProxiesForAutoConfigurationScript (proxyAutoConfigurationScript, targetURL);
if (array == null)
return null;
CFProxy[] 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 ();
return proxies;
}
public static CFProxy[] GetProxiesForAutoConfigurationScript (IntPtr proxyAutoConfigurationScript, Uri targetUri)
{
if (proxyAutoConfigurationScript == IntPtr.Zero)
throw new ArgumentNullException ("proxyAutoConfigurationScript");
if (targetUri == null)
throw new ArgumentNullException ("targetUri");
CFUrl targetURL = CFUrl.Create (targetUri.AbsoluteUri);
CFProxy[] proxies = GetProxiesForAutoConfigurationScript (proxyAutoConfigurationScript, targetURL);
targetURL.Dispose ();
return proxies;
}
delegate void CFProxyAutoConfigurationResultCallback (IntPtr client, IntPtr proxyList, IntPtr error);
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;
}
[DllImport (CFNetworkLibrary)]
// CFArrayRef CFNetworkCopyProxiesForURL (CFURLRef url, CFDictionaryRef proxySettings);
extern static IntPtr CFNetworkCopyProxiesForURL (IntPtr url, IntPtr proxySettings);
static CFArray CopyProxiesForURL (CFUrl url, CFDictionary proxySettings)
{
IntPtr native = CFNetworkCopyProxiesForURL (url.Handle, proxySettings != null ? proxySettings.Handle : IntPtr.Zero);
if (native == IntPtr.Zero)
return null;
return new CFArray (native, true);
}
public static CFProxy[] GetProxiesForURL (CFUrl url, CFProxySettings proxySettings)
{
if (url == null || url.Handle == IntPtr.Zero)
throw new ArgumentNullException ("url");
if (proxySettings == null)
proxySettings = GetSystemProxySettings ();
CFArray array = CopyProxiesForURL (url, proxySettings.Dictionary);
if (array == null)
return null;
CFProxy[] 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 ();
return proxies;
}
public static CFProxy[] GetProxiesForUri (Uri uri, CFProxySettings proxySettings)
{
if (uri == null)
throw new ArgumentNullException ("uri");
CFUrl url = CFUrl.Create (uri.AbsoluteUri);
if (url == null)
return null;
CFProxy[] proxies = GetProxiesForURL (url, proxySettings);
url.Dispose ();
return proxies;
}
[DllImport (CFNetworkLibrary)]
// CFDictionaryRef CFNetworkCopySystemProxySettings (void);
extern static IntPtr CFNetworkCopySystemProxySettings ();
public static CFProxySettings GetSystemProxySettings ()
{
IntPtr native = CFNetworkCopySystemProxySettings ();
if (native == IntPtr.Zero)
return null;
var dict = new CFDictionary (native, true);
return new CFProxySettings (dict);
}
class CFWebProxy : IWebProxy {
ICredentials credentials;
bool userSpecified;
public CFWebProxy ()
{
}
public ICredentials Credentials {
get { return credentials; }
set {
userSpecified = true;
credentials = value;
}
}
static Uri GetProxyUri (CFProxy proxy, out NetworkCredential credentials)
{
string protocol;
switch (proxy.ProxyType) {
case CFProxyType.FTP:
protocol = "ftp://";
break;
case CFProxyType.HTTP:
case CFProxyType.HTTPS:
protocol = "http://";
break;
default:
credentials = null;
return null;
}
string username = proxy.Username;
string password = proxy.Password;
string hostname = proxy.HostName;
int port = proxy.Port;
string uri;
if (username != null)
credentials = new NetworkCredential (username, password);
else
credentials = null;
uri = protocol + hostname + (port != 0 ? ':' + port.ToString () : string.Empty);
return new Uri (uri, UriKind.Absolute);
}
static Uri GetProxyUriFromScript (IntPtr script, Uri targetUri, out NetworkCredential credentials)
{
CFProxy[] proxies = CFNetwork.GetProxiesForAutoConfigurationScript (script, targetUri);
return SelectProxy (proxies, targetUri, out credentials);
}
static Uri ExecuteProxyAutoConfigurationURL (IntPtr proxyAutoConfigURL, Uri targetUri, out NetworkCredential credentials)
{
CFProxy[] proxies = CFNetwork.ExecuteProxyAutoConfigurationURL (proxyAutoConfigURL, targetUri);
return SelectProxy (proxies, targetUri, out credentials);
}
static Uri SelectProxy (CFProxy[] proxies, Uri targetUri, out NetworkCredential credentials)
{
if (proxies == null) {
credentials = null;
return targetUri;
}
for (int i = 0; i < proxies.Length; i++) {
switch (proxies[i].ProxyType) {
case CFProxyType.HTTPS:
case CFProxyType.HTTP:
case CFProxyType.FTP:
// create a Uri based on the hostname/port/etc info
return GetProxyUri (proxies[i], out credentials);
case CFProxyType.SOCKS:
default:
// unsupported proxy type, try the next one
break;
case CFProxyType.None:
// no proxy should be used
credentials = null;
return targetUri;
}
}
credentials = null;
return null;
}
public Uri GetProxy (Uri targetUri)
{
NetworkCredential credentials = null;
Uri proxy = null;
if (targetUri == null)
throw new ArgumentNullException ("targetUri");
try {
CFProxySettings settings = CFNetwork.GetSystemProxySettings ();
CFProxy[] proxies = CFNetwork.GetProxiesForUri (targetUri, settings);
if (proxies != null) {
for (int i = 0; i < proxies.Length && proxy == null; i++) {
switch (proxies[i].ProxyType) {
case CFProxyType.AutoConfigurationJavaScript:
proxy = GetProxyUriFromScript (proxies[i].AutoConfigurationJavaScript, targetUri, out credentials);
break;
case CFProxyType.AutoConfigurationUrl:
proxy = ExecuteProxyAutoConfigurationURL (proxies[i].AutoConfigurationUrl, targetUri, out credentials);
break;
case CFProxyType.HTTPS:
case CFProxyType.HTTP:
case CFProxyType.FTP:
// create a Uri based on the hostname/port/etc info
proxy = GetProxyUri (proxies[i], out credentials);
break;
case CFProxyType.SOCKS:
// unsupported proxy type, try the next one
break;
case CFProxyType.None:
// no proxy should be used
proxy = targetUri;
break;
}
}
if (proxy == null) {
// no supported proxies for this Uri, fall back to trying to connect to targetUri directly
proxy = targetUri;
}
} else {
proxy = targetUri;
}
} catch {
// ignore errors while retrieving proxy data
proxy = targetUri;
}
if (!userSpecified)
this.credentials = credentials;
return proxy;
}
public bool IsBypassed (Uri targetUri)
{
if (targetUri == null)
throw new ArgumentNullException ("targetUri");
return GetProxy (targetUri) == targetUri;
}
}
public static IWebProxy GetDefaultProxy ()
{
return new CFWebProxy ();
}
}
}