From e83328841b229927c633df353a6f01c9e4e107db Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 24 Jan 2025 16:02:16 -0500 Subject: [PATCH 1/2] [dotnet] Serialize command parameters directly to UTF-8 --- dotnet/src/webdriver/Command.cs | 18 ++++++++++- .../webdriver/Remote/HttpCommandExecutor.cs | 6 ++-- .../SendingRemoteHttpRequestEventArgs.cs | 32 +++++++++++++++++-- dotnet/test/common/CommandTests.cs | 18 ++++++++++- 4 files changed, 67 insertions(+), 7 deletions(-) diff --git a/dotnet/src/webdriver/Command.cs b/dotnet/src/webdriver/Command.cs index 1559fe9690f5a..a3aaa8484c59d 100644 --- a/dotnet/src/webdriver/Command.cs +++ b/dotnet/src/webdriver/Command.cs @@ -101,13 +101,29 @@ public string ParametersAsJsonString } } + /// + /// Serializes the parameters of the comand to JSON as UTF-8 bytes. + /// + /// + public byte[] GetParametersAsUtf8Bytes() + { + if (this.Parameters != null && this.Parameters.Count > 0) + { + return JsonSerializer.SerializeToUtf8Bytes(this.Parameters, s_jsonSerializerOptions); + } + else + { + return "{}"u8.ToArray(); + } + } + /// /// Returns a string of the Command object /// /// A string representation of the Command Object public override string ToString() { - return string.Concat("[", this.SessionId, "]: ", this.Name, " ", this.ParametersAsJsonString); + return $"[{this.SessionId}]: {this.Name} Parameters: {this.ParametersAsJsonString}"; } /// diff --git a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs index 9ab474b8ec235..f1aa29981d8db 100644 --- a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs +++ b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs @@ -280,7 +280,7 @@ private async Task MakeHttpRequest(HttpRequestInfo requestInfo acceptHeader.CharSet = Utf8CharsetType; requestMessage.Headers.Accept.Add(acceptHeader); - byte[] bytes = Encoding.UTF8.GetBytes(requestInfo.RequestBody); + byte[] bytes = requestInfo.RequestBody; requestMessage.Content = new ByteArrayContent(bytes, 0, bytes.Length); MediaTypeHeaderValue contentTypeHeader = new MediaTypeHeaderValue(JsonMimeType); @@ -370,12 +370,12 @@ public HttpRequestInfo(Uri serverUri, Command commandToExecute, HttpCommandInfo this.FullUri = commandInfo.CreateCommandUri(serverUri, commandToExecute); this.HttpMethod = commandInfo.Method; - this.RequestBody = commandToExecute.ParametersAsJsonString; + this.RequestBody = commandToExecute.GetParametersAsUtf8Bytes(); } public Uri FullUri { get; set; } public string HttpMethod { get; set; } - public string RequestBody { get; set; } + public byte[] RequestBody { get; set; } } private class HttpResponseInfo diff --git a/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs b/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs index 34a92714e0b2d..cd5babebefc5c 100644 --- a/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs +++ b/dotnet/src/webdriver/Remote/SendingRemoteHttpRequestEventArgs.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; +using System.Text; #nullable enable @@ -29,6 +30,8 @@ namespace OpenQA.Selenium.Remote /// public class SendingRemoteHttpRequestEventArgs : EventArgs { + private string? _requestBody; + private readonly byte[]? _utf8RequestBody; private readonly Dictionary headers = new Dictionary(); /// @@ -42,7 +45,21 @@ public SendingRemoteHttpRequestEventArgs(string method, string fullUrl, string? { this.Method = method ?? throw new ArgumentNullException(nameof(method)); this.FullUrl = fullUrl ?? throw new ArgumentNullException(nameof(fullUrl)); - this.RequestBody = requestBody; + _utf8RequestBody = requestBody is null ? null : Encoding.UTF8.GetBytes(requestBody); + } + + /// + /// Initializes a new instance of the class. + /// + /// The HTTP method of the request being sent. + /// The full URL of the request being sent. + /// The body of the request. + /// If , are null. + public SendingRemoteHttpRequestEventArgs(string method, string fullUrl, byte[]? requestBody) + { + this.Method = method ?? throw new ArgumentNullException(nameof(method)); + this.FullUrl = fullUrl ?? throw new ArgumentNullException(nameof(fullUrl)); + _utf8RequestBody = requestBody; } /// @@ -58,7 +75,18 @@ public SendingRemoteHttpRequestEventArgs(string method, string fullUrl, string? /// /// Gets the body of the HTTP request as a string. /// - public string? RequestBody { get; } + public string? RequestBody + { + get + { + if (_requestBody is not null) + { + return _requestBody; + } + + return _requestBody = _utf8RequestBody is null ? null : Encoding.UTF8.GetString(_utf8RequestBody); + } + } /// /// Gets a read-only dictionary of the headers of the HTTP request. diff --git a/dotnet/test/common/CommandTests.cs b/dotnet/test/common/CommandTests.cs index f0480c034efd3..19da224503a9e 100644 --- a/dotnet/test/common/CommandTests.cs +++ b/dotnet/test/common/CommandTests.cs @@ -25,6 +25,22 @@ namespace OpenQA.Selenium [TestFixture] public class CommandTests { + [Test] + public void CommandSerializesNullParameters() + { + var command = new Command(new SessionId("session"), "test command", parameters: null); + + Assert.That(command.GetParametersAsUtf8Bytes(), Is.EqualTo("{}"u8.ToArray())); + } + + [Test] + public void CommandSerializesEmptyParameters() + { + var command = new Command(new SessionId("session"), "test command", parameters: new Dictionary()); + + Assert.That(command.GetParametersAsUtf8Bytes(), Is.EqualTo("{}"u8.ToArray())); + } + [Test] public void CommandSerializesAnonymousType() { @@ -35,7 +51,7 @@ public void CommandSerializesAnonymousType() var command = new Command(new SessionId("session"), "test command", parameters); - Assert.That(command.ParametersAsJsonString, Is.EqualTo("""{"arg":{"param1":true,"param2":false}}""")); + Assert.That(command.GetParametersAsUtf8Bytes(), Is.EqualTo("""{"arg":{"param1":true,"param2":false}}"""u8.ToArray())); } } } From f8624ecdee824950f6aa8cf5ebe54c7114162272 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 24 Jan 2025 16:10:59 -0500 Subject: [PATCH 2/2] revert unnecessary diff --- dotnet/src/webdriver/Command.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/webdriver/Command.cs b/dotnet/src/webdriver/Command.cs index a3aaa8484c59d..58d6e3070296b 100644 --- a/dotnet/src/webdriver/Command.cs +++ b/dotnet/src/webdriver/Command.cs @@ -123,7 +123,7 @@ public byte[] GetParametersAsUtf8Bytes() /// A string representation of the Command Object public override string ToString() { - return $"[{this.SessionId}]: {this.Name} Parameters: {this.ParametersAsJsonString}"; + return $"[{this.SessionId}]: {this.Name} {this.ParametersAsJsonString}"; } ///