Skip to content

Commit

Permalink
Updating serialization of Proxy for W3C-compliant drivers in .NET
Browse files Browse the repository at this point in the history
Fixes issue #4574 for .NET.
  • Loading branch information
jimevans committed Aug 31, 2017
1 parent 20ca315 commit eead3f1
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 39 deletions.
25 changes: 25 additions & 0 deletions dotnet/src/webdriver/Firefox/FirefoxOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class FirefoxOptions : DriverOptions
private string browserBinaryLocation;
private FirefoxDriverLogLevel logLevel = FirefoxDriverLogLevel.Default;
private FirefoxProfile profile;
private Proxy proxy;
private List<string> firefoxArguments = new List<string>();
private Dictionary<string, object> profilePreferences = new Dictionary<string, object>();
private Dictionary<string, object> additionalCapabilities = new Dictionary<string, object>();
Expand Down Expand Up @@ -120,6 +121,15 @@ public string BrowserExecutableLocation
set { this.browserBinaryLocation = value; }
}

/// <summary>
/// Gets or sets the <see cref="Proxy"/> to be used with Firefox.
/// </summary>
public Proxy Proxy
{
get { return this.proxy; }
set { this.proxy = value; }
}

/// <summary>
/// Gets or sets the logging level of the Firefox driver.
/// </summary>
Expand Down Expand Up @@ -270,6 +280,7 @@ public void AddAdditionalCapability(string capabilityName, object capabilityValu
if (capabilityName == IsMarionetteCapability ||
capabilityName == FirefoxProfileCapability ||
capabilityName == FirefoxBinaryCapability ||
capabilityName == CapabilityType.Proxy ||
capabilityName == FirefoxLegacyProfileCapability ||
capabilityName == FirefoxLegacyBinaryCapability ||
capabilityName == FirefoxArgumentsCapability ||
Expand Down Expand Up @@ -307,6 +318,15 @@ public override ICapabilities ToCapabilities()
DesiredCapabilities capabilities = DesiredCapabilities.Firefox();
if (this.isMarionette)
{
if (this.proxy != null)
{
Dictionary<string, object> proxyCapabiity = this.proxy.ToCapability();
if (proxyCapabiity != null)
{
capabilities.SetCapability(CapabilityType.Proxy, proxyCapabiity);
}
}

Dictionary<string, object> firefoxOptions = this.GenerateFirefoxOptionsDictionary();
capabilities.SetCapability(FirefoxOptionsCapability, firefoxOptions);
}
Expand All @@ -315,6 +335,11 @@ public override ICapabilities ToCapabilities()
capabilities.SetCapability(IsMarionetteCapability, this.isMarionette);
if (this.profile != null)
{
if (this.proxy != null)
{
this.profile.InternalSetProxyPreferences(this.proxy);
}

capabilities.SetCapability(FirefoxProfileCapability, this.profile.ToBase64String());
}

Expand Down
75 changes: 43 additions & 32 deletions dotnet/src/webdriver/Firefox/FirefoxProfile.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="FirefoxProfile.cs" company="WebDriver Committers">
// <copyright file="FirefoxProfile.cs" company="WebDriver Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
Expand Down Expand Up @@ -241,39 +241,10 @@ public void SetPreference(string name, bool value)
/// </summary>
/// <param name="proxy">The <see cref="Proxy"/> object defining the proxy
/// preferences for the profile.</param>
[Obsolete("Use the FirefoxOptions class to set a proxy for Firefox.")]
public void SetProxyPreferences(Proxy proxy)
{
if (proxy == null)
{
throw new ArgumentNullException("proxy", "proxy must not be null");
}

if (proxy.Kind == ProxyKind.Unspecified)
{
return;
}

this.SetPreference("network.proxy.type", (int)proxy.Kind);

switch (proxy.Kind)
{
case ProxyKind.Manual: // By default, assume we're proxying the lot
this.SetPreference("network.proxy.no_proxies_on", string.Empty);

this.SetManualProxyPreference("ftp", proxy.FtpProxy);
this.SetManualProxyPreference("http", proxy.HttpProxy);
this.SetManualProxyPreference("ssl", proxy.SslProxy);
this.SetManualProxyPreference("socks", proxy.SocksProxy);
if (proxy.NoProxy != null)
{
this.SetPreference("network.proxy.no_proxies_on", proxy.NoProxy);
}

break;
case ProxyKind.ProxyAutoConfigure:
this.SetPreference("network.proxy.autoconfig_url", proxy.ProxyAutoConfigUrl);
break;
}
this.InternalSetProxyPreferences(proxy);
}

/// <summary>
Expand Down Expand Up @@ -356,6 +327,46 @@ internal void AddWebDriverExtension()
}
}

/// <summary>
/// Internal implementation to set proxy preferences for this profile.
/// </summary>
/// <param name="proxy">The <see cref="Proxy"/> object defining the proxy
/// preferences for the profile.</param>
internal void InternalSetProxyPreferences(Proxy proxy)
{
if (proxy == null)
{
throw new ArgumentNullException("proxy", "proxy must not be null");
}

if (proxy.Kind == ProxyKind.Unspecified)
{
return;
}

this.SetPreference("network.proxy.type", (int)proxy.Kind);

switch (proxy.Kind)
{
case ProxyKind.Manual: // By default, assume we're proxying the lot
this.SetPreference("network.proxy.no_proxies_on", string.Empty);

this.SetManualProxyPreference("ftp", proxy.FtpProxy);
this.SetManualProxyPreference("http", proxy.HttpProxy);
this.SetManualProxyPreference("ssl", proxy.SslProxy);
this.SetManualProxyPreference("socks", proxy.SocksProxy);
if (proxy.NoProxy != null)
{
this.SetPreference("network.proxy.no_proxies_on", proxy.NoProxy);
}

break;
case ProxyKind.ProxyAutoConfigure:
this.SetPreference("network.proxy.autoconfig_url", proxy.ProxyAutoConfigUrl);
break;
}
}

/// <summary>
/// Generates a random directory name for the profile.
/// </summary>
Expand Down
8 changes: 6 additions & 2 deletions dotnet/src/webdriver/IE/InternetExplorerOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="InternetExplorerOptions.cs" company="WebDriver Committers">
// <copyright file="InternetExplorerOptions.cs" company="WebDriver Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
Expand Down Expand Up @@ -484,7 +484,11 @@ public override ICapabilities ToCapabilities()

if (this.proxy != null)
{
capabilities.SetCapability(CapabilityType.Proxy, this.proxy);
Dictionary<string, object> proxyCapability = this.proxy.ToCapability();
if (proxyCapability != null)
{
capabilities.SetCapability(CapabilityType.Proxy, proxyCapability);
}
}

Dictionary<string, object> internetExplorerOptions = this.BuildInternetExplorerOptionsDictionary();
Expand Down
113 changes: 108 additions & 5 deletions dotnet/src/webdriver/Proxy.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="Proxy.cs" company="WebDriver Committers">
// <copyright file="Proxy.cs" company="WebDriver Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
Expand Down Expand Up @@ -79,6 +79,7 @@ public class Proxy
private string socksProxyLocation;
private string socksUserName;
private string socksPassword;
private List<string> noProxyAddresses = new List<string>();

/// <summary>
/// Initializes a new instance of the <see cref="Proxy"/> class.
Expand Down Expand Up @@ -250,19 +251,23 @@ public string HttpProxy
/// <summary>
/// Gets or sets the value for bypass proxy addresses.
/// </summary>
[Obsolete("Add addresses to bypass with the proxy by using the AddBypassAddress method.")]
[JsonProperty("noProxy", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)]
public string NoProxy
{
get
{
return this.noProxy;
if (this.noProxyAddresses.Count == 0)
{
return null;
}

return string.Join(";", this.noProxyAddresses);
}

set
{
this.VerifyProxyTypeCompatilibily(ProxyKind.Manual);
this.proxyKind = ProxyKind.Manual;
this.noProxy = value;
this.AddBypassAddress(value);
}
}

Expand Down Expand Up @@ -361,6 +366,104 @@ public string SocksPassword
}
}

/// <summary>
/// Adds a single address to the list of addresses against which the proxy will not be used.
/// </summary>
/// <param name="address">The address to add.</param>
public void AddBypassAddress(string address)
{
if (string.IsNullOrEmpty(address))
{
throw new ArgumentException("address must not be null or empty", "address");
}

this.AddBypassAddresses(address);
}

/// <summary>
/// Adds addresses to the list of addresses against which the proxy will not be used.
/// </summary>
/// <param name="addressesToAdd">An array of addresses to add.</param>
public void AddBypassAddresses(params string[] addressesToAdd)
{
this.AddBypassAddresses(new List<string>(addressesToAdd));
}

/// <summary>
/// Adds addresses to the list of addresses against which the proxy will not be used.
/// </summary>
/// <param name="addressesToAdd">An <see cref="IEnumerable{T}"/> object of arguments to add.</param>
public void AddBypassAddresses(IEnumerable<string> addressesToAdd)
{
if (addressesToAdd == null)
{
throw new ArgumentNullException("addressesToAdd", "addressesToAdd must not be null");
}

this.VerifyProxyTypeCompatilibily(ProxyKind.Manual);
this.proxyKind = ProxyKind.Manual;
this.noProxyAddresses.AddRange(addressesToAdd);
}

/// <summary>
/// Returns a dictionary suitable for serializing to the W3C Specification
/// dialect of the wire protocol.
/// </summary>
/// <returns>A dictionary suitable for serializing to the W3C Specification
/// dialect of the wire protocol.</returns>
internal Dictionary<string, object> ToCapability()
{
Dictionary<string, object> serializedDictionary = null;
if (this.proxyKind != ProxyKind.Unspecified)
{
serializedDictionary = new Dictionary<string, object>();
if (this.proxyKind == ProxyKind.ProxyAutoConfigure)
{
serializedDictionary["proxyType"] = "pac";
}
else
{
serializedDictionary["proxyType"] = this.proxyKind.ToString().ToLowerInvariant();
}

if (!string.IsNullOrEmpty(this.httpProxyLocation))
{
serializedDictionary["httpProxy"] = this.httpProxyLocation;
}

if (!string.IsNullOrEmpty(this.sslProxyLocation))
{
serializedDictionary["sslProxy"] = this.sslProxyLocation;
}

if (!string.IsNullOrEmpty(this.ftpProxyLocation))
{
serializedDictionary["ftpProxy"] = this.ftpProxyLocation;
}

if (!string.IsNullOrEmpty(this.socksProxyLocation))
{
string socksAuth = string.Empty;
if (!string.IsNullOrEmpty(this.socksUserName) && !string.IsNullOrEmpty(this.socksPassword))
{
// TODO: this is probably inaccurate as to how this is supposed
// to look.
socksAuth = this.socksUserName + ":" + this.socksPassword + "@";
}

serializedDictionary["socksProxy"] = socksAuth + this.socksProxyLocation;
}

if (this.noProxyAddresses.Count > 0)
{
List<object> addressList = new List<object>(this.noProxyAddresses);
serializedDictionary["noProxy"] = addressList;
}
}

return serializedDictionary;
}

private void VerifyProxyTypeCompatilibily(ProxyKind compatibleProxy)
{
if (this.proxyKind != ProxyKind.Unspecified && this.proxyKind != compatibleProxy)
Expand Down

0 comments on commit eead3f1

Please sign in to comment.