# HG changeset patch # User s.jodogne@gmail.com # Date 1560005375 -7200 # Node ID 877363a406478dfdc41d06be3a60a9d585645dec # Parent 1787ad59406398a7be379d183e00d696f5c41bf5# Parent b7728227a852679fe447cd324b7d73c804c1deb0 merge diff -r 1787ad594063 -r 877363a40647 Plugins/Engine/OrthancPlugins.cpp --- 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; } diff -r 1787ad594063 -r 877363a40647 Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- 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 +# else +# define HAS_ORTHANC_FRAMEWORK_MULTIPART_READER 0 +# endif +#endif + + #include #include #include @@ -2744,6 +2755,144 @@ reinterpret_cast(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 compatibilityMultipartCallbacks_; + + + namespace + { + void CompatibilityMultipartRestCallback(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) + { + std::map 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 groups; + groups.reserve(request->groupsCount); + for (uint32_t i = 0; i < request->groupsCount; i++) + { + groups[i] = request->groups[i]; + } + + std::auto_ptr handler; + + { + boost::shared_lock lock(compatibilityMultipartMutex_); + + for (std::set::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 lock(compatibilityMultipartMutex_); + compatibilityMultipartCallbacks_.insert(this); + } + + OrthancPluginRegisterRestCallback(GetGlobalContext(), regularExpression.c_str(), + Internals::Protect); + } + + +#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 } diff -r 1787ad594063 -r 877363a40647 Plugins/Samples/Common/OrthancPluginCppWrapper.h --- 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 } diff -r 1787ad594063 -r 877363a40647 Resources/DownloadOrthancFramework.cmake --- 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()