Skip to content

Commit eead3f1

Browse files
committed
Updating serialization of Proxy for W3C-compliant drivers in .NET
Fixes issue #4574 for .NET.
1 parent 20ca315 commit eead3f1

File tree

4 files changed

+182
-39
lines changed

4 files changed

+182
-39
lines changed

dotnet/src/webdriver/Firefox/FirefoxOptions.cs

+25
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public class FirefoxOptions : DriverOptions
6262
private string browserBinaryLocation;
6363
private FirefoxDriverLogLevel logLevel = FirefoxDriverLogLevel.Default;
6464
private FirefoxProfile profile;
65+
private Proxy proxy;
6566
private List<string> firefoxArguments = new List<string>();
6667
private Dictionary<string, object> profilePreferences = new Dictionary<string, object>();
6768
private Dictionary<string, object> additionalCapabilities = new Dictionary<string, object>();
@@ -120,6 +121,15 @@ public string BrowserExecutableLocation
120121
set { this.browserBinaryLocation = value; }
121122
}
122123

124+
/// <summary>
125+
/// Gets or sets the <see cref="Proxy"/> to be used with Firefox.
126+
/// </summary>
127+
public Proxy Proxy
128+
{
129+
get { return this.proxy; }
130+
set { this.proxy = value; }
131+
}
132+
123133
/// <summary>
124134
/// Gets or sets the logging level of the Firefox driver.
125135
/// </summary>
@@ -270,6 +280,7 @@ public void AddAdditionalCapability(string capabilityName, object capabilityValu
270280
if (capabilityName == IsMarionetteCapability ||
271281
capabilityName == FirefoxProfileCapability ||
272282
capabilityName == FirefoxBinaryCapability ||
283+
capabilityName == CapabilityType.Proxy ||
273284
capabilityName == FirefoxLegacyProfileCapability ||
274285
capabilityName == FirefoxLegacyBinaryCapability ||
275286
capabilityName == FirefoxArgumentsCapability ||
@@ -307,6 +318,15 @@ public override ICapabilities ToCapabilities()
307318
DesiredCapabilities capabilities = DesiredCapabilities.Firefox();
308319
if (this.isMarionette)
309320
{
321+
if (this.proxy != null)
322+
{
323+
Dictionary<string, object> proxyCapabiity = this.proxy.ToCapability();
324+
if (proxyCapabiity != null)
325+
{
326+
capabilities.SetCapability(CapabilityType.Proxy, proxyCapabiity);
327+
}
328+
}
329+
310330
Dictionary<string, object> firefoxOptions = this.GenerateFirefoxOptionsDictionary();
311331
capabilities.SetCapability(FirefoxOptionsCapability, firefoxOptions);
312332
}
@@ -315,6 +335,11 @@ public override ICapabilities ToCapabilities()
315335
capabilities.SetCapability(IsMarionetteCapability, this.isMarionette);
316336
if (this.profile != null)
317337
{
338+
if (this.proxy != null)
339+
{
340+
this.profile.InternalSetProxyPreferences(this.proxy);
341+
}
342+
318343
capabilities.SetCapability(FirefoxProfileCapability, this.profile.ToBase64String());
319344
}
320345

dotnet/src/webdriver/Firefox/FirefoxProfile.cs

+43-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// <copyright file="FirefoxProfile.cs" company="WebDriver Committers">
1+
// <copyright file="FirefoxProfile.cs" company="WebDriver Committers">
22
// Licensed to the Software Freedom Conservancy (SFC) under one
33
// or more contributor license agreements. See the NOTICE file
44
// distributed with this work for additional information
@@ -241,39 +241,10 @@ public void SetPreference(string name, bool value)
241241
/// </summary>
242242
/// <param name="proxy">The <see cref="Proxy"/> object defining the proxy
243243
/// preferences for the profile.</param>
244+
[Obsolete("Use the FirefoxOptions class to set a proxy for Firefox.")]
244245
public void SetProxyPreferences(Proxy proxy)
245246
{
246-
if (proxy == null)
247-
{
248-
throw new ArgumentNullException("proxy", "proxy must not be null");
249-
}
250-
251-
if (proxy.Kind == ProxyKind.Unspecified)
252-
{
253-
return;
254-
}
255-
256-
this.SetPreference("network.proxy.type", (int)proxy.Kind);
257-
258-
switch (proxy.Kind)
259-
{
260-
case ProxyKind.Manual: // By default, assume we're proxying the lot
261-
this.SetPreference("network.proxy.no_proxies_on", string.Empty);
262-
263-
this.SetManualProxyPreference("ftp", proxy.FtpProxy);
264-
this.SetManualProxyPreference("http", proxy.HttpProxy);
265-
this.SetManualProxyPreference("ssl", proxy.SslProxy);
266-
this.SetManualProxyPreference("socks", proxy.SocksProxy);
267-
if (proxy.NoProxy != null)
268-
{
269-
this.SetPreference("network.proxy.no_proxies_on", proxy.NoProxy);
270-
}
271-
272-
break;
273-
case ProxyKind.ProxyAutoConfigure:
274-
this.SetPreference("network.proxy.autoconfig_url", proxy.ProxyAutoConfigUrl);
275-
break;
276-
}
247+
this.InternalSetProxyPreferences(proxy);
277248
}
278249

279250
/// <summary>
@@ -356,6 +327,46 @@ internal void AddWebDriverExtension()
356327
}
357328
}
358329

330+
/// <summary>
331+
/// Internal implementation to set proxy preferences for this profile.
332+
/// </summary>
333+
/// <param name="proxy">The <see cref="Proxy"/> object defining the proxy
334+
/// preferences for the profile.</param>
335+
internal void InternalSetProxyPreferences(Proxy proxy)
336+
{
337+
if (proxy == null)
338+
{
339+
throw new ArgumentNullException("proxy", "proxy must not be null");
340+
}
341+
342+
if (proxy.Kind == ProxyKind.Unspecified)
343+
{
344+
return;
345+
}
346+
347+
this.SetPreference("network.proxy.type", (int)proxy.Kind);
348+
349+
switch (proxy.Kind)
350+
{
351+
case ProxyKind.Manual: // By default, assume we're proxying the lot
352+
this.SetPreference("network.proxy.no_proxies_on", string.Empty);
353+
354+
this.SetManualProxyPreference("ftp", proxy.FtpProxy);
355+
this.SetManualProxyPreference("http", proxy.HttpProxy);
356+
this.SetManualProxyPreference("ssl", proxy.SslProxy);
357+
this.SetManualProxyPreference("socks", proxy.SocksProxy);
358+
if (proxy.NoProxy != null)
359+
{
360+
this.SetPreference("network.proxy.no_proxies_on", proxy.NoProxy);
361+
}
362+
363+
break;
364+
case ProxyKind.ProxyAutoConfigure:
365+
this.SetPreference("network.proxy.autoconfig_url", proxy.ProxyAutoConfigUrl);
366+
break;
367+
}
368+
}
369+
359370
/// <summary>
360371
/// Generates a random directory name for the profile.
361372
/// </summary>

dotnet/src/webdriver/IE/InternetExplorerOptions.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// <copyright file="InternetExplorerOptions.cs" company="WebDriver Committers">
1+
// <copyright file="InternetExplorerOptions.cs" company="WebDriver Committers">
22
// Licensed to the Software Freedom Conservancy (SFC) under one
33
// or more contributor license agreements. See the NOTICE file
44
// distributed with this work for additional information
@@ -484,7 +484,11 @@ public override ICapabilities ToCapabilities()
484484

485485
if (this.proxy != null)
486486
{
487-
capabilities.SetCapability(CapabilityType.Proxy, this.proxy);
487+
Dictionary<string, object> proxyCapability = this.proxy.ToCapability();
488+
if (proxyCapability != null)
489+
{
490+
capabilities.SetCapability(CapabilityType.Proxy, proxyCapability);
491+
}
488492
}
489493

490494
Dictionary<string, object> internetExplorerOptions = this.BuildInternetExplorerOptionsDictionary();

dotnet/src/webdriver/Proxy.cs

+108-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// <copyright file="Proxy.cs" company="WebDriver Committers">
1+
// <copyright file="Proxy.cs" company="WebDriver Committers">
22
// Licensed to the Software Freedom Conservancy (SFC) under one
33
// or more contributor license agreements. See the NOTICE file
44
// distributed with this work for additional information
@@ -79,6 +79,7 @@ public class Proxy
7979
private string socksProxyLocation;
8080
private string socksUserName;
8181
private string socksPassword;
82+
private List<string> noProxyAddresses = new List<string>();
8283

8384
/// <summary>
8485
/// Initializes a new instance of the <see cref="Proxy"/> class.
@@ -250,19 +251,23 @@ public string HttpProxy
250251
/// <summary>
251252
/// Gets or sets the value for bypass proxy addresses.
252253
/// </summary>
254+
[Obsolete("Add addresses to bypass with the proxy by using the AddBypassAddress method.")]
253255
[JsonProperty("noProxy", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)]
254256
public string NoProxy
255257
{
256258
get
257259
{
258-
return this.noProxy;
260+
if (this.noProxyAddresses.Count == 0)
261+
{
262+
return null;
263+
}
264+
265+
return string.Join(";", this.noProxyAddresses);
259266
}
260267

261268
set
262269
{
263-
this.VerifyProxyTypeCompatilibily(ProxyKind.Manual);
264-
this.proxyKind = ProxyKind.Manual;
265-
this.noProxy = value;
270+
this.AddBypassAddress(value);
266271
}
267272
}
268273

@@ -361,6 +366,104 @@ public string SocksPassword
361366
}
362367
}
363368

369+
/// <summary>
370+
/// Adds a single address to the list of addresses against which the proxy will not be used.
371+
/// </summary>
372+
/// <param name="address">The address to add.</param>
373+
public void AddBypassAddress(string address)
374+
{
375+
if (string.IsNullOrEmpty(address))
376+
{
377+
throw new ArgumentException("address must not be null or empty", "address");
378+
}
379+
380+
this.AddBypassAddresses(address);
381+
}
382+
383+
/// <summary>
384+
/// Adds addresses to the list of addresses against which the proxy will not be used.
385+
/// </summary>
386+
/// <param name="addressesToAdd">An array of addresses to add.</param>
387+
public void AddBypassAddresses(params string[] addressesToAdd)
388+
{
389+
this.AddBypassAddresses(new List<string>(addressesToAdd));
390+
}
391+
392+
/// <summary>
393+
/// Adds addresses to the list of addresses against which the proxy will not be used.
394+
/// </summary>
395+
/// <param name="addressesToAdd">An <see cref="IEnumerable{T}"/> object of arguments to add.</param>
396+
public void AddBypassAddresses(IEnumerable<string> addressesToAdd)
397+
{
398+
if (addressesToAdd == null)
399+
{
400+
throw new ArgumentNullException("addressesToAdd", "addressesToAdd must not be null");
401+
}
402+
403+
this.VerifyProxyTypeCompatilibily(ProxyKind.Manual);
404+
this.proxyKind = ProxyKind.Manual;
405+
this.noProxyAddresses.AddRange(addressesToAdd);
406+
}
407+
408+
/// <summary>
409+
/// Returns a dictionary suitable for serializing to the W3C Specification
410+
/// dialect of the wire protocol.
411+
/// </summary>
412+
/// <returns>A dictionary suitable for serializing to the W3C Specification
413+
/// dialect of the wire protocol.</returns>
414+
internal Dictionary<string, object> ToCapability()
415+
{
416+
Dictionary<string, object> serializedDictionary = null;
417+
if (this.proxyKind != ProxyKind.Unspecified)
418+
{
419+
serializedDictionary = new Dictionary<string, object>();
420+
if (this.proxyKind == ProxyKind.ProxyAutoConfigure)
421+
{
422+
serializedDictionary["proxyType"] = "pac";
423+
}
424+
else
425+
{
426+
serializedDictionary["proxyType"] = this.proxyKind.ToString().ToLowerInvariant();
427+
}
428+
429+
if (!string.IsNullOrEmpty(this.httpProxyLocation))
430+
{
431+
serializedDictionary["httpProxy"] = this.httpProxyLocation;
432+
}
433+
434+
if (!string.IsNullOrEmpty(this.sslProxyLocation))
435+
{
436+
serializedDictionary["sslProxy"] = this.sslProxyLocation;
437+
}
438+
439+
if (!string.IsNullOrEmpty(this.ftpProxyLocation))
440+
{
441+
serializedDictionary["ftpProxy"] = this.ftpProxyLocation;
442+
}
443+
444+
if (!string.IsNullOrEmpty(this.socksProxyLocation))
445+
{
446+
string socksAuth = string.Empty;
447+
if (!string.IsNullOrEmpty(this.socksUserName) && !string.IsNullOrEmpty(this.socksPassword))
448+
{
449+
// TODO: this is probably inaccurate as to how this is supposed
450+
// to look.
451+
socksAuth = this.socksUserName + ":" + this.socksPassword + "@";
452+
}
453+
454+
serializedDictionary["socksProxy"] = socksAuth + this.socksProxyLocation;
455+
}
456+
457+
if (this.noProxyAddresses.Count > 0)
458+
{
459+
List<object> addressList = new List<object>(this.noProxyAddresses);
460+
serializedDictionary["noProxy"] = addressList;
461+
}
462+
}
463+
464+
return serializedDictionary;
465+
}
466+
364467
private void VerifyProxyTypeCompatilibily(ProxyKind compatibleProxy)
365468
{
366469
if (this.proxyKind != ProxyKind.Unspecified && this.proxyKind != compatibleProxy)

0 commit comments

Comments
 (0)