changeset 3409:877363a40647

merge
author s.jodogne@gmail.com
date Sat, 08 Jun 2019 16:49:35 +0200
parents 1787ad594063 (current diff) b7728227a852 (diff)
children 3575466a3e57
files
diffstat 4 files changed, 174 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Engine/OrthancPlugins.cpp	Sat Jun 08 16:49:10 2019 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Sat Jun 08 16:49:35 2019 +0200
@@ -4231,8 +4231,8 @@
             throw OrthancException(ErrorCode_ParameterOutOfRange);
         }
 
-        std::string multipartContentType;
-        if (!MultipartStreamReader::GetMainContentType(multipartContentType, headers))
+        std::string mainContentType;
+        if (!MultipartStreamReader::GetMainContentType(mainContentType, headers))
         {
           LOG(INFO) << "Missing Content-Type HTTP header, prevents streaming the body";
           continue;
@@ -4240,10 +4240,10 @@
 
         std::string contentType, subType, boundary;
         if (!MultipartStreamReader::ParseMultipartContentType
-            (contentType, subType, boundary, multipartContentType))
+            (contentType, subType, boundary, mainContentType))
         {
           LOG(INFO) << "Invalid Content-Type HTTP header, "
-                    << "prevents streaming the body: \"" << multipartContentType << "\"";
+                    << "prevents streaming the body: \"" << mainContentType << "\"";
           continue;
         }
 
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Sat Jun 08 16:49:10 2019 +0200
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Sat Jun 08 16:49:35 2019 +0200
@@ -33,6 +33,17 @@
 
 #include "OrthancPluginCppWrapper.h"
 
+#if HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER == 0
+#  if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 5, 7)
+#    define HAS_ORTHANC_FRAMEWORK_MULTIPART_READER 1
+#    include "../../../Core/HttpServer/MultipartStreamReader.h"
+#    include <boost/thread/shared_mutex.hpp>
+#  else
+#    define HAS_ORTHANC_FRAMEWORK_MULTIPART_READER 0
+#  endif
+#endif
+
+
 #include <boost/algorithm/string/predicate.hpp>
 #include <json/reader.h>
 #include <json/writer.h>
@@ -2744,6 +2755,144 @@
       reinterpret_cast<OrthancPluginMultipartRestFactory*>(this), 
       MultipartRestFactory, MultipartRestAddPart, MultipartRestExecute, MultipartRestFinalize);
   }
+
+#elif HAS_ORTHANC_FRAMEWORK_MULTIPART_READER == 1
+
+  namespace
+  {
+    class CompatibilityPartHandler : public Orthanc::MultipartStreamReader::IHandler
+    {
+    private:
+      MultipartRestCallback::IHandler&  handler_;
+
+    public:
+      CompatibilityPartHandler(MultipartRestCallback::IHandler& handler) :
+        handler_(handler)
+      {
+      }
+
+      virtual void HandlePart(const Orthanc::MultipartStreamReader::HttpHeaders& headers,
+                              const void* part,
+                              size_t size)
+      {
+        std::string contentType;
+        if (!Orthanc::MultipartStreamReader::GetMainContentType(contentType, headers))
+        {
+          contentType.clear();
+        }        
+
+        OrthancPluginErrorCode code = handler_.AddPart(contentType, headers, part, size);
+
+        if (code != OrthancPluginErrorCode_Success)
+        {
+          ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code);
+        }
+      }
+    };
+  }
+
+  static boost::shared_mutex  compatibilityMultipartMutex_;
+  static std::set<MultipartRestCallback*> compatibilityMultipartCallbacks_;
+    
+
+  namespace
+  {
+    void CompatibilityMultipartRestCallback(OrthancPluginRestOutput* output,
+                                            const char* url,
+                                            const OrthancPluginHttpRequest* request)
+    {
+      std::map<std::string, std::string> headers;
+      for (uint32_t i = 0; i < request->headersCount; i++)
+      {
+        headers[request->headersKeys[i]] = request->headersValues[i];
+      }
+
+      std::string mainContentType;
+      if (!Orthanc::MultipartStreamReader::GetMainContentType(mainContentType, headers))
+      {
+        LogError("Missing Content-Type HTTP header, prevents streaming the body");
+        ORTHANC_PLUGINS_THROW_EXCEPTION(UnsupportedMediaType);
+      }
+
+      std::string contentType, subType, boundary;
+      if (!Orthanc::MultipartStreamReader::ParseMultipartContentType
+          (contentType, subType, boundary, mainContentType))
+      {
+        LogError("Invalid Content-Type HTTP header, prevents streaming the body: \"" + 
+                 mainContentType + "\"");
+        ORTHANC_PLUGINS_THROW_EXCEPTION(UnsupportedMediaType);
+      }
+
+      std::vector<std::string> groups;
+      groups.reserve(request->groupsCount);
+      for (uint32_t i = 0; i < request->groupsCount; i++)
+      {
+        groups[i] = request->groups[i];
+      }
+
+      std::auto_ptr<MultipartRestCallback::IHandler> handler;
+
+      {
+        boost::shared_lock<boost::shared_mutex> lock(compatibilityMultipartMutex_);
+
+        for (std::set<MultipartRestCallback*>::const_iterator 
+               it = compatibilityMultipartCallbacks_.begin();
+             it != compatibilityMultipartCallbacks_.end(); ++it)
+        {
+          assert(*it != NULL);
+          handler.reset((*it)->CreateHandler(request->method, url, contentType, subType, groups, headers));
+          if (handler.get() != NULL)
+          {
+            break;
+          }
+        }
+      }
+
+      if (handler.get() != NULL)
+      {
+        {
+          CompatibilityPartHandler wrapper(*handler);
+          Orthanc::MultipartStreamReader reader(boundary);
+          reader.SetHandler(wrapper);
+          reader.AddChunk(request->body, request->bodySize);
+          reader.CloseStream();
+        }
+
+        handler->Execute(output);
+      }
+    }
+  }
+
+  void MultipartRestCallback::Register(const std::string& regularExpression)
+  {
+    LogWarning("Performance warning: The plugin was compiled against a pre-1.5.7 version "
+               "of the Orthanc SDK. Multipart transfers will be entirely stored in RAM.");
+
+    {
+      boost::unique_lock<boost::shared_mutex> lock(compatibilityMultipartMutex_);
+      compatibilityMultipartCallbacks_.insert(this);
+    }
+
+    OrthancPluginRegisterRestCallback(GetGlobalContext(), regularExpression.c_str(), 
+                                      Internals::Protect<CompatibilityMultipartRestCallback>);
+  }
+
+
+#else
+
+  void MultipartRestCallback::Register(const std::string& regularExpression)
+  {
+    /**
+     * Version >= 1.5.7 of the Orthanc framework must be
+     * available. Make sure that macros
+     * "ORTHANC_FRAMEWORK_VERSION_MAJOR",
+     * "ORTHANC_FRAMEWORK_VERSION_MINOR" and
+     * "ORTHANC_FRAMEWORK_VERSION_REVISION" are properly set.
+     **/
+    LogError("The compatibility mode for multipart transfers is not available.");
+    ORTHANC_PLUGINS_THROW_EXCEPTION(NotImplemented);
+  }  
+
 #endif
 
 }
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Sat Jun 08 16:49:10 2019 +0200
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Sat Jun 08 16:49:35 2019 +0200
@@ -57,6 +57,19 @@
 #endif
 
 
+#if !defined(ORTHANC_FRAMEWORK_VERSION_IS_ABOVE)
+#define ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(major, minor, revision)      \
+  (defined(ORTHANC_FRAMEWORK_VERSION_MAJOR) &&                          \
+   defined(ORTHANC_FRAMEWORK_VERSION_MINOR) &&                          \
+   defined(ORTHANC_FRAMEWORK_VERSION_REVISION) &&                       \
+   ORTHANC_FRAMEWORK_VERSION_MAJOR > major ||                           \
+   (ORTHANC_FRAMEWORK_VERSION_MAJOR == major &&                         \
+    (ORTHANC_FRAMEWORK_VERSION_MINOR > minor ||                         \
+     (ORTHANC_FRAMEWORK_VERSION_MINOR == minor &&                       \
+      ORTHANC_FRAMEWORK_VERSION_REVISION >= revision))))
+#endif
+
+
 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0)
 // The "OrthancPluginFindMatcher()" primitive was introduced in Orthanc 1.2.0
 #  define HAS_ORTHANC_PLUGIN_FIND_MATCHER  1
@@ -921,7 +934,6 @@
 
 
 
-#if HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER == 1
   class MultipartRestCallback : public boost::noncopyable
   {
   public:
@@ -954,5 +966,4 @@
 
     void Register(const std::string& regularExpression);
   };
-#endif
 }
--- a/Resources/DownloadOrthancFramework.cmake	Sat Jun 08 16:49:10 2019 +0200
+++ b/Resources/DownloadOrthancFramework.cmake	Sat Jun 08 16:49:35 2019 +0200
@@ -66,6 +66,9 @@
   if (NOT DEFINED ORTHANC_FRAMEWORK_BRANCH)
     if (ORTHANC_FRAMEWORK_VERSION STREQUAL "mainline")
       set(ORTHANC_FRAMEWORK_BRANCH "default")
+      set(ORTHANC_FRAMEWORK_MAJOR 999)
+      set(ORTHANC_FRAMEWORK_MINOR 999)
+      set(ORTHANC_FRAMEWORK_REVISION 999)
 
     else()
       set(ORTHANC_FRAMEWORK_BRANCH "Orthanc-${ORTHANC_FRAMEWORK_VERSION}")
@@ -108,6 +111,11 @@
       endif()
     endif()
   endif()
+else()
+  message("Using the Orthanc framework from a path of the filesystem. Assuming mainline version.")
+  set(ORTHANC_FRAMEWORK_MAJOR 999)
+  set(ORTHANC_FRAMEWORK_MINOR 999)
+  set(ORTHANC_FRAMEWORK_REVISION 999)
 endif()