From d2a3a82b950fe5d307685ff1e275c200bc057934 Mon Sep 17 00:00:00 2001 From: GHXX Date: Mon, 2 Jun 2025 17:23:35 +0200 Subject: [PATCH] Add option to ignore trailing slashes in requests --- SimpleHttpServer/HttpServer.cs | 9 +++++++-- SimpleHttpServer/SimpleHttpServerConfiguration.cs | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/SimpleHttpServer/HttpServer.cs b/SimpleHttpServer/HttpServer.cs index 2df5293..0ce3537 100644 --- a/SimpleHttpServer/HttpServer.cs +++ b/SimpleHttpServer/HttpServer.cs @@ -213,7 +213,7 @@ public sealed class HttpServer { private readonly Dictionary stringToTypeParameterConverters = new(); - private static string NormalizeUrlPath(string url) { + private string NormalizeUrlPath(string url) { var fwdSlashUrl = url.Replace('\\', '/'); var segments = fwdSlashUrl.Trim('/').Split('/', StringSplitOptions.RemoveEmptyEntries).ToList(); @@ -242,7 +242,12 @@ public sealed class HttpServer { } rv.AppendJoin('/', simplifiedSegmentsReversed.Reverse()); - return '/' + (rv.ToString().TrimEnd('/') + (fwdSlashUrl.EndsWith('/') ? "/" : "")).TrimStart('/'); + var suffix = (rv.ToString().TrimEnd('/') + (fwdSlashUrl.EndsWith('/') ? "/" : "")).TrimStart('/'); + if (conf.TrimTrailingSlash) { + suffix = suffix.TrimEnd('/'); + } + + return '/' + suffix; } private async Task ProcessRequestAsync(HttpListenerContext ctx) { diff --git a/SimpleHttpServer/SimpleHttpServerConfiguration.cs b/SimpleHttpServer/SimpleHttpServerConfiguration.cs index 64e4e63..5633aad 100644 --- a/SimpleHttpServer/SimpleHttpServerConfiguration.cs +++ b/SimpleHttpServer/SimpleHttpServerConfiguration.cs @@ -13,6 +13,10 @@ public class SimpleHttpServerConfiguration { /// See description of /// public CustomLogMessageHandler? LogMessageHandler { get; init; } = null; + /// + /// If set to true, paths ending with / are identical to paths without said trailing slash. E.g. /index is then the same as /index/ + /// + public bool TrimTrailingSlash { get; init; } = true; public SimpleHttpServerConfiguration() { }