Mercurial > hg > orthanc
comparison Plugins/Samples/Common/OrthancPluginCppWrapper.cpp @ 3407:b7728227a852
C++ wrappers: compatibility mode if missing OrthancPluginRegisterMultipartRestCallback()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sat, 08 Jun 2019 11:57:46 +0200 |
parents | 408ffcb4038f |
children | 3575466a3e57 |
comparison
equal
deleted
inserted
replaced
3406:8de071691d13 | 3407:b7728227a852 |
---|---|
31 **/ | 31 **/ |
32 | 32 |
33 | 33 |
34 #include "OrthancPluginCppWrapper.h" | 34 #include "OrthancPluginCppWrapper.h" |
35 | 35 |
36 #if HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER == 0 | |
37 # if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 5, 7) | |
38 # define HAS_ORTHANC_FRAMEWORK_MULTIPART_READER 1 | |
39 # include "../../../Core/HttpServer/MultipartStreamReader.h" | |
40 # include <boost/thread/shared_mutex.hpp> | |
41 # else | |
42 # define HAS_ORTHANC_FRAMEWORK_MULTIPART_READER 0 | |
43 # endif | |
44 #endif | |
45 | |
46 | |
36 #include <boost/algorithm/string/predicate.hpp> | 47 #include <boost/algorithm/string/predicate.hpp> |
37 #include <json/reader.h> | 48 #include <json/reader.h> |
38 #include <json/writer.h> | 49 #include <json/writer.h> |
39 | 50 |
40 | 51 |
2742 OrthancPluginRegisterMultipartRestCallback( | 2753 OrthancPluginRegisterMultipartRestCallback( |
2743 GetGlobalContext(), regularExpression.c_str(), | 2754 GetGlobalContext(), regularExpression.c_str(), |
2744 reinterpret_cast<OrthancPluginMultipartRestFactory*>(this), | 2755 reinterpret_cast<OrthancPluginMultipartRestFactory*>(this), |
2745 MultipartRestFactory, MultipartRestAddPart, MultipartRestExecute, MultipartRestFinalize); | 2756 MultipartRestFactory, MultipartRestAddPart, MultipartRestExecute, MultipartRestFinalize); |
2746 } | 2757 } |
2758 | |
2759 #elif HAS_ORTHANC_FRAMEWORK_MULTIPART_READER == 1 | |
2760 | |
2761 namespace | |
2762 { | |
2763 class CompatibilityPartHandler : public Orthanc::MultipartStreamReader::IHandler | |
2764 { | |
2765 private: | |
2766 MultipartRestCallback::IHandler& handler_; | |
2767 | |
2768 public: | |
2769 CompatibilityPartHandler(MultipartRestCallback::IHandler& handler) : | |
2770 handler_(handler) | |
2771 { | |
2772 } | |
2773 | |
2774 virtual void HandlePart(const Orthanc::MultipartStreamReader::HttpHeaders& headers, | |
2775 const void* part, | |
2776 size_t size) | |
2777 { | |
2778 std::string contentType; | |
2779 if (!Orthanc::MultipartStreamReader::GetMainContentType(contentType, headers)) | |
2780 { | |
2781 contentType.clear(); | |
2782 } | |
2783 | |
2784 OrthancPluginErrorCode code = handler_.AddPart(contentType, headers, part, size); | |
2785 | |
2786 if (code != OrthancPluginErrorCode_Success) | |
2787 { | |
2788 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); | |
2789 } | |
2790 } | |
2791 }; | |
2792 } | |
2793 | |
2794 static boost::shared_mutex compatibilityMultipartMutex_; | |
2795 static std::set<MultipartRestCallback*> compatibilityMultipartCallbacks_; | |
2796 | |
2797 | |
2798 namespace | |
2799 { | |
2800 void CompatibilityMultipartRestCallback(OrthancPluginRestOutput* output, | |
2801 const char* url, | |
2802 const OrthancPluginHttpRequest* request) | |
2803 { | |
2804 std::map<std::string, std::string> headers; | |
2805 for (uint32_t i = 0; i < request->headersCount; i++) | |
2806 { | |
2807 headers[request->headersKeys[i]] = request->headersValues[i]; | |
2808 } | |
2809 | |
2810 std::string mainContentType; | |
2811 if (!Orthanc::MultipartStreamReader::GetMainContentType(mainContentType, headers)) | |
2812 { | |
2813 LogError("Missing Content-Type HTTP header, prevents streaming the body"); | |
2814 ORTHANC_PLUGINS_THROW_EXCEPTION(UnsupportedMediaType); | |
2815 } | |
2816 | |
2817 std::string contentType, subType, boundary; | |
2818 if (!Orthanc::MultipartStreamReader::ParseMultipartContentType | |
2819 (contentType, subType, boundary, mainContentType)) | |
2820 { | |
2821 LogError("Invalid Content-Type HTTP header, prevents streaming the body: \"" + | |
2822 mainContentType + "\""); | |
2823 ORTHANC_PLUGINS_THROW_EXCEPTION(UnsupportedMediaType); | |
2824 } | |
2825 | |
2826 std::vector<std::string> groups; | |
2827 groups.reserve(request->groupsCount); | |
2828 for (uint32_t i = 0; i < request->groupsCount; i++) | |
2829 { | |
2830 groups[i] = request->groups[i]; | |
2831 } | |
2832 | |
2833 std::auto_ptr<MultipartRestCallback::IHandler> handler; | |
2834 | |
2835 { | |
2836 boost::shared_lock<boost::shared_mutex> lock(compatibilityMultipartMutex_); | |
2837 | |
2838 for (std::set<MultipartRestCallback*>::const_iterator | |
2839 it = compatibilityMultipartCallbacks_.begin(); | |
2840 it != compatibilityMultipartCallbacks_.end(); ++it) | |
2841 { | |
2842 assert(*it != NULL); | |
2843 handler.reset((*it)->CreateHandler(request->method, url, contentType, subType, groups, headers)); | |
2844 if (handler.get() != NULL) | |
2845 { | |
2846 break; | |
2847 } | |
2848 } | |
2849 } | |
2850 | |
2851 if (handler.get() != NULL) | |
2852 { | |
2853 { | |
2854 CompatibilityPartHandler wrapper(*handler); | |
2855 Orthanc::MultipartStreamReader reader(boundary); | |
2856 reader.SetHandler(wrapper); | |
2857 reader.AddChunk(request->body, request->bodySize); | |
2858 reader.CloseStream(); | |
2859 } | |
2860 | |
2861 handler->Execute(output); | |
2862 } | |
2863 } | |
2864 } | |
2865 | |
2866 void MultipartRestCallback::Register(const std::string& regularExpression) | |
2867 { | |
2868 LogWarning("Performance warning: The plugin was compiled against a pre-1.5.7 version " | |
2869 "of the Orthanc SDK. Multipart transfers will be entirely stored in RAM."); | |
2870 | |
2871 { | |
2872 boost::unique_lock<boost::shared_mutex> lock(compatibilityMultipartMutex_); | |
2873 compatibilityMultipartCallbacks_.insert(this); | |
2874 } | |
2875 | |
2876 OrthancPluginRegisterRestCallback(GetGlobalContext(), regularExpression.c_str(), | |
2877 Internals::Protect<CompatibilityMultipartRestCallback>); | |
2878 } | |
2879 | |
2880 | |
2881 #else | |
2882 | |
2883 void MultipartRestCallback::Register(const std::string& regularExpression) | |
2884 { | |
2885 /** | |
2886 * Version >= 1.5.7 of the Orthanc framework must be | |
2887 * available. Make sure that macros | |
2888 * "ORTHANC_FRAMEWORK_VERSION_MAJOR", | |
2889 * "ORTHANC_FRAMEWORK_VERSION_MINOR" and | |
2890 * "ORTHANC_FRAMEWORK_VERSION_REVISION" are properly set. | |
2891 **/ | |
2892 LogError("The compatibility mode for multipart transfers is not available."); | |
2893 ORTHANC_PLUGINS_THROW_EXCEPTION(NotImplemented); | |
2894 } | |
2895 | |
2747 #endif | 2896 #endif |
2748 | 2897 |
2749 } | 2898 } |