Skip to content

Commit 4c00c23

Browse files
[dotnet] Log http requests/responses via internal DiagnosticsHttpHandler (#13978)
* [dotnet] Add Execution Context * Added http status code validation * update validation http status code validation as int * Update http validation status code from 299 to 399 * Logs Response to HttpClientHandler * update name * revert http response message logger * Remove White Space * fix build error * Update InterceptAsync Summary * Update Logger field initialization * Remove logger parameter in ResponseLoggerInterceptor method * fix comment to add responseBody inside the if statement * Update Delegating Handler and Remove unable to push files in local * Update from null validation to status code * Fix comment * fix minor comments and adjust logic improvement * Revert "fix minor comments and adjust logic improvement" This reverts commit 4240536. * Null check for response content * Requests/Responses as single log message * Pass logger from upstream * Fix missing responses in log * Put log message in parallel with sending a request --------- Co-authored-by: Nikolay Borisenko <[email protected]>
1 parent cd96b62 commit 4c00c23

File tree

1 file changed

+60
-12
lines changed

1 file changed

+60
-12
lines changed

dotnet/src/webdriver/Remote/HttpCommandExecutor.cs

+60-12
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
using System;
2222
using System.Collections.Generic;
2323
using System.Globalization;
24-
using System.Linq;
2524
using System.Net;
2625
using System.Net.Http;
2726
using System.Net.Http.Headers;
2827
using System.Text;
28+
using System.Threading;
2929
using System.Threading.Tasks;
3030

3131
namespace OpenQA.Selenium.Remote
@@ -247,7 +247,14 @@ private void CreateHttpClient()
247247

248248
httpClientHandler.Proxy = this.Proxy;
249249

250-
this.client = new HttpClient(httpClientHandler);
250+
HttpMessageHandler handler = httpClientHandler;
251+
252+
if (_logger.IsEnabled(LogEventLevel.Trace))
253+
{
254+
handler = new DiagnosticsHttpHandler(httpClientHandler, _logger);
255+
}
256+
257+
this.client = new HttpClient(handler);
251258
this.client.DefaultRequestHeaders.UserAgent.ParseAdd(this.UserAgent);
252259
this.client.DefaultRequestHeaders.Accept.ParseAdd(RequestAcceptHeader);
253260
this.client.DefaultRequestHeaders.ExpectContinue = false;
@@ -293,18 +300,8 @@ private async Task<HttpResponseInfo> MakeHttpRequest(HttpRequestInfo requestInfo
293300
requestMessage.Content.Headers.ContentType = contentTypeHeader;
294301
}
295302

296-
if (_logger.IsEnabled(LogEventLevel.Trace))
297-
{
298-
_logger.Trace($">> {requestMessage}");
299-
}
300-
301303
using (HttpResponseMessage responseMessage = await this.client.SendAsync(requestMessage).ConfigureAwait(false))
302304
{
303-
if (_logger.IsEnabled(LogEventLevel.Trace))
304-
{
305-
_logger.Trace($"<< {responseMessage}");
306-
}
307-
308305
HttpResponseInfo httpResponseInfo = new HttpResponseInfo();
309306
httpResponseInfo.Body = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
310307
httpResponseInfo.ContentType = responseMessage.Content.Headers.ContentType?.ToString();
@@ -395,5 +392,56 @@ private class HttpResponseInfo
395392
public string Body { get; set; }
396393
public string ContentType { get; set; }
397394
}
395+
396+
/// <summary>
397+
/// Internal diagnostic handler to log http requests/responses.
398+
/// </summary>
399+
private class DiagnosticsHttpHandler : DelegatingHandler
400+
{
401+
private readonly ILogger _logger;
402+
403+
public DiagnosticsHttpHandler(HttpMessageHandler messageHandler, ILogger logger)
404+
: base(messageHandler)
405+
{
406+
_logger = logger;
407+
}
408+
409+
/// <summary>
410+
/// Sends the specified request and returns the associated response.
411+
/// </summary>
412+
/// <param name="request">The request to be sent.</param>
413+
/// <param name="cancellationToken">A CancellationToken object to allow for cancellation of the request.</param>
414+
/// <returns>The http response message content.</returns>
415+
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
416+
{
417+
StringBuilder requestLogMessageBuilder = new();
418+
requestLogMessageBuilder.AppendFormat(">> {0}", request);
419+
420+
if (request.Content != null)
421+
{
422+
var requestContent = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
423+
requestLogMessageBuilder.AppendFormat("{0}{1}", Environment.NewLine, requestContent);
424+
}
425+
426+
var responseTask = base.SendAsync(request, cancellationToken).ConfigureAwait(false);
427+
428+
_logger.Trace(requestLogMessageBuilder.ToString());
429+
430+
var response = await responseTask;
431+
432+
StringBuilder responseLogMessageBuilder = new();
433+
responseLogMessageBuilder.AppendFormat("<< {0}", response);
434+
435+
if (!response.IsSuccessStatusCode && response.Content != null)
436+
{
437+
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
438+
responseLogMessageBuilder.AppendFormat("{0}{1}", Environment.NewLine, responseContent);
439+
}
440+
441+
_logger.Trace(responseLogMessageBuilder.ToString());
442+
443+
return response;
444+
}
445+
}
398446
}
399447
}

0 commit comments

Comments
 (0)