From 543b2f5e6a28325a0d66c7cbcbd86ec0ccabf90a Mon Sep 17 00:00:00 2001 From: Georgi Hristov Date: Fri, 29 May 2026 12:53:06 +0300 Subject: [PATCH] refactor: remove code duplication --- .../Handlers/DebugProbeHttpClientHandler.cs | 19 ++++++------------- .../Internal/Utils/HeaderUtils.cs | 16 ++++++++++++++++ .../Internal/Utils/HttpContentUtils.cs | 2 +- .../Middleware/DebugProbeMiddleware.cs | 17 ++++------------- .../Options/DebugProbeOptions.cs | 2 ++ 5 files changed, 29 insertions(+), 27 deletions(-) create mode 100644 DebugProbe.AspNetCore/Internal/Utils/HeaderUtils.cs diff --git a/DebugProbe.AspNetCore/Handlers/DebugProbeHttpClientHandler.cs b/DebugProbe.AspNetCore/Handlers/DebugProbeHttpClientHandler.cs index 2791d99..742d021 100644 --- a/DebugProbe.AspNetCore/Handlers/DebugProbeHttpClientHandler.cs +++ b/DebugProbe.AspNetCore/Handlers/DebugProbeHttpClientHandler.cs @@ -11,13 +11,6 @@ namespace DebugProbe.AspNetCore.Handlers; /// public class DebugProbeHttpClientHandler : DelegatingHandler { - private static readonly HashSet SensitiveHeaders = - [ - "Authorization", - "Cookie", - "Set-Cookie" - ]; - private readonly DebugProbeOptions _options; private readonly IHttpContextAccessor _httpContextAccessor; @@ -55,7 +48,7 @@ protected override async Task SendAsync(HttpRequestMessage /// /// Captures outgoing request details and stores them in the active DebugProbe entry. /// - private async Task CaptureRequest(HttpRequestMessage request, HttpResponseMessage? response, Exception? exception,long durationMs) + private async Task CaptureRequest(HttpRequestMessage request, HttpResponseMessage? response, Exception? exception, long durationMs) { var context = _httpContextAccessor.HttpContext; @@ -90,9 +83,9 @@ private async Task CaptureRequest(HttpRequestMessage request, HttpResponseMessag IsSuccessStatusCode = response?.IsSuccessStatusCode ?? false, - RequestHeaders = request.Headers.ToDictionary(x => x.Key, x => SensitiveHeaders.Contains(x.Key) ? "[REDACTED]" : string.Join(", ", x.Value)), + RequestHeaders = request.Headers.ToDictionary(x => x.Key, x => HeaderUtils.RedactIfSensitive(x.Key, string.Join(", ", x.Value))), - ResponseHeaders = response != null ? response.Headers.ToDictionary(x => x.Key, x => SensitiveHeaders.Contains(x.Key) ? "[REDACTED]" : string.Join(", ", x.Value)) : [] + ResponseHeaders = response != null ? response.Headers.ToDictionary(x => x.Key, x => HeaderUtils.RedactIfSensitive(x.Key, string.Join(", ", x.Value))) : [] }; if (request.Content != null) @@ -103,7 +96,7 @@ private async Task CaptureRequest(HttpRequestMessage request, HttpResponseMessag { var body = await request.Content.ReadAsStringAsync(); - outgoing.RequestBody = JsonUtils.Format(HttpContentUtils.Trim(body, _options.MaxBodyCaptureSizeKb * 1024)); + outgoing.RequestBody = JsonUtils.Format(HttpContentUtils.Trim(body, _options.MaxBodyCaptureSizeBytes)); } } @@ -115,10 +108,10 @@ private async Task CaptureRequest(HttpRequestMessage request, HttpResponseMessag { var body = await response.Content.ReadAsStringAsync(); - outgoing.ResponseBody = JsonUtils.Format(HttpContentUtils.Trim(body, _options.MaxBodyCaptureSizeKb * 1024)); + outgoing.ResponseBody = JsonUtils.Format(HttpContentUtils.Trim(body, _options.MaxBodyCaptureSizeBytes)); } } entry.OutgoingRequests.Add(outgoing); } -} \ No newline at end of file +} diff --git a/DebugProbe.AspNetCore/Internal/Utils/HeaderUtils.cs b/DebugProbe.AspNetCore/Internal/Utils/HeaderUtils.cs new file mode 100644 index 0000000..559f2d2 --- /dev/null +++ b/DebugProbe.AspNetCore/Internal/Utils/HeaderUtils.cs @@ -0,0 +1,16 @@ +namespace DebugProbe.AspNetCore.Internal.Utils; + +internal static class HeaderUtils +{ + private static readonly HashSet SensitiveHeaders = new(StringComparer.OrdinalIgnoreCase) + { + "Authorization", + "Cookie", + "Set-Cookie" + }; + + public static string RedactIfSensitive(string name, string value) + { + return SensitiveHeaders.Contains(name) ? "[REDACTED]" : value; + } +} diff --git a/DebugProbe.AspNetCore/Internal/Utils/HttpContentUtils.cs b/DebugProbe.AspNetCore/Internal/Utils/HttpContentUtils.cs index f120dda..02d9575 100644 --- a/DebugProbe.AspNetCore/Internal/Utils/HttpContentUtils.cs +++ b/DebugProbe.AspNetCore/Internal/Utils/HttpContentUtils.cs @@ -24,6 +24,6 @@ public static string Trim(string? value, int max = 2000) return value ?? string.Empty; } - return value.Length <= max? value : value.Substring(0, max); + return value.Length <= max ? value : value[..max]; } } diff --git a/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs b/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs index b261ebc..5cfe61a 100644 --- a/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs +++ b/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs @@ -36,13 +36,6 @@ public class DebugProbeMiddleware "/server-status" ]; - private static readonly HashSet SensitiveHeaders = new(StringComparer.OrdinalIgnoreCase) - { - "Authorization", - "Cookie", - "Set-Cookie" - }; - private readonly RequestDelegate _next; private readonly DebugProbeOptions _options; @@ -75,7 +68,7 @@ public async Task Invoke(HttpContext context, DebugEntryStore store) return; } - var maxBodySize = _options.MaxBodyCaptureSizeKb * 1024; + var maxBodySize = _options.MaxBodyCaptureSizeBytes; var requestBody = await CaptureRequestBodyAsync(context, maxBodySize); @@ -140,7 +133,7 @@ public async Task Invoke(HttpContext context, DebugEntryStore store) entry.RequestHeaders = context.Request.Headers.ToDictionary( x => x.Key, - x => SensitiveHeaders.Contains(x.Key) ? "[REDACTED]" : x.Value.ToString()); + x => HeaderUtils.RedactIfSensitive(x.Key, x.Value.ToString())); entry.RequestUrl = $"{context.Request.Scheme}://{context.Request.Host}" + @@ -150,10 +143,10 @@ public async Task Invoke(HttpContext context, DebugEntryStore store) entry.ResponseBody = HttpContentUtils.Trim(responseBody, maxBodySize); - entry.ResponseHeaders = + entry.ResponseHeaders = context.Response.Headers.ToDictionary( x => x.Key, - x => SensitiveHeaders.Contains(x.Key) ? "[REDACTED]" : x.Value.ToString()); + x => HeaderUtils.RedactIfSensitive(x.Key, x.Value.ToString())); store.Add(entry); } @@ -226,8 +219,6 @@ private static bool HasBody(HttpRequest request) string.Equals(request.Method, HttpMethods.Patch, StringComparison.OrdinalIgnoreCase); } - - private static async Task ReadAtMostAsync(Stream stream, int byteLimit) { using var buffer = new MemoryStream(); diff --git a/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs b/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs index ed7c46f..7c32817 100644 --- a/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs +++ b/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs @@ -15,6 +15,8 @@ public class DebugProbeOptions /// public int MaxBodyCaptureSizeKb { get; set; } = 32; + internal int MaxBodyCaptureSizeBytes => MaxBodyCaptureSizeKb * 1024; + /// /// Allows compare requests to local or private network targets. ///