From c66b1ea6bce7e09219512254b9f0b6bc31acf477 Mon Sep 17 00:00:00 2001 From: Jim Evans Date: Tue, 28 Sep 2021 19:04:17 -0400 Subject: [PATCH] [dotnet] Restore ability to add headers to WebDriver HTTP commands --- dotnet/src/webdriver/ICommandExecutor.cs | 7 +-- .../webdriver/Remote/HttpCommandExecutor.cs | 49 ++++++++++++++----- .../SendingRemoteHttpRequestEventArgs.cs | 36 ++++++++++++++ 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/dotnet/src/webdriver/ICommandExecutor.cs b/dotnet/src/webdriver/ICommandExecutor.cs index 85f969ee2c8e6..68cfe200391f4 100644 --- a/dotnet/src/webdriver/ICommandExecutor.cs +++ b/dotnet/src/webdriver/ICommandExecutor.cs @@ -26,10 +26,11 @@ namespace OpenQA.Selenium public interface ICommandExecutor : IDisposable { /// - /// Gets the repository of objects containin information about commands. + /// Attempts to add a command to the repository of commands known to this executor. /// - //CommandInfoRepository CommandInfoRepository { get; } - + /// The name of the command to attempt to add. + /// The describing the commnd to add. + /// if the new command has been added successfully; otherwise, . bool TryAddCommand(string commandName, CommandInfo info); /// diff --git a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs index f6617394c1b01..2a43bb0f283c2 100644 --- a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs +++ b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs @@ -17,6 +17,7 @@ // using System; +using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; @@ -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; @@ -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; @@ -89,15 +92,6 @@ public HttpCommandExecutor(Uri addressOfRemoteServer, TimeSpan timeout, bool ena /// public event EventHandler SendingRemoteHttpRequest; - /// - /// Gets the repository of objects containin information about commands. - /// - //public CommandInfoRepository CommandInfoRepository - //{ - // get { return this.commandInfoRepository; } - // protected set { this.commandInfoRepository = value; } - //} - /// /// Gets or sets an object to be used to proxy requests /// between this and the remote end WebDriver @@ -120,6 +114,32 @@ public bool IsKeepAliveEnabled set { this.enableKeepAlive = value; } } + /// + /// Gets or sets the user agent string used for HTTP communication + /// batween this and the remote end + /// WebDriver implementation + /// + public string UserAgent + { + get { return this.userAgent; } + set { this.userAgent = value; } + } + + /// + /// Gets the repository of objects containing information about commands. + /// + protected CommandInfoRepository CommandInfoRepository + { + get { return this.commandInfoRepository; } + set { this.commandInfoRepository = value; } + } + + /// + /// Attempts to add a command to the repository of commands known to this executor. + /// + /// The name of the command to attempt to add. + /// The describing the commnd to add. + /// if the new command has been added successfully; otherwise, . public bool TryAddCommand(string commandName, CommandInfo info) { HttpCommandInfo commandInfo = info as HttpCommandInfo; @@ -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) { @@ -254,6 +272,11 @@ private async Task MakeHttpRequest(HttpRequestInfo requestInfo HttpMethod method = new HttpMethod(requestInfo.HttpMethod); using (HttpRequestMessage requestMessage = new HttpRequestMessage(method, requestInfo.FullUri)) { + foreach (KeyValuePair header in eventArgs.Headers) + { + requestMessage.Headers.Add(header.Key, header.Value); + } + if (requestInfo.HttpMethod == HttpCommandInfo.GetCommand) { CacheControlHeaderValue cacheControlHeader = new CacheControlHeaderValue(); @@ -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); } diff --git a/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs b/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs index cff920e6bb114..83c0a2b1172b8 100644 --- a/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs +++ b/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs @@ -17,6 +17,7 @@ // using System; +using System.Collections.Generic; using System.Net; namespace OpenQA.Selenium.Remote @@ -29,6 +30,7 @@ public class SendingRemoteHttpRequestEventArgs : EventArgs private string method; private string fullUrl; private string requestBody; + private Dictionary headers = new Dictionary(); /// /// Initializes a new instance of the class. @@ -75,5 +77,39 @@ public string RequestBody { get { return this.requestBody; } } + + /// + /// Gets a read-only dictionary of the headers of the HTTP request. + /// Does not include default headers of the web client making the request. + /// + public IReadOnlyDictionary Headers + { + get { return this.headers; } + } + + /// + /// Adds a header to the HTTP request. + /// + /// The name of the header to add. + /// The value of the header to add. + /// + /// 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. + /// + 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; + } } }