Skip to content

Commit

Permalink
[dotnet] Restore ability to add headers to WebDriver HTTP commands
Browse files Browse the repository at this point in the history
  • Loading branch information
jimevans committed Sep 28, 2021
1 parent d2636d7 commit c66b1ea
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 16 deletions.
7 changes: 4 additions & 3 deletions dotnet/src/webdriver/ICommandExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ namespace OpenQA.Selenium
public interface ICommandExecutor : IDisposable
{
/// <summary>
/// Gets the repository of objects containin information about commands.
/// Attempts to add a command to the repository of commands known to this executor.
/// </summary>
//CommandInfoRepository CommandInfoRepository { get; }

/// <param name="commandName">The name of the command to attempt to add.</param>
/// <param name="info">The <see cref="CommandInfo"/> describing the commnd to add.</param>
/// <returns><see langword="true"/> if the new command has been added successfully; otherwise, <see langword="false"/>.</returns>
bool TryAddCommand(string commandName, CommandInfo info);

/// <summary>
Expand Down
49 changes: 36 additions & 13 deletions dotnet/src/webdriver/Remote/HttpCommandExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// </copyright>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
Expand All @@ -43,6 +44,7 @@ public class HttpCommandExecutor : ICommandExecutor
private const string UserAgentHeaderTemplate = "selenium/{0} (.net {1})";
private Uri remoteServerUri;
private TimeSpan serverResponseTimeout;
private string userAgent;
private bool enableKeepAlive;
private bool isDisposed;
private IWebProxy proxy;
Expand Down Expand Up @@ -78,6 +80,7 @@ public HttpCommandExecutor(Uri addressOfRemoteServer, TimeSpan timeout, bool ena
addressOfRemoteServer = new Uri(addressOfRemoteServer.ToString() + "/");
}

this.userAgent = string.Format(CultureInfo.InvariantCulture, UserAgentHeaderTemplate, ResourceUtilities.AssemblyVersion, ResourceUtilities.PlatformFamily);
this.remoteServerUri = addressOfRemoteServer;
this.serverResponseTimeout = timeout;
this.enableKeepAlive = enableKeepAlive;
Expand All @@ -89,15 +92,6 @@ public HttpCommandExecutor(Uri addressOfRemoteServer, TimeSpan timeout, bool ena
/// </summary>
public event EventHandler<SendingRemoteHttpRequestEventArgs> SendingRemoteHttpRequest;

/// <summary>
/// Gets the repository of objects containin information about commands.
/// </summary>
//public CommandInfoRepository CommandInfoRepository
//{
// get { return this.commandInfoRepository; }
// protected set { this.commandInfoRepository = value; }
//}

/// <summary>
/// Gets or sets an <see cref="IWebProxy"/> object to be used to proxy requests
/// between this <see cref="HttpCommandExecutor"/> and the remote end WebDriver
Expand All @@ -120,6 +114,32 @@ public bool IsKeepAliveEnabled
set { this.enableKeepAlive = value; }
}

/// <summary>
/// Gets or sets the user agent string used for HTTP communication
/// batween this <see cref="HttpCommandExecutor"/> and the remote end
/// WebDriver implementation
/// </summary>
public string UserAgent
{
get { return this.userAgent; }
set { this.userAgent = value; }
}

/// <summary>
/// Gets the repository of objects containing information about commands.
/// </summary>
protected CommandInfoRepository CommandInfoRepository
{
get { return this.commandInfoRepository; }
set { this.commandInfoRepository = value; }
}

/// <summary>
/// Attempts to add a command to the repository of commands known to this executor.
/// </summary>
/// <param name="commandName">The name of the command to attempt to add.</param>
/// <param name="info">The <see cref="CommandInfo"/> describing the commnd to add.</param>
/// <returns><see langword="true"/> if the new command has been added successfully; otherwise, <see langword="false"/>.</returns>
public bool TryAddCommand(string commandName, CommandInfo info)
{
HttpCommandInfo commandInfo = info as HttpCommandInfo;
Expand Down Expand Up @@ -234,9 +254,7 @@ private void CreateHttpClient()
httpClientHandler.Proxy = this.Proxy;

this.client = new HttpClient(httpClientHandler);
string userAgentString = string.Format(CultureInfo.InvariantCulture, UserAgentHeaderTemplate, ResourceUtilities.AssemblyVersion, ResourceUtilities.PlatformFamily);
this.client.DefaultRequestHeaders.UserAgent.ParseAdd(userAgentString);

this.client.DefaultRequestHeaders.UserAgent.ParseAdd(this.UserAgent);
this.client.DefaultRequestHeaders.Accept.ParseAdd(RequestAcceptHeader);
if (!this.IsKeepAliveEnabled)
{
Expand All @@ -254,6 +272,11 @@ private async Task<HttpResponseInfo> MakeHttpRequest(HttpRequestInfo requestInfo
HttpMethod method = new HttpMethod(requestInfo.HttpMethod);
using (HttpRequestMessage requestMessage = new HttpRequestMessage(method, requestInfo.FullUri))
{
foreach (KeyValuePair<string, string> header in eventArgs.Headers)
{
requestMessage.Headers.Add(header.Key, header.Value);
}

if (requestInfo.HttpMethod == HttpCommandInfo.GetCommand)
{
CacheControlHeaderValue cacheControlHeader = new CacheControlHeaderValue();
Expand Down Expand Up @@ -291,7 +314,7 @@ private Response CreateResponse(HttpResponseInfo responseInfo)
{
Response response = new Response();
string body = responseInfo.Body;
if (responseInfo.ContentType != null && responseInfo.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
if (responseInfo.ContentType != null && responseInfo.ContentType.StartsWith(JsonMimeType, StringComparison.OrdinalIgnoreCase))
{
response = Response.FromJson(body);
}
Expand Down
36 changes: 36 additions & 0 deletions dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// </copyright>

using System;
using System.Collections.Generic;
using System.Net;

namespace OpenQA.Selenium.Remote
Expand All @@ -29,6 +30,7 @@ public class SendingRemoteHttpRequestEventArgs : EventArgs
private string method;
private string fullUrl;
private string requestBody;
private Dictionary<string, string> headers = new Dictionary<string, string>();

/// <summary>
/// Initializes a new instance of the <see cref="SendingRemoteHttpRequestEventArgs"/> class.
Expand Down Expand Up @@ -75,5 +77,39 @@ public string RequestBody
{
get { return this.requestBody; }
}

/// <summary>
/// Gets a read-only dictionary of the headers of the HTTP request.
/// Does not include default headers of the web client making the request.
/// </summary>
public IReadOnlyDictionary<string, string> Headers
{
get { return this.headers; }
}

/// <summary>
/// Adds a header to the HTTP request.
/// </summary>
/// <param name="headerName">The name of the header to add.</param>
/// <param name="headerValue">The value of the header to add.</param>
/// <remarks>
/// Adding headers here will attempt to add them to the headers for the
/// HTTP request being sent; however, be aware they may be overwritten by
/// the client raising the event.
/// </remarks>
public void AddHeader(string headerName, string headerValue)
{
if (string.IsNullOrEmpty(headerName))
{
throw new ArgumentException("Header name may not be null or the empty string.", "headerName");
}

if (headerValue == null)
{
throw new ArgumentNullException("headerValue", "Header value may not be null.")
}

this.headers[headerName] = headerValue;
}
}
}

0 comments on commit c66b1ea

Please sign in to comment.