You've already forked linux-packaging-mono
733 lines
26 KiB
C#
733 lines
26 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="webproxy.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace System.Net {
|
|
using System.Net.NetworkInformation;
|
|
using System.Globalization;
|
|
using System.Security.Permissions;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Collections;
|
|
using System.Runtime.Serialization;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
class WebProxyData {
|
|
internal bool bypassOnLocal;
|
|
internal bool automaticallyDetectSettings;
|
|
internal Uri proxyAddress;
|
|
internal Hashtable proxyHostAddresses;
|
|
internal Uri scriptLocation;
|
|
#if USE_WINIET_AUTODETECT_CACHE
|
|
internal Uri lkgScriptLocation;
|
|
#endif
|
|
internal ArrayList bypassList;
|
|
}
|
|
|
|
// Handles default proxy setting implementation for the Http proxy.
|
|
//
|
|
// The following order is used when determinig proxy settings:
|
|
// 1. web.config/app.config: if available, use settings specified in <system.net><defaultProxy>
|
|
// 2. If the config file doesn't contain proxy settings, read the IE proxy settings
|
|
//
|
|
// If the IE proxy settings contain invalid settings (e.g. "invalid;host" - note the semicolon), then
|
|
// a FormatException will be thrown.
|
|
[Serializable]
|
|
public class WebProxy : IAutoWebProxy, ISerializable {
|
|
// these are settable by the user
|
|
private bool _UseRegistry; // This is just around for serialization. Can we get rid of it?
|
|
private bool _BypassOnLocal;
|
|
private bool m_EnableAutoproxy;
|
|
private Uri _ProxyAddress;
|
|
private ArrayList _BypassList;
|
|
private ICredentials _Credentials;
|
|
|
|
// these are computed on the fly
|
|
private Regex[] _RegExBypassList;
|
|
private Hashtable _ProxyHostAddresses;
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy()
|
|
: this((Uri) null, false, null, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(Uri Address)
|
|
: this(Address, false, null, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(Uri Address, bool BypassOnLocal)
|
|
: this(Address, BypassOnLocal, null, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(Uri Address, bool BypassOnLocal, string[] BypassList)
|
|
: this(Address, BypassOnLocal, BypassList, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(Uri Address, bool BypassOnLocal, string[] BypassList, ICredentials Credentials) {
|
|
_ProxyAddress = Address;
|
|
_BypassOnLocal = BypassOnLocal;
|
|
if (BypassList != null) {
|
|
_BypassList = new ArrayList(BypassList);
|
|
UpdateRegExList(true);
|
|
}
|
|
_Credentials = Credentials;
|
|
m_EnableAutoproxy = true;
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(string Host, int Port)
|
|
: this(new Uri("http://" + Host + ":" + Port.ToString(CultureInfo.InvariantCulture)), false, null, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(string Address)
|
|
: this(CreateProxyUri(Address), false, null, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(string Address, bool BypassOnLocal)
|
|
: this(CreateProxyUri(Address), BypassOnLocal, null, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(string Address, bool BypassOnLocal, string[] BypassList)
|
|
: this(CreateProxyUri(Address), BypassOnLocal, BypassList, null) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public WebProxy(string Address, bool BypassOnLocal, string[] BypassList, ICredentials Credentials)
|
|
: this(CreateProxyUri(Address), BypassOnLocal, BypassList, Credentials) {
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public Uri Address {
|
|
get {
|
|
#if !FEATURE_PAL
|
|
CheckForChanges();
|
|
#endif // !FEATURE_PAL
|
|
return _ProxyAddress;
|
|
}
|
|
set {
|
|
_UseRegistry = false;
|
|
DeleteScriptEngine();
|
|
_ProxyHostAddresses = null; // hash list of proxies
|
|
_ProxyAddress = value;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
internal bool AutoDetect
|
|
{
|
|
set {
|
|
GlobalLog.Assert(_UseRegistry == false, "Cannot set AutoDetect if we are using registry for proxy settings");
|
|
GlobalLog.Assert(m_EnableAutoproxy, "WebProxy#{0}::.ctor()|Cannot set AutoDetect if usesystemdefault is set.", ValidationHelper.HashString(this));
|
|
|
|
if (ScriptEngine == null)
|
|
{
|
|
ScriptEngine = new AutoWebProxyScriptEngine(this, false);
|
|
}
|
|
ScriptEngine.AutomaticallyDetectSettings = value;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
internal Uri ScriptLocation {
|
|
set {
|
|
GlobalLog.Assert(value != null, "Cannot set ScriptLocation to null");
|
|
GlobalLog.Assert(_UseRegistry == false, "Cannot set AutoDetect if we are using registry for proxy settings");
|
|
GlobalLog.Assert(m_EnableAutoproxy, "WebProxy#{0}::.ctor()|Cannot set ScriptLocation if usesystemdefault is set.", ValidationHelper.HashString(this));
|
|
|
|
if (ScriptEngine == null)
|
|
{
|
|
ScriptEngine = new AutoWebProxyScriptEngine(this, false);
|
|
}
|
|
ScriptEngine.AutomaticConfigurationScript = value;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public bool BypassProxyOnLocal {
|
|
get {
|
|
#if !FEATURE_PAL
|
|
CheckForChanges();
|
|
#endif // !FEATURE_PAL
|
|
return _BypassOnLocal;
|
|
}
|
|
set {
|
|
_UseRegistry = false;
|
|
DeleteScriptEngine();
|
|
_BypassOnLocal = value;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public string[] BypassList {
|
|
get {
|
|
#if !FEATURE_PAL
|
|
CheckForChanges();
|
|
#endif // !FEATURE_PAL
|
|
if (_BypassList == null) {
|
|
_BypassList = new ArrayList();
|
|
}
|
|
return (string[])_BypassList.ToArray(typeof(string));
|
|
}
|
|
set {
|
|
_UseRegistry = false;
|
|
DeleteScriptEngine();
|
|
_BypassList = new ArrayList(value);
|
|
UpdateRegExList(true);
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public ICredentials Credentials {
|
|
get {
|
|
return _Credentials;
|
|
}
|
|
set {
|
|
_Credentials = value;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>Sets Credentials to CredentialCache.DefaultCredentials</para>
|
|
/// </devdoc>
|
|
public bool UseDefaultCredentials {
|
|
get {
|
|
return (Credentials is SystemNetworkCredential) ? true : false;
|
|
}
|
|
set {
|
|
_Credentials = value ? CredentialCache.DefaultCredentials : null;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public ArrayList BypassArrayList {
|
|
get {
|
|
#if !FEATURE_PAL
|
|
CheckForChanges();
|
|
#endif // !FEATURE_PAL
|
|
if ( _BypassList == null ) {
|
|
_BypassList = new ArrayList();
|
|
}
|
|
return _BypassList;
|
|
}
|
|
}
|
|
|
|
internal void CheckForChanges() {
|
|
if (ScriptEngine != null)
|
|
{
|
|
ScriptEngine.CheckForChanges();
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public Uri GetProxy(Uri destination) {
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxy() destination:" + ValidationHelper.ToString(destination));
|
|
if (destination == null)
|
|
{
|
|
throw new ArgumentNullException("destination");
|
|
}
|
|
|
|
Uri result;
|
|
if (GetProxyAuto(destination, out result)) {
|
|
return result;
|
|
}
|
|
if (IsBypassedManual(destination)) {
|
|
return destination;
|
|
}
|
|
Hashtable proxyHostAddresses = _ProxyHostAddresses;
|
|
Uri proxy = proxyHostAddresses!=null ? proxyHostAddresses[destination.Scheme] as Uri : _ProxyAddress;
|
|
return proxy!=null? proxy : destination;
|
|
}
|
|
|
|
//
|
|
// CreateProxyUri - maps string to Uri
|
|
//
|
|
|
|
private static Uri CreateProxyUri(string address) {
|
|
if (address == null) {
|
|
return null;
|
|
}
|
|
if (address.IndexOf("://") == -1) {
|
|
address = "http://" + address;
|
|
}
|
|
return new Uri(address);
|
|
}
|
|
|
|
//
|
|
// UpdateRegExList - Update internal _RegExBypassList
|
|
// warning - can throw if the RegEx doesn't parse??
|
|
//
|
|
private void UpdateRegExList(bool canThrow) {
|
|
Regex[] regExBypassList = null;
|
|
ArrayList bypassList = _BypassList;
|
|
try {
|
|
if ( bypassList != null && bypassList.Count > 0 ) {
|
|
regExBypassList = new Regex[bypassList.Count];
|
|
for (int i = 0; i < bypassList.Count; i++ ) {
|
|
regExBypassList[i] = new Regex((string)bypassList[i], RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
|
}
|
|
}
|
|
}
|
|
catch {
|
|
if (!canThrow) {
|
|
_RegExBypassList = null;
|
|
return;
|
|
}
|
|
throw;
|
|
}
|
|
// only update here, cause it could throw earlier in the loop
|
|
_RegExBypassList = regExBypassList;
|
|
}
|
|
|
|
//
|
|
// IsMatchInBypassList - match input against _RegExBypassList
|
|
//
|
|
private bool IsMatchInBypassList(Uri input) {
|
|
UpdateRegExList(false);
|
|
if ( _RegExBypassList == null ) {
|
|
return false;
|
|
}
|
|
string matchUriString = input.Scheme + "://" + input.Host + (!input.IsDefaultPort ? (":"+input.Port) : "" );
|
|
for (int i = 0; i < _BypassList.Count; i++ ) {
|
|
if (_RegExBypassList[i].IsMatch(matchUriString)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// Determines if the host Uri should be routed locally or go through the proxy.
|
|
/// </devdoc>
|
|
private bool IsLocal(Uri host) {
|
|
string hostString = host.Host;
|
|
|
|
IPAddress hostAddress;
|
|
if (IPAddress.TryParse(hostString, out hostAddress))
|
|
{
|
|
return (IPAddress.IsLoopback(hostAddress) || NclUtilities.IsAddressLocal(hostAddress));
|
|
}
|
|
|
|
int dot = hostString.IndexOf('.');
|
|
|
|
// No dot? Local.
|
|
if (dot == -1)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// If it matches the primary domain, it's local. (Whether or not the hostname matches.)
|
|
string local = "." + IPGlobalProperties.InternalGetIPGlobalProperties().DomainName;
|
|
if (local != null && local.Length == (hostString.Length - dot) &&
|
|
string.Compare(local, 0, hostString, dot, local.Length, StringComparison.OrdinalIgnoreCase ) == 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// Determines if the host Uri should be routed locally or go through a proxy.
|
|
/// </devdoc>
|
|
private bool IsLocalInProxyHash(Uri host) {
|
|
Hashtable proxyHostAddresses = _ProxyHostAddresses;
|
|
if (proxyHostAddresses != null) {
|
|
Uri proxy = (Uri) proxyHostAddresses[host.Scheme];
|
|
if (proxy == null) {
|
|
return true; // no proxy entry for this scheme, then bypass
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public bool IsBypassed(Uri host) {
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::IsBypassed() destination:" + ValidationHelper.ToString(host));
|
|
if (host == null)
|
|
{
|
|
throw new ArgumentNullException("host");
|
|
}
|
|
|
|
bool result;
|
|
if (IsBypassedAuto(host, out result)) {
|
|
return result;
|
|
}
|
|
return IsBypassedManual(host);
|
|
}
|
|
|
|
private bool IsBypassedManual(Uri host) {
|
|
if (host.IsLoopback) {
|
|
return true; // bypass localhost from using a proxy.
|
|
}
|
|
return (_ProxyAddress==null && _ProxyHostAddresses==null) || (_BypassOnLocal && IsLocal(host)) || IsMatchInBypassList(host) || IsLocalInProxyHash(host);
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[Obsolete("This method has been deprecated. Please use the proxy selected for you by default. http://go.microsoft.com/fwlink/?linkid=14202")]
|
|
public static WebProxy GetDefaultProxy() {
|
|
#if MONO_FEATURE_CAS
|
|
ExceptionHelper.WebPermissionUnrestricted.Demand();
|
|
#endif
|
|
return new WebProxy(true);
|
|
}
|
|
|
|
//
|
|
// ISerializable constructor
|
|
//
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
protected WebProxy(SerializationInfo serializationInfo, StreamingContext streamingContext) {
|
|
// first check for useRegistry on the serialized proxy
|
|
bool useRegistry = false;
|
|
try {
|
|
useRegistry = serializationInfo.GetBoolean("_UseRegistry");
|
|
}
|
|
catch {
|
|
}
|
|
if (useRegistry) {
|
|
// just make the proxy advanced, don't populate with any settings
|
|
// note - this will happen in the context of the user performing the deserialization (their proxy settings get read)
|
|
#if MONO_FEATURE_CAS
|
|
ExceptionHelper.WebPermissionUnrestricted.Demand();
|
|
#endif
|
|
UnsafeUpdateFromRegistry();
|
|
return;
|
|
}
|
|
// normal proxy
|
|
_ProxyAddress = (Uri)serializationInfo.GetValue("_ProxyAddress", typeof(Uri));
|
|
_BypassOnLocal = serializationInfo.GetBoolean("_BypassOnLocal");
|
|
_BypassList = (ArrayList)serializationInfo.GetValue("_BypassList", typeof(ArrayList));
|
|
try {
|
|
UseDefaultCredentials = serializationInfo.GetBoolean("_UseDefaultCredentials");
|
|
}
|
|
catch {
|
|
}
|
|
}
|
|
|
|
//
|
|
// ISerializable method
|
|
//
|
|
/// <internalonly/>
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
|
|
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter, SerializationFormatter=true)]
|
|
void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
|
|
{
|
|
GetObjectData(serializationInfo, streamingContext);
|
|
}
|
|
|
|
//
|
|
// FxCop: provide a way for derived classes to access this method even if they reimplement ISerializable.
|
|
//
|
|
[SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter=true)]
|
|
protected virtual void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
|
|
{
|
|
serializationInfo.AddValue("_BypassOnLocal", _BypassOnLocal);
|
|
serializationInfo.AddValue("_ProxyAddress", _ProxyAddress);
|
|
serializationInfo.AddValue("_BypassList", _BypassList);
|
|
serializationInfo.AddValue("_UseDefaultCredentials", UseDefaultCredentials);
|
|
if (_UseRegistry) {
|
|
serializationInfo.AddValue("_UseRegistry", true);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Handles proxy settings by using Internet Explorer based settings,
|
|
/// keep in mind the security implications when downloading and running
|
|
/// script from any network source configured in Internet Explorer.
|
|
/// </summary>
|
|
|
|
private AutoWebProxyScriptEngine m_ScriptEngine;
|
|
|
|
internal AutoWebProxyScriptEngine ScriptEngine {
|
|
get {
|
|
return m_ScriptEngine;
|
|
}
|
|
set {
|
|
m_ScriptEngine = value;
|
|
}
|
|
}
|
|
|
|
#if MONO
|
|
public static IWebProxy CreateDefaultProxy ()
|
|
{
|
|
#if FEATURE_NO_BSD_SOCKETS
|
|
throw new PlatformNotSupportedException ();
|
|
#elif MONOTOUCH
|
|
return Mono.Net.CFNetwork.GetDefaultProxy ();
|
|
#elif MONODROID && !MOBILE_DESKTOP_HOST
|
|
// Return the system web proxy. This only works for ICS+.
|
|
var data = AndroidPlatform.GetDefaultProxy ();
|
|
if (data != null)
|
|
return data;
|
|
|
|
return new WebProxy (true);
|
|
#elif ORBIS
|
|
return new WebProxy (true);
|
|
#else
|
|
if (Platform.IsMacOS) {
|
|
var data = Mono.Net.CFNetwork.GetDefaultProxy ();
|
|
if (data != null)
|
|
return data;
|
|
}
|
|
|
|
return new WebProxy (true);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
// This constructor is used internally to make WebProxies that read their state from the registry.
|
|
//
|
|
internal WebProxy(bool enableAutoproxy)
|
|
{
|
|
m_EnableAutoproxy = enableAutoproxy;
|
|
UnsafeUpdateFromRegistry();
|
|
}
|
|
|
|
internal void DeleteScriptEngine() {
|
|
if (ScriptEngine != null) {
|
|
ScriptEngine.Close();
|
|
ScriptEngine = null;
|
|
}
|
|
}
|
|
|
|
internal void UnsafeUpdateFromRegistry() {
|
|
GlobalLog.Assert(!_UseRegistry, "WebProxy#{0}::UnsafeUpdateFromRegistry()|_UseRegistry ScriptEngine#{1}", ValidationHelper.HashString(this), ValidationHelper.HashString(m_ScriptEngine));
|
|
_UseRegistry = true;
|
|
#if !FEATURE_PAL || !MOBILE
|
|
ScriptEngine = new AutoWebProxyScriptEngine(this, true);
|
|
WebProxyData webProxyData = ScriptEngine.GetWebProxyData();
|
|
|
|
Update(webProxyData);
|
|
#endif
|
|
}
|
|
|
|
internal void Update(WebProxyData webProxyData) {
|
|
#if TRAVE
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::Update() Before " + DumpIWebProxy(this));
|
|
#endif
|
|
// update needs to happen atomically
|
|
lock (this) {
|
|
_BypassOnLocal = webProxyData.bypassOnLocal;
|
|
_ProxyAddress = webProxyData.proxyAddress;
|
|
_ProxyHostAddresses = webProxyData.proxyHostAddresses;
|
|
_BypassList = webProxyData.bypassList;
|
|
|
|
ScriptEngine.AutomaticallyDetectSettings = m_EnableAutoproxy && webProxyData.automaticallyDetectSettings;
|
|
ScriptEngine.AutomaticConfigurationScript = m_EnableAutoproxy ? webProxyData.scriptLocation : null;
|
|
}
|
|
#if TRAVE
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::Update() After " + DumpIWebProxy(this));
|
|
#endif
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>
|
|
/// We really didn't want to expose this. IWebProxy is kind of broken so we needed
|
|
/// a different way of calling into IsBypassed/GetProxy with a single method call.
|
|
/// We need to make it public though, so it is. This API will return null if
|
|
/// the proxy is to be bypassed, otherwise it returns an array of Uri to proxise
|
|
/// that may be used to access the destination. If an entry in the array is null
|
|
/// we want to try a direct access. Today we only attempt using the first entry.
|
|
/// </para>
|
|
/// </devdoc>
|
|
ProxyChain IAutoWebProxy.GetProxies(Uri destination) {
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxies() destination:" + ValidationHelper.ToString(destination));
|
|
if (destination == null)
|
|
{
|
|
throw new ArgumentNullException("destination");
|
|
}
|
|
return new ProxyScriptChain(this, destination);
|
|
}
|
|
|
|
#if TRAVE
|
|
internal static string DumpIWebProxy(IWebProxy proxy) {
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
stringBuilder.Append(" Type: " + ValidationHelper.ToString(proxy.GetType()) + "\r\n");
|
|
WebProxy webProxy = proxy as WebProxy;
|
|
if (webProxy!=null) {
|
|
stringBuilder.Append(" - Address: " + ValidationHelper.ToString(webProxy._ProxyAddress) + "\r\n");
|
|
stringBuilder.Append(" - BypassProxyOnLocal: " + ValidationHelper.ToString(webProxy._BypassOnLocal) + "\r\n");
|
|
}
|
|
stringBuilder.Append(" - -------------------------------------------------");
|
|
return stringBuilder.ToString();
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// IWebProxy implementation
|
|
//
|
|
|
|
// Get proxies can never return null in the case of ExecutionSuccess.
|
|
private bool GetProxyAuto(Uri destination, out Uri proxyUri) {
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxyAuto() destination:" + ValidationHelper.ToString(destination));
|
|
|
|
proxyUri = null;
|
|
if (ScriptEngine == null) {
|
|
return false;
|
|
}
|
|
IList<string> proxies = null;
|
|
if (!ScriptEngine.GetProxies(destination, out proxies)) {
|
|
return false;
|
|
}
|
|
|
|
// Returning null in case 'proxies.Count == 0' means, no proxy available (incl. DIRECT), the request is prohibited.
|
|
if (proxies.Count > 0) {
|
|
if (AreAllBypassed(proxies, true)) {
|
|
// this is the broken behaviour of IWebProxy. Returning the same destination means bypass
|
|
proxyUri = destination;
|
|
}
|
|
else {
|
|
proxyUri = ProxyUri(proxies[0]);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private bool IsBypassedAuto(Uri destination, out bool isBypassed) {
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::IsBypassedAuto() destination:" + ValidationHelper.ToString(destination));
|
|
|
|
isBypassed = true;
|
|
|
|
if (ScriptEngine == null) {
|
|
return false;
|
|
}
|
|
IList<string> proxyList;
|
|
if (!ScriptEngine.GetProxies(destination, out proxyList)) {
|
|
return false;
|
|
}
|
|
if (proxyList.Count == 0) {
|
|
isBypassed = false;
|
|
}
|
|
else {
|
|
isBypassed = AreAllBypassed(proxyList, true);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
internal Uri[] GetProxiesAuto(Uri destination, ref int syncStatus)
|
|
{
|
|
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::GetProxiesAuto() destination:" + ValidationHelper.ToString(destination));
|
|
|
|
if (ScriptEngine == null) {
|
|
return null;
|
|
}
|
|
|
|
IList<string> proxyList = null;
|
|
if (!ScriptEngine.GetProxies(destination, out proxyList, ref syncStatus)) {
|
|
return null;
|
|
}
|
|
|
|
Uri[] proxyUris = null;
|
|
if (proxyList.Count == 0) {
|
|
proxyUris = new Uri[] { };
|
|
}
|
|
else if (AreAllBypassed(proxyList, false)) {
|
|
proxyUris = new Uri[] { null };
|
|
}
|
|
else {
|
|
proxyUris = new Uri[proxyList.Count];
|
|
for (int i = 0; i < proxyList.Count; i++) {
|
|
proxyUris[i] = ProxyUri(proxyList[i]);
|
|
}
|
|
}
|
|
return proxyUris;
|
|
}
|
|
|
|
internal void AbortGetProxiesAuto(ref int syncStatus)
|
|
{
|
|
if (ScriptEngine != null)
|
|
{
|
|
ScriptEngine.Abort(ref syncStatus);
|
|
}
|
|
}
|
|
|
|
internal Uri GetProxyAutoFailover(Uri destination)
|
|
{
|
|
if (IsBypassedManual(destination))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Uri proxy = _ProxyAddress;
|
|
Hashtable proxyHostAddresses = _ProxyHostAddresses;
|
|
if (proxyHostAddresses != null)
|
|
{
|
|
proxy = proxyHostAddresses[destination.Scheme] as Uri;
|
|
}
|
|
return proxy;
|
|
}
|
|
|
|
private static bool AreAllBypassed(IEnumerable<string> proxies, bool checkFirstOnly) {
|
|
bool isBypassed = true;
|
|
|
|
foreach (string proxy in proxies) {
|
|
isBypassed = string.IsNullOrEmpty(proxy);
|
|
|
|
if (checkFirstOnly || !isBypassed) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return isBypassed;
|
|
}
|
|
|
|
private static Uri ProxyUri(string proxyName) {
|
|
return proxyName==null || proxyName.Length==0 ? null : new Uri("http://" + proxyName);
|
|
}
|
|
}
|
|
}
|