dotnet / WatsonWebserver

Watson is the fastest, easiest way to build scalable RESTful web servers and services in C#.
MIT License
403 stars 83 forks source link

ContentRouteManager Match() fails to match individual files #76

Closed orinem closed 2 years ago

orinem commented 2 years ago

Match() adds a trailing '/' to all incoming paths. This fails to match a route for an individual file (which shouldn't end with a '/').

The simple solution is to only append a '/' if comparing against a route that is a directory, or as below, create a separate 'dirPath' variable with the trailing '/' to be used when comparing routes that are directories.

diff --git a/WatsonWebserver/ContentRouteManager.cs b/WatsonWebserver/ContentRouteManager.cs
index e36e22e..ddb21ec 100644
--- a/WatsonWebserver/ContentRouteManager.cs
+++ b/WatsonWebserver/ContentRouteManager.cs
@@ -164,7 +164,8 @@ namespace WatsonWebserver

             path = path.ToLower();
             if (!path.StartsWith("/")) path = "/" + path;
-            if (!path.EndsWith("/")) path = path + "/";
+            string dirPath = path;
+            if (!dirPath.EndsWith("/")) dirPath = dirPath + "/";

             lock (_Lock)
             {
@@ -172,7 +173,7 @@ namespace WatsonWebserver
                 {
                     if (curr.IsDirectory)
                     {
-                        if (path.StartsWith(curr.Path.ToLower()))
+                        if (dirPath.StartsWith(curr.Path.ToLower()))
                         {
                             route = curr;
                             return true;
jchristn commented 2 years ago

Thanks @orinem - excellent catch. I've also adjusted the constructor to ContentRoute as follows:


        /// <summary>
        /// Create a new route object.
        /// </summary> 
        /// <param name="path">The pattern against which the raw URL should be matched.</param>
        /// <param name="isDirectory">Indicates whether or not the path specifies a directory.  If so, any matching URL will be handled by the specified handler.</param> 
        /// <param name="guid">Globally-unique identifier.</param>
        /// <param name="metadata">User-supplied metadata.</param>
        public ContentRoute(string path, bool isDirectory, string guid = null, object metadata = null)
        {
            if (String.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));            
            Path = path.ToLower();
            IsDirectory = isDirectory;
            if (IsDirectory) if (!Path.EndsWith("/")) Path += "/";
            if (!String.IsNullOrEmpty(guid)) GUID = guid;
            if (metadata != null) Metadata = metadata;
        }

I will incorporate your fix using the dirPath variable. Will be in the next release. Thanks so much!

jchristn commented 2 years ago

NuGet: https://www.nuget.org/packages/Watson/4.2.2 Commit: https://github.com/jchristn/WatsonWebserver/commit/4273b5a29cad33f5f498437333f4cc3454a7abf4