Mercurial > hg > orthanc
diff Plugins/Samples/Common/OrthancPluginCppWrapper.h @ 3415:2a821deece64
refactoring to handle "not allowed" HTTP status 405
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 11 Jun 2019 21:06:57 +0200 |
parents | b9cba6a91780 |
children | 541c787e2230 |
line wrap: on
line diff
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h Tue Jun 11 19:44:10 2019 +0200 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h Tue Jun 11 21:06:57 2019 +0200 @@ -554,9 +554,9 @@ namespace Internals { template <RestCallback Callback> - OrthancPluginErrorCode Protect(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) + static OrthancPluginErrorCode Protect(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { try { @@ -934,71 +934,52 @@ }; - typedef IChunkedRequestReader* (*ChunkedRestCallback) (OrthancPluginRestOutput* output, - const char* url, + typedef IChunkedRequestReader* (*ChunkedRestCallback) (const char* url, const OrthancPluginHttpRequest* request); namespace Internals { + inline void NullRestCallback(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) + { + } + + inline IChunkedRequestReader *NullChunkedRestCallback(const char* url, + const OrthancPluginHttpRequest* request) + { + return NULL; + } + + #if HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER == 1 template <ChunkedRestCallback Callback> - OrthancPluginErrorCode Protect(OrthancPluginRestOutput* output, - OrthancPluginServerChunkedRequestReader** reader, - const char* url, - const OrthancPluginHttpRequest* request) + static OrthancPluginErrorCode Protect(OrthancPluginServerChunkedRequestReader** reader, + const char* url, + const OrthancPluginHttpRequest* request) { try { - switch (request->method) + if (reader == NULL) + { + return OrthancPluginErrorCode_InternalError; + } + else { - case OrthancPluginHttpMethod_Get: - case OrthancPluginHttpMethod_Delete: - if (output == NULL || - reader != NULL || - Callback(output, url, request) != NULL) - { - return OrthancPluginErrorCode_InternalError; - } - + *reader = reinterpret_cast<OrthancPluginServerChunkedRequestReader*>(Callback(url, request)); + if (*reader == NULL) + { + return OrthancPluginErrorCode_Plugin; + } + else + { return OrthancPluginErrorCode_Success; - - case OrthancPluginHttpMethod_Post: - case OrthancPluginHttpMethod_Put: - if (output != NULL || - reader == NULL) - { - return OrthancPluginErrorCode_InternalError; - } - else - { - *reader = reinterpret_cast<OrthancPluginServerChunkedRequestReader*>(Callback(NULL, url, request)); - if (*reader == NULL) - { - return OrthancPluginErrorCode_Plugin; - } - } - - return OrthancPluginErrorCode_Success; - - default: - return OrthancPluginErrorCode_InternalError; + } } } catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) { -#if HAS_ORTHANC_EXCEPTION == 1 && HAS_ORTHANC_PLUGIN_EXCEPTION_DETAILS == 1 - if (HasGlobalContext() && - e.HasDetails()) - { - // The "false" instructs Orthanc not to log the detailed - // error message. This is to avoid duplicating the details, - // because "OrthancException" already does it on construction. - OrthancPluginSetHttpErrorDetails - (GetGlobalContext(), output, e.GetDetails(), false); - } -#endif - return static_cast<OrthancPluginErrorCode>(e.GetErrorCode()); } catch (boost::bad_lexical_cast&) @@ -1011,7 +992,7 @@ } } - static OrthancPluginErrorCode ChunkedRequestReaderAddChunk( + static inline OrthancPluginErrorCode ChunkedRequestReaderAddChunk( OrthancPluginServerChunkedRequestReader* reader, const void* data, uint32_t size) @@ -1040,7 +1021,7 @@ } } - static OrthancPluginErrorCode ChunkedRequestReaderExecute( + static inline OrthancPluginErrorCode ChunkedRequestReaderExecute( OrthancPluginServerChunkedRequestReader* reader, OrthancPluginRestOutput* output) { @@ -1068,7 +1049,7 @@ } } - static void ChunkedRequestReaderFinalize( + static inline void ChunkedRequestReaderFinalize( OrthancPluginServerChunkedRequestReader* reader) { if (reader != NULL) @@ -1079,39 +1060,121 @@ #else - template <ChunkedRestCallback Callback> - void ChunkedRestCompatibility(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) + template< + RestCallback GetHandler, + ChunkedRestCallback PostHandler, + RestCallback DeleteHandler, + ChunkedRestCallback PutHandler + > + static void ChunkedRestCompatibility(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { + std::string allowed; + + if (GetHandler != Internals::NullRestCallback) + { + allowed += "GET"; + } + + if (PostHandler != Internals::NullChunkedRestCallback) + { + if (!allowed.empty()) + { + allowed += ","; + } + + allowed += "POST"; + } + + if (DeleteHandler != Internals::NullRestCallback) + { + if (!allowed.empty()) + { + allowed += ","; + } + + allowed += "DELETE"; + } + + if (PutHandler != Internals::NullChunkedRestCallback) + { + if (!allowed.empty()) + { + allowed += ","; + } + + allowed += "PUT"; + } + switch (request->method) { case OrthancPluginHttpMethod_Get: - case OrthancPluginHttpMethod_Delete: - if (Callback(output, url, request) != NULL) + { + if (GetHandler == Internals::NullRestCallback) { - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowed.c_str()); } else { - return; + GetHandler(output, url, request); } + return; + } case OrthancPluginHttpMethod_Post: - case OrthancPluginHttpMethod_Put: { - std::auto_ptr<IChunkedRequestReader> reader(Callback(NULL, url, request)); - if (reader.get() == NULL) + if (PostHandler == Internals::NullChunkedRestCallback) { - ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); + OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowed.c_str()); } else { - if (request->bodySize != 0) + std::auto_ptr<IChunkedRequestReader> reader(PostHandler(url, request)); + if (reader.get() == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(Plugin); + } + else { reader->AddChunk(request->body, request->bodySize); + reader->Execute(output); } - reader->Execute(output); + } + return; + } + + case OrthancPluginHttpMethod_Delete: + { + if (DeleteHandler == Internals::NullRestCallback) + { + OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowed.c_str()); + } + else + { + DeleteHandler(output, url, request); + } + return; + } + + case OrthancPluginHttpMethod_Put: + { + if (PutHandler == Internals::NullChunkedRestCallback) + { + OrthancPluginSendMethodNotAllowed(GetGlobalContext(), output, allowed.c_str()); + } + else + { + std::auto_ptr<IChunkedRequestReader> reader(PutHandler(url, request)); + if (reader.get() == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(Plugin); + } + else + { + reader->AddChunk(request->body, request->bodySize); + reader->Execute(output); + } } return; } @@ -1124,12 +1187,22 @@ } - template <ChunkedRestCallback Callback> + + template< + RestCallback GetHandler = Internals::NullRestCallback, + ChunkedRestCallback PostHandler = Internals::NullChunkedRestCallback, + RestCallback DeleteHandler = Internals::NullRestCallback, + ChunkedRestCallback PutHandler = Internals::NullChunkedRestCallback + > void RegisterChunkedRestCallback(const std::string& uri) { #if HAS_ORTHANC_PLUGIN_CHUNKED_HTTP_SERVER == 1 OrthancPluginRegisterChunkedRestCallback( - GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>, + GetGlobalContext(), uri.c_str(), + GetHandler == Internals::NullRestCallback ? NULL : Internals::Protect<GetHandler>, + PostHandler == Internals::NullChunkedRestCallback ? NULL : Internals::Protect<PostHandler>, + DeleteHandler == Internals::NullRestCallback ? NULL : Internals::Protect<DeleteHandler>, + PutHandler == Internals::NullChunkedRestCallback ? NULL : Internals::Protect<PutHandler>, Internals::ChunkedRequestReaderAddChunk, Internals::ChunkedRequestReaderExecute, Internals::ChunkedRequestReaderFinalize); @@ -1138,7 +1211,8 @@ "of the Orthanc SDK. Multipart transfers will be entirely stored in RAM."); OrthancPluginRegisterRestCallback( GetGlobalContext(), uri.c_str(), - Internals::Protect< Internals::ChunkedRestCompatibility<Callback> >); + Internals::Protect< Internals::ChunkedRestCompatibility< + GetHandler, PostHandler, DeleteHandler, PutHandler> >); #endif } }