changeset 2153:32bfccdc030f

consistency in the way URLs are concatenated
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 25 Sep 2024 18:09:24 +0200
parents 02a06434833c
children f8cbfd7175c3
files OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake OrthancStone/Sources/Loaders/DicomSource.cpp OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.cpp OrthancStone/Sources/Toolbox/OrthancDatasets/OrthancHttpConnection.cpp OrthancStone/Sources/Toolbox/StoneToolbox.cpp OrthancStone/Sources/Toolbox/StoneToolbox.h OrthancStone/UnitTestsSources/UnitTestsMain.cpp
diffstat 7 files changed, 117 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake	Sat Aug 31 08:37:39 2024 +0200
+++ b/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Sep 25 18:09:24 2024 +0200
@@ -439,6 +439,8 @@
   ${ORTHANC_STONE_ROOT}/Toolbox/SlicesSorter.h
   ${ORTHANC_STONE_ROOT}/Toolbox/SortedFrames.cpp
   ${ORTHANC_STONE_ROOT}/Toolbox/SortedFrames.h
+  ${ORTHANC_STONE_ROOT}/Toolbox/StoneToolbox.cpp
+  ${ORTHANC_STONE_ROOT}/Toolbox/StoneToolbox.h
   ${ORTHANC_STONE_ROOT}/Toolbox/SubpixelReader.h
   ${ORTHANC_STONE_ROOT}/Toolbox/SubvoxelReader.h
   ${ORTHANC_STONE_ROOT}/Toolbox/TextRenderer.cpp
--- a/OrthancStone/Sources/Loaders/DicomSource.cpp	Sat Aug 31 08:37:39 2024 +0200
+++ b/OrthancStone/Sources/Loaders/DicomSource.cpp	Wed Sep 25 18:09:24 2024 +0200
@@ -25,6 +25,7 @@
 
 #include "../Oracle/HttpCommand.h"
 #include "../Oracle/OrthancRestApiCommand.h"
+#include "../Toolbox/StoneToolbox.h"
 
 #include <OrthancException.h>
 #include <Toolbox.h>
@@ -60,39 +61,6 @@
   }
 
 
-  static std::string AddUriSuffix(const std::string& base,
-                                  const std::string& suffix)
-  {
-    if (base.empty())
-    {
-      return suffix;
-    }
-    else if (suffix.empty())
-    {
-      return base;
-    }
-    else
-    {
-      char lastBase = base[base.size() - 1];
-      
-      if (lastBase == '/' &&
-          suffix[0] == '/')
-      {
-        return base + suffix.substr(1);
-      }
-      else if (lastBase == '/' ||
-               suffix[0] == '/')
-      {
-        return base + suffix;
-      }
-      else
-      {
-        return base + "/" + suffix;
-      }
-    }
-  }
-
-
   void DicomSource::SetOrthancSource(const Orthanc::WebServiceParameters& parameters)
   {
     type_ = DicomSourceType_Orthanc;
@@ -229,7 +197,7 @@
         std::unique_ptr<HttpCommand> command(new HttpCommand);
         
         command->SetMethod(Orthanc::HttpMethod_Get);
-        command->SetUrl(AddUriSuffix(webService_.GetUrl(), uri + EncodeGetArguments(arguments)));
+        command->SetUrl(StoneToolbox::JoinUrl(webService_.GetUrl(), uri + EncodeGetArguments(arguments)));
         command->SetHttpHeaders(webService_.GetHttpHeaders());
 
         for (std::map<std::string, std::string>::const_iterator
@@ -274,7 +242,7 @@
 
         std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand);
         command->SetMethod(Orthanc::HttpMethod_Post);
-        command->SetUri(AddUriSuffix(orthancDicomWebRoot_, "/servers/" + serverName_ + "/get"));
+        command->SetUri(StoneToolbox::JoinUrl(orthancDicomWebRoot_, "/servers/" + serverName_ + "/get"));
         command->SetBody(body);
 
         if (protection.get())
--- a/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.cpp	Sat Aug 31 08:37:39 2024 +0200
+++ b/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.cpp	Wed Sep 25 18:09:24 2024 +0200
@@ -29,6 +29,8 @@
 #  include <Oracle/WebAssemblyOracle_Includes.h>
 #endif
 
+#include "../../Toolbox/StoneToolbox.h"
+
 #include <OrthancException.h>
 #include <Toolbox.h>
 
@@ -542,11 +544,11 @@
   {
     if (isLocalOrthanc_)
     {
-      command.SetUrl(localOrthancRoot_ + uri);
+      command.SetUrl(StoneToolbox::JoinUrl(localOrthancRoot_, uri));
     }
     else
     {
-      command.SetUrl(remoteOrthanc_.GetUrl() + uri);
+      command.SetUrl(StoneToolbox::JoinUrl(remoteOrthanc_.GetUrl(), uri));
       command.AddHttpHeaders(remoteOrthanc_.GetHttpHeaders());
       
       if (!remoteOrthanc_.GetUsername().empty())
--- a/OrthancStone/Sources/Toolbox/OrthancDatasets/OrthancHttpConnection.cpp	Sat Aug 31 08:37:39 2024 +0200
+++ b/OrthancStone/Sources/Toolbox/OrthancDatasets/OrthancHttpConnection.cpp	Wed Sep 25 18:09:24 2024 +0200
@@ -23,6 +23,8 @@
 
 #include "OrthancHttpConnection.h"
 
+#include "../StoneToolbox.h"
+
 namespace OrthancStone
 {
   void OrthancHttpConnection::Setup()
@@ -54,7 +56,7 @@
     boost::mutex::scoped_lock lock(mutex_);
 
     client_.SetMethod(Orthanc::HttpMethod_Get);
-    client_.SetUrl(url_ + uri);
+    client_.SetUrl(StoneToolbox::JoinUrl(url_, uri));
     client_.ApplyAndThrowException(result);
   }
 
@@ -66,7 +68,7 @@
     boost::mutex::scoped_lock lock(mutex_);
 
     client_.SetMethod(Orthanc::HttpMethod_Post);
-    client_.SetUrl(url_ + uri);
+    client_.SetUrl(StoneToolbox::JoinUrl(url_, uri));
 
 #if defined(ORTHANC_FRAMEWORK_VERSION_IS_ABOVE) && ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 9, 3)
     client_.SetExternalBody(body);
@@ -86,7 +88,7 @@
     boost::mutex::scoped_lock lock(mutex_);
 
     client_.SetMethod(Orthanc::HttpMethod_Put);
-    client_.SetUrl(url_ + uri);
+    client_.SetUrl(StoneToolbox::JoinUrl(url_, uri));
 
 #if defined(ORTHANC_FRAMEWORK_VERSION_IS_ABOVE) && ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 9, 3)
     client_.SetExternalBody(body);
@@ -106,7 +108,7 @@
     std::string result;
 
     client_.SetMethod(Orthanc::HttpMethod_Delete);
-    client_.SetUrl(url_ + uri);
+    client_.SetUrl(StoneToolbox::JoinUrl(url_, uri));
     client_.ApplyAndThrowException(result);
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancStone/Sources/Toolbox/StoneToolbox.cpp	Wed Sep 25 18:09:24 2024 +0200
@@ -0,0 +1,50 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "StoneToolbox.h"
+
+namespace OrthancStone
+{
+  namespace StoneToolbox
+  {
+    std::string JoinUrl(const std::string& base,
+                        const std::string& path)
+    {
+      size_t end = base.size();
+      while (end > 0 &&
+             base[end - 1] == '/')
+      {
+        end--;
+      }
+
+      size_t start = 0;
+      while (start < path.size() &&
+             path[start] == '/')
+      {
+        start++;
+      }
+
+      return base.substr(0, end) + "/" + path.substr(start);
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancStone/Sources/Toolbox/StoneToolbox.h	Wed Sep 25 18:09:24 2024 +0200
@@ -0,0 +1,35 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include <string>
+
+namespace OrthancStone
+{
+  namespace StoneToolbox
+  {
+    std::string JoinUrl(const std::string& base,
+                        const std::string& path);
+  }
+}
--- a/OrthancStone/UnitTestsSources/UnitTestsMain.cpp	Sat Aug 31 08:37:39 2024 +0200
+++ b/OrthancStone/UnitTestsSources/UnitTestsMain.cpp	Wed Sep 25 18:09:24 2024 +0200
@@ -25,6 +25,7 @@
 
 #include "../Sources/StoneEnumerations.h"
 #include "../Sources/StoneInitialization.h"
+#include "../Sources/Toolbox/StoneToolbox.h"
 
 #include <Logging.h>
 
@@ -58,6 +59,22 @@
 }
 
 
+TEST(StoneToolbox, JoinUrl)
+{
+  ASSERT_EQ("/", OrthancStone::StoneToolbox::JoinUrl("", ""));
+  ASSERT_EQ("/", OrthancStone::StoneToolbox::JoinUrl("", "/"));
+  ASSERT_EQ("/", OrthancStone::StoneToolbox::JoinUrl("", "//"));
+  ASSERT_EQ("/", OrthancStone::StoneToolbox::JoinUrl("/", ""));
+  ASSERT_EQ("/", OrthancStone::StoneToolbox::JoinUrl("//", ""));
+  ASSERT_EQ("/", OrthancStone::StoneToolbox::JoinUrl("////", "/////"));
+  ASSERT_EQ("a/b/d/e/", OrthancStone::StoneToolbox::JoinUrl("a/b", "d/e/"));
+  ASSERT_EQ("a/b/d/e/", OrthancStone::StoneToolbox::JoinUrl("a/b", "/d/e/"));
+  ASSERT_EQ("a/b/d/e/", OrthancStone::StoneToolbox::JoinUrl("a/b/", "d/e/"));
+  ASSERT_EQ("a/b/d/e/", OrthancStone::StoneToolbox::JoinUrl("a/b/", "/d/e/"));
+  ASSERT_EQ("a/b/d/e/", OrthancStone::StoneToolbox::JoinUrl("a/b///", "///d/e/"));
+}
+
+
 int main(int argc, char **argv)
 {
 #if defined(__EMSCRIPTEN__)