changeset 6230:b8660d8ff4e7

fix WebDav URI encodings
author Alain Mazy <am@orthanc.team>
date Tue, 08 Jul 2025 11:41:27 +0200
parents a85ff09d94a0
children c13cc738bceb
files OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp OrthancFramework/Sources/Toolbox.cpp OrthancFramework/Sources/Toolbox.h
diffstat 3 files changed, 51 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp	Tue Jul 08 07:44:09 2025 +0200
+++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp	Tue Jul 08 11:41:27 2025 +0200
@@ -48,7 +48,20 @@
     return s;
   }
 }
-  
+
+static std::string AddLeadingSlash(const std::string& s)
+{
+  if (s.empty() ||
+      s[0] != '/')
+  {
+    return std::string("/") + s;
+  }
+  else
+  {
+    return s;
+  }
+}
+
 
 namespace Orthanc
 {
@@ -163,7 +176,14 @@
                                    const std::string& parentPath) const
   {
     std::string href;
-    Toolbox::UriEncode(href, AddTrailingSlash(parentPath) + GetDisplayName());
+    std::vector<std::string> pathTokens;
+
+    Toolbox::SplitString(pathTokens, parentPath, '/');
+    pathTokens.push_back(GetDisplayName());
+
+    Toolbox::UriEncode(href, pathTokens);
+    href = AddLeadingSlash(href);
+
     FormatInternal(node, href, GetDisplayName(), GetCreationTime(), GetModificationTime());
 
     pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop");
@@ -181,7 +201,14 @@
                                      const std::string& parentPath) const
   {
     std::string href;
-    Toolbox::UriEncode(href, AddTrailingSlash(parentPath) + GetDisplayName());
+    std::vector<std::string> pathTokens;
+
+    Toolbox::SplitString(pathTokens, parentPath, '/');
+    pathTokens.push_back(GetDisplayName());
+
+    Toolbox::UriEncode(href, pathTokens);
+    href = AddLeadingSlash(href);
+
     FormatInternal(node, href, GetDisplayName(), GetCreationTime(), GetModificationTime());
         
     pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop");
@@ -245,7 +272,8 @@
       }
        
       std::string href;
-      Toolbox::UriEncode(href, Toolbox::FlattenUri(tokens) + "/");
+      Toolbox::UriEncode(href, tokens);
+      href = AddTrailingSlash(AddLeadingSlash(href));
 
       boost::posix_time::ptime now = GetNow();
       FormatInternal(self, href, folder, now, now);
--- a/OrthancFramework/Sources/Toolbox.cpp	Tue Jul 08 07:44:09 2025 +0200
+++ b/OrthancFramework/Sources/Toolbox.cpp	Tue Jul 08 11:41:27 2025 +0200
@@ -1485,6 +1485,22 @@
             c == '~');
   }
 
+  // in this version, each path token is uri encoded separately and then all parts are joined with "/"
+  void Toolbox::UriEncode(std::string& target,
+                          const std::vector<std::string>& pathTokens)
+  {
+    std::vector<std::string> uriEncodedPathTokens;
+    for (std::vector<std::string>::const_iterator it = pathTokens.begin(); it != pathTokens.end(); ++it)
+    {
+      std::string encodedPathToken;
+      Toolbox::UriEncode(encodedPathToken, *it);
+      uriEncodedPathTokens.push_back(encodedPathToken);
+    }
+
+    Toolbox::JoinStrings(target, uriEncodedPathTokens, "/");
+  }
+
+
   void Toolbox::UriEncode(std::string& target,
                           const std::string& source)
   {
--- a/OrthancFramework/Sources/Toolbox.h	Tue Jul 08 07:44:09 2025 +0200
+++ b/OrthancFramework/Sources/Toolbox.h	Tue Jul 08 11:41:27 2025 +0200
@@ -320,6 +320,9 @@
     static void UriEncode(std::string& target,
                           const std::string& source);
 
+    static void UriEncode(std::string& target,
+                          const std::vector<std::string>& pathTokens);
+
     static std::string GetJsonStringField(const ::Json::Value& json,
                                           const std::string& key,
                                           const std::string& defaultValue);