Mercurial > hg > orthanc
diff Plugins/Engine/OrthancPlugins.cpp @ 3399:4e8205871967
OrthancPluginRegisterMultipartRestCallback() is working
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 07 Jun 2019 14:14:31 +0200 |
parents | 9019279dbfd7 |
children | 962e5f00744b |
line wrap: on
line diff
--- a/Plugins/Engine/OrthancPlugins.cpp Fri Jun 07 13:36:43 2019 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Fri Jun 07 14:14:31 2019 +0200 @@ -51,6 +51,7 @@ #include "../../Core/DicomParsing/Internals/DicomImageDecoder.h" #include "../../Core/DicomParsing/ToDcmtkBridge.h" #include "../../Core/HttpServer/HttpToolbox.h" +#include "../../Core/HttpServer/MultipartStreamReader.h" #include "../../Core/Images/Image.h" #include "../../Core/Images/ImageProcessing.h" #include "../../Core/Images/JpegReader.h" @@ -1322,12 +1323,14 @@ memset(&request, 0, sizeof(OrthancPluginHttpRequest)); ArgumentsToPlugin(headersKeys, headersValues, headers); + assert(headersKeys.size() == headersValues.size()); switch (method) { case HttpMethod_Get: request.method = OrthancPluginHttpMethod_Get; ArgumentsToPlugin(getKeys, getValues, getArguments); + assert(getKeys.size() == getValues.size()); break; case HttpMethod_Post: @@ -4107,25 +4110,59 @@ } - class OrthancPlugins::MultipartStream : public IHttpHandler::IStream + class OrthancPlugins::MultipartStream : + public IHttpHandler::IStream, + private MultipartStreamReader::IHandler { private: OrthancPluginMultipartRestHandler* handler_; _OrthancPluginMultipartRestCallback parameters_; + MultipartStreamReader reader_; PluginsErrorDictionary& errorDictionary_; + virtual void HandlePart(const MultipartStreamReader::HttpHeaders& headers, + const void* part, + size_t size) + { + assert(handler_ != NULL); + + std::string contentType; + MultipartStreamReader::GetMainContentType(contentType, headers); + Orthanc::Toolbox::ToLowerCase(contentType); + + std::vector<const char*> headersKeys, headersValues; + ArgumentsToPlugin(headersKeys, headersValues, headers); + assert(headersKeys.size() == headersValues.size()); + + OrthancPluginErrorCode error = parameters_.addPart( + handler_, contentType.c_str(), headersKeys.size(), + headersKeys.empty() ? NULL : &headersKeys[0], + headersValues.empty() ? NULL : &headersValues[0], + part, size); + + if (error != OrthancPluginErrorCode_Success) + { + errorDictionary_.LogError(error, true); + throw OrthancException(static_cast<ErrorCode>(error)); + } + } + public: MultipartStream(OrthancPluginMultipartRestHandler* handler, const _OrthancPluginMultipartRestCallback& parameters, + const std::string& boundary, PluginsErrorDictionary& errorDictionary) : handler_(handler), parameters_(parameters), + reader_(boundary), errorDictionary_(errorDictionary) { if (handler_ == NULL) { throw OrthancException(ErrorCode_Plugin, "The plugin has not created a multipart stream handler"); } + + reader_.SetHandler(*this); } virtual ~MultipartStream() @@ -4139,25 +4176,15 @@ virtual void AddBodyChunk(const void* data, size_t size) { - assert(handler_ != NULL); - - // TODO => multipart parsing - - OrthancPluginErrorCode error = - parameters_.addPart(handler_, "content-type", 0 /* headers */, NULL, NULL, - data, size); - - if (error != OrthancPluginErrorCode_Success) - { - errorDictionary_.LogError(error, true); - throw OrthancException(static_cast<ErrorCode>(error)); - } + reader_.AddChunk(data, size); } virtual void Execute(HttpOutput& output) { assert(handler_ != NULL); + reader_.CloseStream(); + PImpl::PluginHttpOutput pluginOutput(output); OrthancPluginErrorCode error = parameters_.execute( @@ -4187,6 +4214,7 @@ std::vector<const char*> headersKeys, headersValues; ArgumentsToPlugin(headersKeys, headersValues, headers); + assert(headersKeys.size() == headersValues.size()); OrthancPluginHttpMethod convertedMethod; switch (method) @@ -4203,16 +4231,30 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } - std::string contentType = "TODO"; // TODO + std::string multipartContentType; + if (!MultipartStreamReader::GetMainContentType(multipartContentType, headers)) + { + LOG(INFO) << "Missing Content-Type HTTP header, prevents streaming the body"; + continue; + } + + std::string contentType, subType, boundary; + if (!MultipartStreamReader::ParseMultipartContentType + (contentType, subType, boundary, multipartContentType)) + { + LOG(INFO) << "Invalid Content-Type HTTP header, " + << "prevents streaming the body: \"" << multipartContentType << "\""; + continue; + } OrthancPluginMultipartRestHandler* handler = (*it)->GetParameters().createHandler( (*it)->GetParameters().factory, - convertedMethod, matcher.GetFlatUri().c_str(), contentType.c_str(), + convertedMethod, matcher.GetFlatUri().c_str(), contentType.c_str(), subType.c_str(), matcher.GetGroupsCount(), matcher.GetGroups(), headers.size(), headers.empty() ? NULL : &headersKeys[0], headers.empty() ? NULL : &headersValues[0]); - return new MultipartStream(handler, (*it)->GetParameters(), GetErrorDictionary()); + return new MultipartStream(handler, (*it)->GetParameters(), boundary, GetErrorDictionary()); } }