# HG changeset patch # User Sebastien Jodogne # Date 1487796556 -3600 # Node ID ce5c13b95dac460a2b8e323a4e680ab3037ebffc # Parent f915aff7a866bf81017138023dd872796a7847e7 New function: OrthancPluginRegisterIncomingHttpRequestFilter2() diff -r f915aff7a866 -r ce5c13b95dac Core/HttpServer/IIncomingHttpRequestFilter.h --- a/Core/HttpServer/IIncomingHttpRequestFilter.h Wed Feb 22 13:32:05 2017 +0100 +++ b/Core/HttpServer/IIncomingHttpRequestFilter.h Wed Feb 22 21:49:16 2017 +0100 @@ -48,6 +48,7 @@ const char* uri, const char* ip, const char* username, - const IHttpHandler::Arguments& httpHeaders) const = 0; + const IHttpHandler::Arguments& httpHeaders, + const IHttpHandler::GetArguments& getArguments) const = 0; }; } diff -r f915aff7a866 -r ce5c13b95dac Core/HttpServer/MongooseServer.cpp --- a/Core/HttpServer/MongooseServer.cpp Wed Feb 22 13:32:05 2017 +0100 +++ b/Core/HttpServer/MongooseServer.cpp Wed Feb 22 21:49:16 2017 +0100 @@ -652,7 +652,8 @@ const IIncomingHttpRequestFilter *filter = server.GetIncomingHttpRequestFilter(); if (filter != NULL) { - if (!filter->IsAllowed(method, request->uri, remoteIp, username.c_str(), headers)) + if (!filter->IsAllowed(method, request->uri, remoteIp, + username.c_str(), headers, argumentsGET)) { //output.SendUnauthorized(ORTHANC_REALM); output.SendStatus(HttpStatus_403_Forbidden); diff -r f915aff7a866 -r ce5c13b95dac NEWS --- a/NEWS Wed Feb 22 13:32:05 2017 +0100 +++ b/NEWS Wed Feb 22 21:49:16 2017 +0100 @@ -1,8 +1,17 @@ Pending changes in the mainline =============================== +Plugins +------- + +* New function: "OrthancPluginRegisterIncomingHttpRequestFilter2()" + +Lua +--- + * Added HTTP headers support for Lua HttpPost/HttpGet/HttpPut/HttpDelete + Version 1.2.0 (2016/12/13) ========================== diff -r f915aff7a866 -r ce5c13b95dac OrthancServer/main.cpp --- a/OrthancServer/main.cpp Wed Feb 22 13:32:05 2017 +0100 +++ b/OrthancServer/main.cpp Wed Feb 22 21:49:16 2017 +0100 @@ -291,10 +291,11 @@ const char* uri, const char* ip, const char* username, - const IHttpHandler::Arguments& httpHeaders) const + const IHttpHandler::Arguments& httpHeaders, + const IHttpHandler::GetArguments& getArguments) const { if (plugins_ != NULL && - !plugins_->IsAllowed(method, uri, ip, username, httpHeaders)) + !plugins_->IsAllowed(method, uri, ip, username, httpHeaders, getArguments)) { return false; } diff -r f915aff7a866 -r ce5c13b95dac Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Wed Feb 22 13:32:05 2017 +0100 +++ b/Plugins/Engine/OrthancPlugins.cpp Wed Feb 22 21:49:16 2017 +0100 @@ -345,6 +345,7 @@ typedef std::list OnStoredCallbacks; typedef std::list OnChangeCallbacks; typedef std::list IncomingHttpRequestFilters; + typedef std::list IncomingHttpRequestFilters2; typedef std::list DecodeImageCallbacks; typedef std::map Properties; @@ -358,6 +359,7 @@ DecodeImageCallbacks decodeImageCallbacks_; _OrthancPluginMoveCallback moveCallbacks_; IncomingHttpRequestFilters incomingHttpRequestFilters_; + IncomingHttpRequestFilters2 incomingHttpRequestFilters2_; std::auto_ptr storageArea_; boost::recursive_mutex restCallbackMutex_; @@ -1121,6 +1123,16 @@ } + void OrthancPlugins::RegisterIncomingHttpRequestFilter2(const void* parameters) + { + const _OrthancPluginIncomingHttpRequestFilter2& p = + *reinterpret_cast(parameters); + + LOG(INFO) << "Plugin has registered a callback to filter incoming HTTP requests"; + pimpl_->incomingHttpRequestFilters2_.push_back(p.callback); + } + + void OrthancPlugins::AnswerBuffer(const void* parameters) { const _OrthancPluginAnswerBuffer& p = @@ -2688,6 +2700,10 @@ RegisterIncomingHttpRequestFilter(parameters); return true; + case _OrthancPluginService_RegisterIncomingHttpRequestFilter2: + RegisterIncomingHttpRequestFilter2(parameters); + return true; + case _OrthancPluginService_RegisterStorageArea: { LOG(INFO) << "Plugin has registered a custom storage area"; @@ -3098,8 +3114,11 @@ const char* uri, const char* ip, const char* username, - const IHttpHandler::Arguments& httpHeaders) const + const IHttpHandler::Arguments& httpHeaders, + const IHttpHandler::GetArguments& getArguments) const { + OrthancPluginHttpMethod cMethod = Plugins::Convert(method); + std::vector httpKeys(httpHeaders.size()); std::vector httpValues(httpHeaders.size()); @@ -3111,26 +3130,56 @@ httpValues[pos] = it->second.c_str(); } - OrthancPluginHttpMethod cMethod = Plugins::Convert(method); - const char** cHttpKeys = (httpKeys.size() == 0 ? NULL : &httpKeys[0]); - const char** cHttpValues = (httpValues.size() == 0 ? NULL : &httpValues[0]); + std::vector getKeys(getArguments.size()); + std::vector getValues(getArguments.size()); + + for (size_t i = 0; i < getArguments.size(); i++) + { + getKeys[i] = getArguments[i].first.c_str(); + getValues[i] = getArguments[i].second.c_str(); + } + + // Improved callback with support for GET arguments, since Orthanc 1.2.1 + for (PImpl::IncomingHttpRequestFilters2::const_iterator + filter = pimpl_->incomingHttpRequestFilters2_.begin(); + filter != pimpl_->incomingHttpRequestFilters2_.end(); ++filter) + { + int32_t allowed = (*filter) (cMethod, uri, ip, + httpKeys.size(), + httpKeys.empty() ? NULL : &httpKeys[0], + httpValues.empty() ? NULL : &httpValues[0], + getKeys.size(), + getKeys.empty() ? NULL : &getKeys[0], + getValues.empty() ? NULL : &getValues[0]); + + if (allowed == 0) + { + return false; + } + else if (allowed != 1) + { + // The callback is only allowed to answer 0 or 1 + throw OrthancException(ErrorCode_Plugin); + } + } for (PImpl::IncomingHttpRequestFilters::const_iterator filter = pimpl_->incomingHttpRequestFilters_.begin(); filter != pimpl_->incomingHttpRequestFilters_.end(); ++filter) { - int32_t allowed = (*filter) (cMethod, uri, ip, httpKeys.size(), cHttpKeys, cHttpValues); - - if (allowed != 0 && - allowed != 1) - { - throw OrthancException(ErrorCode_Plugin); - } + int32_t allowed = (*filter) (cMethod, uri, ip, httpKeys.size(), + httpKeys.empty() ? NULL : &httpKeys[0], + httpValues.empty() ? NULL : &httpValues[0]); if (allowed == 0) { return false; } + else if (allowed != 1) + { + // The callback is only allowed to answer 0 or 1 + throw OrthancException(ErrorCode_Plugin); + } } return true; diff -r f915aff7a866 -r ce5c13b95dac Plugins/Engine/OrthancPlugins.h --- a/Plugins/Engine/OrthancPlugins.h Wed Feb 22 13:32:05 2017 +0100 +++ b/Plugins/Engine/OrthancPlugins.h Wed Feb 22 21:49:16 2017 +0100 @@ -106,6 +106,8 @@ void RegisterIncomingHttpRequestFilter(const void* parameters); + void RegisterIncomingHttpRequestFilter2(const void* parameters); + void AnswerBuffer(const void* parameters); void Redirect(const void* parameters); @@ -281,7 +283,8 @@ const char* uri, const char* ip, const char* username, - const IHttpHandler::Arguments& httpHeaders) const; + const IHttpHandler::Arguments& httpHeaders, + const IHttpHandler::GetArguments& getArguments) const; bool HasFindHandler(); diff -r f915aff7a866 -r ce5c13b95dac Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 22 13:32:05 2017 +0100 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 22 21:49:16 2017 +0100 @@ -22,7 +22,7 @@ * - Possibly register a handler for C-Find SCP against DICOM worklists using OrthancPluginRegisterWorklistCallback(). * - Possibly register a handler for C-Move SCP using OrthancPluginRegisterMoveCallback(). * - Possibly register a custom decoder for DICOM images using OrthancPluginRegisterDecodeImageCallback(). - * - Possibly register a callback to filter incoming HTTP requests using OrthancPluginRegisterIncomingHttpRequestFilter(). + * - Possibly register a callback to filter incoming HTTP requests using OrthancPluginRegisterIncomingHttpRequestFilter2(). * -# void OrthancPluginFinalize(): * This function is invoked by Orthanc during its shutdown. The plugin * must free all its memory. @@ -422,6 +422,7 @@ _OrthancPluginService_RegisterIncomingHttpRequestFilter = 1007, _OrthancPluginService_RegisterFindCallback = 1008, _OrthancPluginService_RegisterMoveCallback = 1009, + _OrthancPluginService_RegisterIncomingHttpRequestFilter2 = 1010, /* Sending answers to REST calls */ _OrthancPluginService_AnswerBuffer = 2000, @@ -1014,6 +1015,7 @@ * @param headersValues The values of the HTTP headers. * @return 0 if forbidden access, 1 if allowed access, -1 if error. * @ingroup Callback + * @deprecated Please instead use OrthancPluginIncomingHttpRequestFilter2() **/ typedef int32_t (*OrthancPluginIncomingHttpRequestFilter) ( OrthancPluginHttpMethod method, @@ -1026,6 +1028,40 @@ /** + * @brief Callback to filter incoming HTTP requests received by Orthanc. + * + * Signature of a callback function that is triggered whenever + * Orthanc receives an HTTP/REST request, and that answers whether + * this request should be allowed. If the callback returns "0" + * ("false"), the server answers with HTTP status code 403 + * (Forbidden). + * + * @param method The HTTP method used by the request. + * @param uri The URI of interest. + * @param ip The IP address of the HTTP client. + * @param headersCount The number of HTTP headers. + * @param headersKeys The keys of the HTTP headers (always converted to low-case). + * @param headersValues The values of the HTTP headers. + * @param getArgumentsCount The number of GET arguments (only for the GET HTTP method). + * @param getArgumentsKeys The keys of the GET arguments (only for the GET HTTP method). + * @param getArgumentsValues The values of the GET arguments (only for the GET HTTP method). + * @return 0 if forbidden access, 1 if allowed access, -1 if error. + * @ingroup Callback + **/ + typedef int32_t (*OrthancPluginIncomingHttpRequestFilter2) ( + OrthancPluginHttpMethod method, + const char* uri, + const char* ip, + uint32_t headersCount, + const char* const* headersKeys, + const char* const* headersValues, + uint32_t getArgumentsCount, + const char* const* getArgumentsKeys, + const char* const* getArgumentsValues); + + + + /** * @brief Callback to handle incoming C-Find SCP requests. * * Signature of a callback function that is triggered whenever @@ -4997,6 +5033,7 @@ * @param callback The callback. * @return 0 if success, other value if error. * @ingroup Callbacks + * @deprecated Please instead use OrthancPluginRegisterIncomingHttpRequestFilter2() **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingHttpRequestFilter( OrthancPluginContext* context, @@ -5546,6 +5583,32 @@ } + typedef struct + { + OrthancPluginIncomingHttpRequestFilter2 callback; + } _OrthancPluginIncomingHttpRequestFilter2; + + /** + * @brief Register a callback to filter incoming HTTP requests. + * + * This function registers a custom callback to filter incoming HTTP/REST + * requests received by the HTTP server of Orthanc. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param callback The callback. + * @return 0 if success, other value if error. + * @ingroup Callbacks + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingHttpRequestFilter2( + OrthancPluginContext* context, + OrthancPluginIncomingHttpRequestFilter2 callback) + { + _OrthancPluginIncomingHttpRequestFilter2 params; + params.callback = callback; + + return context->InvokeService(context, _OrthancPluginService_RegisterIncomingHttpRequestFilter2, ¶ms); + } + #ifdef __cplusplus } #endif diff -r f915aff7a866 -r ce5c13b95dac Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Wed Feb 22 13:32:05 2017 +0100 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Wed Feb 22 21:49:16 2017 +0100 @@ -1126,14 +1126,14 @@ } - static void ReportIncompatibleVersion(OrthancPluginContext* context, - unsigned int major, - unsigned int minor, - unsigned int revision) + void ReportMinimalOrthancVersion(OrthancPluginContext* context, + unsigned int major, + unsigned int minor, + unsigned int revision) { std::string s = ("Your version of the Orthanc core (" + std::string(context->orthancVersion) + - ") is too old to run this plugin (" + + ") is too old to run this plugin (version " + boost::lexical_cast(major) + "." + boost::lexical_cast(minor) + "." + boost::lexical_cast(revision) + @@ -1189,7 +1189,6 @@ if (a < major) { - ReportIncompatibleVersion(context, major, minor, revision); return false; } @@ -1204,7 +1203,6 @@ if (b < minor) { - ReportIncompatibleVersion(context, major, minor, revision); return false; } @@ -1217,7 +1215,6 @@ } else { - ReportIncompatibleVersion(context, major, minor, revision); return false; } } diff -r f915aff7a866 -r ce5c13b95dac Plugins/Samples/Common/OrthancPluginCppWrapper.h --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h Wed Feb 22 13:32:05 2017 +0100 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h Wed Feb 22 21:49:16 2017 +0100 @@ -461,6 +461,11 @@ } } + void ReportMinimalOrthancVersion(OrthancPluginContext* context, + unsigned int major, + unsigned int minor, + unsigned int revision); + bool CheckMinimalOrthancVersion(OrthancPluginContext* context, unsigned int major, unsigned int minor, diff -r f915aff7a866 -r ce5c13b95dac Plugins/Samples/ModalityWorklists/Plugin.cpp --- a/Plugins/Samples/ModalityWorklists/Plugin.cpp Wed Feb 22 13:32:05 2017 +0100 +++ b/Plugins/Samples/ModalityWorklists/Plugin.cpp Wed Feb 22 21:49:16 2017 +0100 @@ -192,13 +192,10 @@ /* Check the version of the Orthanc core */ if (OrthancPluginCheckVersion(c) == 0) { - char info[1024]; - sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", - context_->orthancVersion, - ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, - ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, - ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); - OrthancPluginLogError(context_, info); + OrthancPlugins::ReportMinimalOrthancVersion(context_, + ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, + ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, + ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); return -1; } diff -r f915aff7a866 -r ce5c13b95dac Plugins/Samples/ServeFolders/Plugin.cpp --- a/Plugins/Samples/ServeFolders/Plugin.cpp Wed Feb 22 13:32:05 2017 +0100 +++ b/Plugins/Samples/ServeFolders/Plugin.cpp Wed Feb 22 21:49:16 2017 +0100 @@ -416,13 +416,10 @@ /* Check the version of the Orthanc core */ if (OrthancPluginCheckVersion(context_) == 0) { - char info[1024]; - sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", - context_->orthancVersion, - ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, - ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, - ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); - OrthancPluginLogError(context_, info); + OrthancPlugins::ReportMinimalOrthancVersion(context_, + ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, + ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, + ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); return -1; }