diff --git a/src/Unosquare.Labs.EmbedIO/Core/VirtualPath.cs b/src/Unosquare.Labs.EmbedIO/Core/VirtualPath.cs index bad12b0b9..ef0e3459c 100644 --- a/src/Unosquare.Labs.EmbedIO/Core/VirtualPath.cs +++ b/src/Unosquare.Labs.EmbedIO/Core/VirtualPath.cs @@ -24,7 +24,14 @@ public VirtualPath(string baseUrlPath, string baseLocalPath) public string BaseLocalPath { get; } - internal bool CanMapUrlPath(string urlPath) => urlPath.StartsWith(BaseUrlPath, StringComparison.Ordinal); + // Base paths are forced to end with a slash, + // while requested paths are forced to NOT end with a slash. + // Virtual path "/media/" can map "/media/file.jpg" + // but it can also map "/media" (without the slash). + + internal bool CanMapUrlPath(string urlPath) + => urlPath.StartsWith(BaseUrlPath, StringComparison.Ordinal) + || (urlPath.Length == BaseUrlPath.Length - 1 && BaseUrlPath.StartsWith(urlPath, StringComparison.Ordinal)); internal bool TryMapUrlPathLoLocalPath(string urlPath, out string localPath) { @@ -34,7 +41,11 @@ internal bool TryMapUrlPathLoLocalPath(string urlPath, out string localPath) return false; } - var relativeUrlPath = urlPath.Substring(BaseUrlPath.Length); + // The only case where CanMapUrlPath returns true for a path shorter than BaseUrlPath + // is urlPath == (BaseUrlPath minus the final slash). + var relativeUrlPath = urlPath.Length < BaseUrlPath.Length + ? string.Empty + : urlPath.Substring(BaseUrlPath.Length); localPath = Path.Combine(BaseLocalPath, relativeUrlPath.Replace('/', Path.DirectorySeparatorChar)); return true; }