diff --git a/DebugProbe.AspNetCore/Extensions/DebugProbeExtensions.cs b/DebugProbe.AspNetCore/Extensions/DebugProbeExtensions.cs index 229465a..549c4a4 100644 --- a/DebugProbe.AspNetCore/Extensions/DebugProbeExtensions.cs +++ b/DebugProbe.AspNetCore/Extensions/DebugProbeExtensions.cs @@ -1,4 +1,4 @@ -using System.Net.Http.Json; +using System.Net.Http.Json; using DebugProbe.AspNetCore.Handlers; using DebugProbe.AspNetCore.Internal.Compare; using DebugProbe.AspNetCore.Internal.Rendering; @@ -90,9 +90,11 @@ public static IApplicationBuilder UseDebugProbe(this IApplicationBuilder app, Ac if (app is WebApplication webApp) { + var prefix = options.RoutePrefix; + if (ShouldMapUiEndpoints(environment, options)) { - RequireDebugAuthorization(webApp.MapGet("/debug", async (HttpContext ctx, DebugEntryStore store) => + RequireDebugAuthorization(webApp.MapGet(prefix, async (HttpContext ctx, DebugEntryStore store) => { var items = store.GetAll() .OrderByDescending(x => x.Timestamp) @@ -105,7 +107,7 @@ public static IApplicationBuilder UseDebugProbe(this IApplicationBuilder app, Ac }).ExcludeFromDescription(), options); - RequireDebugAuthorization(webApp.MapGet("/debug/{id}", async (HttpContext ctx, string id, DebugEntryStore store) => + RequireDebugAuthorization(webApp.MapGet($"{prefix}/{{id}}", async (HttpContext ctx, string id, DebugEntryStore store) => { var item = store.Get(id); @@ -139,7 +141,7 @@ public static IApplicationBuilder UseDebugProbe(this IApplicationBuilder app, Ac }).ExcludeFromDescription(), options); - RequireDebugAuthorization(webApp.MapGet("/debug/js/{file}", (string file) => + RequireDebugAuthorization(webApp.MapGet($"{prefix}/js/{{file}}", (string file) => { if (!EmbeddedResources.JavaScript.TryGetValue(file, out var content)) { @@ -150,7 +152,7 @@ public static IApplicationBuilder UseDebugProbe(this IApplicationBuilder app, Ac }).ExcludeFromDescription(), options); - RequireDebugAuthorization(webApp.MapPost("/debug/clear", (DebugEntryStore store) => + RequireDebugAuthorization(webApp.MapPost($"{prefix}/clear", (DebugEntryStore store) => { store.Clear(); @@ -158,16 +160,16 @@ public static IApplicationBuilder UseDebugProbe(this IApplicationBuilder app, Ac }).ExcludeFromDescription(), options); - RequireDebugAuthorization(webApp.Map("/debug/logo.png", ctx => + RequireDebugAuthorization(webApp.Map($"{prefix}/logo.png", ctx => EmbeddedAssetWriter.WriteEmbeddedAsset(ctx, "DebugProbe.AspNetCore.Assets.images.debugprobe_logo_white_transparent.png", "image/png") ).ExcludeFromDescription(), options); - RequireDebugAuthorization(webApp.Map("/debug/favicon.ico", ctx => + RequireDebugAuthorization(webApp.Map($"{prefix}/favicon.ico", ctx => EmbeddedAssetWriter.WriteEmbeddedAsset(ctx, "DebugProbe.AspNetCore.Assets.images.debugprobe_favicon.ico", "image/x-icon") ).ExcludeFromDescription(), options); } - RequireDebugAuthorization(webApp.MapGet("/debug/compare/{id}", async (string id, string baseUrl, string remoteTraceId, + RequireDebugAuthorization(webApp.MapGet($"{prefix}/compare/{{id}}", async (string id, string baseUrl, string remoteTraceId, DebugEntryStore store, DebugProbeOptions options) => { @@ -191,9 +193,9 @@ public static IApplicationBuilder UseDebugProbe(this IApplicationBuilder app, Ac return Results.BadRequest(validation.Error); } - var remoteEnvironmentUrl = new Uri(validation.BaseUri!, "/debug/environment"); + var remoteEnvironmentUrl = new Uri(validation.BaseUri!, $"{prefix}/environment"); - var remoteEntryUrl = new Uri(validation.BaseUri!, $"/debug/json/{remoteTraceId}"); + var remoteEntryUrl = new Uri(validation.BaseUri!, $"{prefix}/json/{remoteTraceId}"); DebugEntry? remoteEntry; DebugEnvironment? remoteEnvironment; @@ -246,13 +248,13 @@ public static IApplicationBuilder UseDebugProbe(this IApplicationBuilder app, Ac }).ExcludeFromDescription(), options); - RequireDebugAuthorization(webApp.MapGet("/debug/environment", (DebugEntryStore store) => + RequireDebugAuthorization(webApp.MapGet($"{prefix}/environment", (DebugEntryStore store) => { return Results.Ok(store.Environment); }).ExcludeFromDescription(), options); - RequireDebugAuthorization(webApp.MapGet("/debug/json/{id}", (string id, DebugEntryStore store) => + RequireDebugAuthorization(webApp.MapGet($"{prefix}/json/{{id}}", (string id, DebugEntryStore store) => { var item = store.Get(id); diff --git a/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs b/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs index f405cee..13a131f 100644 --- a/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs +++ b/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs @@ -20,7 +20,6 @@ public class DebugProbeMiddleware private static readonly string[] DefaultIgnorePaths = [ - "/debug", "/compare", "/swagger", "/health", @@ -161,6 +160,7 @@ private bool IsIgnoredPath(PathString requestPath) return DefaultIgnorePaths .Concat(_options.IgnorePaths) + .Append(_options.RoutePrefix) .Distinct(StringComparer.OrdinalIgnoreCase) .Any(ignorePath => path.Equals(ignorePath, StringComparison.OrdinalIgnoreCase) || diff --git a/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs b/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs index d6d735e..1753935 100644 --- a/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs +++ b/DebugProbe.AspNetCore/Options/DebugProbeOptions.cs @@ -81,4 +81,17 @@ public int MaxBodyCaptureSizeKb /// Value used when sensitive data is redacted. /// public string RedactionText { get; set; } = "[REDACTED]"; + + /// + /// The route prefix for the DebugProbe dashboard and API endpoints. + /// Defaults to "/debug". A leading slash is added automatically if omitted. + /// + private string _routePrefix = "/debug"; + public string RoutePrefix + { + get => _routePrefix; + set => _routePrefix = string.IsNullOrWhiteSpace(value) + ? "/debug" + : "/" + value.TrimStart('/'); + } }