103 lines
3.8 KiB
C#
103 lines
3.8 KiB
C#
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<HttpResponseMessage> 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<string> values;
|
|
if (!headers.TryGetValues("Content-Type", out values))
|
|
return false;
|
|
var header = string.Join(" ", values).ToLowerInvariant();
|
|
|
|
return types.Any(t => header.Contains(t));
|
|
}
|
|
} |