|
21 | 21 | using System;
|
22 | 22 | using System.Collections.Generic;
|
23 | 23 | using System.Globalization;
|
24 |
| -using System.Linq; |
25 | 24 | using System.Net;
|
26 | 25 | using System.Net.Http;
|
27 | 26 | using System.Net.Http.Headers;
|
28 | 27 | using System.Text;
|
| 28 | +using System.Threading; |
29 | 29 | using System.Threading.Tasks;
|
30 | 30 |
|
31 | 31 | namespace OpenQA.Selenium.Remote
|
@@ -247,7 +247,14 @@ private void CreateHttpClient()
|
247 | 247 |
|
248 | 248 | httpClientHandler.Proxy = this.Proxy;
|
249 | 249 |
|
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); |
251 | 258 | this.client.DefaultRequestHeaders.UserAgent.ParseAdd(this.UserAgent);
|
252 | 259 | this.client.DefaultRequestHeaders.Accept.ParseAdd(RequestAcceptHeader);
|
253 | 260 | this.client.DefaultRequestHeaders.ExpectContinue = false;
|
@@ -293,18 +300,8 @@ private async Task<HttpResponseInfo> MakeHttpRequest(HttpRequestInfo requestInfo
|
293 | 300 | requestMessage.Content.Headers.ContentType = contentTypeHeader;
|
294 | 301 | }
|
295 | 302 |
|
296 |
| - if (_logger.IsEnabled(LogEventLevel.Trace)) |
297 |
| - { |
298 |
| - _logger.Trace($">> {requestMessage}"); |
299 |
| - } |
300 |
| - |
301 | 303 | using (HttpResponseMessage responseMessage = await this.client.SendAsync(requestMessage).ConfigureAwait(false))
|
302 | 304 | {
|
303 |
| - if (_logger.IsEnabled(LogEventLevel.Trace)) |
304 |
| - { |
305 |
| - _logger.Trace($"<< {responseMessage}"); |
306 |
| - } |
307 |
| - |
308 | 305 | HttpResponseInfo httpResponseInfo = new HttpResponseInfo();
|
309 | 306 | httpResponseInfo.Body = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
|
310 | 307 | httpResponseInfo.ContentType = responseMessage.Content.Headers.ContentType?.ToString();
|
@@ -395,5 +392,56 @@ private class HttpResponseInfo
|
395 | 392 | public string Body { get; set; }
|
396 | 393 | public string ContentType { get; set; }
|
397 | 394 | }
|
| 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 | + } |
398 | 446 | }
|
399 | 447 | }
|
0 commit comments