# HG changeset patch # User Alain Mazy # Date 1751967687 -7200 # Node ID b8660d8ff4e79d29c1655a67c55b0c77bb530c7d # Parent a85ff09d94a075cbdb19904951e50c3a639a0668 fix WebDav URI encodings diff -r a85ff09d94a0 -r b8660d8ff4e7 OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp --- 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 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 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); diff -r a85ff09d94a0 -r b8660d8ff4e7 OrthancFramework/Sources/Toolbox.cpp --- 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& pathTokens) + { + std::vector uriEncodedPathTokens; + for (std::vector::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) { diff -r a85ff09d94a0 -r b8660d8ff4e7 OrthancFramework/Sources/Toolbox.h --- 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& pathTokens); + static std::string GetJsonStringField(const ::Json::Value& json, const std::string& key, const std::string& defaultValue);