using System.Net.Http.Headers; using System.Text; namespace NejCommon.Utils; public class HttpDebuggingHandler : DelegatingHandler { protected readonly ILogger Logger; public HttpDebuggingHandler(ILogger logger, HttpMessageHandler innerHandler = null) : base(innerHandler ?? new HttpClientHandler()) { Logger = logger; } async protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var req = request; var id = Guid.NewGuid().ToString(); var msg = $"[{id} - Request]"; StringBuilder output = new StringBuilder(); output.AppendLine($"{msg}========Start=========="); output.AppendLine($"{req.Method} {req.RequestUri.PathAndQuery} {req.RequestUri.Scheme}/{req.Version}"); output.AppendLine($"Host: {req.RequestUri.Scheme}://{req.RequestUri.Host}"); foreach (var header in req.Headers) output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); if (req.Content != null) { foreach (var header in req.Content.Headers) output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); if (req.Content is StringContent || IsTextBasedContentType(req.Headers) || this.IsTextBasedContentType(req.Content.Headers)) { var result = await req.Content.ReadAsStringAsync(); output.AppendLine($"Content:"); output.AppendLine($"{result}"); } } var start = DateTime.Now; var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); var end = DateTime.Now; output.AppendLine($"Duration: {end - start}"); output.AppendLine($"{msg}==========End=========="); Logger.LogInformation(output.ToString()); output.Clear(); msg = $"[{id} - Response]"; output.AppendLine($"{msg}=========Start========="); var resp = response; output.AppendLine( $"{req.RequestUri.Scheme.ToUpper()}/{resp.Version} {(int) resp.StatusCode} {resp.ReasonPhrase}"); foreach (var header in resp.Headers) output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); if (resp.Content != null) { foreach (var header in resp.Content.Headers) output.AppendLine($"{header.Key}: {string.Join(", ", header.Value)}"); if (resp.Content is StringContent || this.IsTextBasedContentType(resp.Headers) || this.IsTextBasedContentType(resp.Content.Headers)) { start = DateTime.Now; var result = await resp.Content.ReadAsStringAsync(); end = DateTime.Now; output.AppendLine($"Content:"); output.AppendLine($"{result}"); output.AppendLine($"Duration: {end - start}"); } } output.AppendLine($"{msg}==========End=========="); Logger.LogInformation(output.ToString()); return response; } readonly string[] types = new[] {"html", "text", "xml", "json", "txt", "x-www-form-urlencoded"}; bool IsTextBasedContentType(HttpHeaders headers) { IEnumerable values; if (!headers.TryGetValues("Content-Type", out values)) return false; var header = string.Join(" ", values).ToLowerInvariant(); return types.Any(t => header.Contains(t)); } }