# HG changeset patch # User Sebastien Jodogne # Date 1443102917 -7200 # Node ID 1558b3226b18d67efa6cc49f1e63e54a5127db23 # Parent 939b921b2c819e6fbb5c17d55158aff53e6bfb4a IHttpExceptionFormatter diff -r 939b921b2c81 -r 1558b3226b18 Core/HttpServer/HttpOutput.cpp --- a/Core/HttpServer/HttpOutput.cpp Wed Sep 23 22:05:27 2015 +0200 +++ b/Core/HttpServer/HttpOutput.cpp Thu Sep 24 15:55:17 2015 +0200 @@ -302,15 +302,7 @@ stateMachine_.ClearHeaders(); stateMachine_.SetHttpStatus(status); - - if (describeErrors_) - { - stateMachine_.SendBody(message, messageSize); - } - else - { - stateMachine_.SendBody(NULL, 0); - } + stateMachine_.SendBody(message, messageSize); } diff -r 939b921b2c81 -r 1558b3226b18 Core/HttpServer/HttpOutput.h --- a/Core/HttpServer/HttpOutput.h Wed Sep 23 22:05:27 2015 +0200 +++ b/Core/HttpServer/HttpOutput.h Thu Sep 24 15:55:17 2015 +0200 @@ -114,7 +114,6 @@ StateMachine stateMachine_; bool isDeflateAllowed_; bool isGzipAllowed_; - bool describeErrors_; HttpCompression GetPreferredCompression(size_t bodySize) const; @@ -123,8 +122,7 @@ bool isKeepAlive) : stateMachine_(stream, isKeepAlive), isDeflateAllowed_(false), - isGzipAllowed_(false), - describeErrors_(true) + isGzipAllowed_(false) { } @@ -148,16 +146,6 @@ return isGzipAllowed_; } - void SetDescribeErrorsEnabled(bool enabled) - { - describeErrors_ = enabled; - } - - bool IsDescribeErrorsEnabled() const - { - return describeErrors_; - } - void SendStatus(HttpStatus status, const char* message, size_t messageSize); diff -r 939b921b2c81 -r 1558b3226b18 Core/HttpServer/MongooseServer.cpp --- a/Core/HttpServer/MongooseServer.cpp Wed Sep 23 22:05:27 2015 +0200 +++ b/Core/HttpServer/MongooseServer.cpp Thu Sep 24 15:55:17 2015 +0200 @@ -36,7 +36,6 @@ #include "MongooseServer.h" #include "../Logging.h" -#include "../OrthancException.h" #include "../ChunkedBuffer.h" #include "HttpToolbox.h" #include "mongoose.h" @@ -583,7 +582,6 @@ MongooseOutputStream stream(connection); HttpOutput output(stream, that->IsKeepAliveEnabled()); - output.SetDescribeErrorsEnabled(that->IsDescribeErrorsEnabled()); // Check remote calls if (!that->IsRemoteAccessAllowed() && @@ -735,12 +733,12 @@ } catch (boost::bad_lexical_cast&) { - throw OrthancException(ErrorCode_BadParameterType, HttpStatus_400_BadRequest); + throw OrthancException(ErrorCode_BadParameterType); } catch (std::runtime_error&) { // Presumably an error while parsing the JSON body - throw OrthancException(ErrorCode_BadRequest, HttpStatus_400_BadRequest); + throw OrthancException(ErrorCode_BadRequest); } if (!found) @@ -753,22 +751,16 @@ // Using this candidate handler results in an exception LOG(ERROR) << "Exception in the HTTP handler: " << e.What(); - Json::Value message = Json::objectValue; - message["Method"] = EnumerationToString(method); - message["Uri"] = request->uri; - - // TODO - message["HttpError"] = EnumerationToString(e.GetHttpStatus()); - message["HttpStatus"] = e.GetHttpStatus(); - message["Message"] = e.What(); - message["OrthancError"] = EnumerationToString(e.GetErrorCode()); - message["OrthancStatus"] = e.GetErrorCode(); - - std::string info = message.toStyledString(); - try { - output.SendStatus(e.GetHttpStatus(), info); + if (that->GetExceptionFormatter() == NULL) + { + output.SendStatus(e.GetHttpStatus()); + } + else + { + that->GetExceptionFormatter()->Format(output, e, method, request->uri); + } } catch (OrthancException&) { @@ -834,7 +826,7 @@ filter_ = NULL; keepAlive_ = false; httpCompression_ = true; - describeErrors_ = true; + exceptionFormatter_ = NULL; #if ORTHANC_SSL_ENABLED == 1 // Check for the Heartbleed exploit @@ -985,18 +977,20 @@ LOG(WARNING) << "HTTP compression is " << (enabled ? "enabled" : "disabled"); } - void MongooseServer::SetDescribeErrorsEnabled(bool enabled) - { - describeErrors_ = enabled; - LOG(INFO) << "Description of the errors in the HTTP answers is " << (enabled ? "enabled" : "disabled"); - } - void MongooseServer::SetIncomingHttpRequestFilter(IIncomingHttpRequestFilter& filter) { Stop(); filter_ = &filter; } + + void MongooseServer::SetHttpExceptionFormatter(IHttpExceptionFormatter& formatter) + { + Stop(); + exceptionFormatter_ = &formatter; + } + + bool MongooseServer::IsValidBasicHttpAuthentication(const std::string& basic) const { return registeredUsers_.find(basic) != registeredUsers_.end(); diff -r 939b921b2c81 -r 1558b3226b18 Core/HttpServer/MongooseServer.h --- a/Core/HttpServer/MongooseServer.h Wed Sep 23 22:05:27 2015 +0200 +++ b/Core/HttpServer/MongooseServer.h Thu Sep 24 15:55:17 2015 +0200 @@ -34,6 +34,8 @@ #include "IHttpHandler.h" +#include "../OrthancException.h" + #include #include #include @@ -57,6 +59,21 @@ const char* username) const = 0; }; + + class IHttpExceptionFormatter + { + public: + virtual ~IHttpExceptionFormatter() + { + } + + virtual void Format(HttpOutput& output, + const OrthancException& exception, + HttpMethod method, + const char* uri) = 0; + }; + + class MongooseServer { private: @@ -77,7 +94,7 @@ IIncomingHttpRequestFilter* filter_; bool keepAlive_; bool httpCompression_; - bool describeErrors_; + IHttpExceptionFormatter* exceptionFormatter_; bool IsRunning() const; @@ -144,13 +161,6 @@ void SetHttpCompressionEnabled(bool enabled); - bool IsDescribeErrorsEnabled() const - { - return describeErrors_; - } - - void SetDescribeErrorsEnabled(bool enabled); - const IIncomingHttpRequestFilter* GetIncomingHttpRequestFilter() const { return filter_; @@ -170,5 +180,12 @@ } IHttpHandler& GetHandler() const; + + void SetHttpExceptionFormatter(IHttpExceptionFormatter& formatter); + + IHttpExceptionFormatter* GetExceptionFormatter() + { + return exceptionFormatter_; + } }; } diff -r 939b921b2c81 -r 1558b3226b18 OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Wed Sep 23 22:05:27 2015 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Thu Sep 24 15:55:17 2015 +0200 @@ -365,6 +365,8 @@ static void ModifyInstance(RestApiPostCall& call) { + throw OrthancException(ErrorCode_CannotStoreInstance); + DicomModification modification; modification.SetAllowManualIdentifiers(true); diff -r 939b921b2c81 -r 1558b3226b18 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Wed Sep 23 22:05:27 2015 +0200 +++ b/OrthancServer/main.cpp Thu Sep 24 15:55:17 2015 +0200 @@ -307,6 +307,67 @@ }; + +class MyHttpExceptionFormatter : public IHttpExceptionFormatter +{ +private: + bool describeErrors_; + OrthancPlugins* plugins_; + +public: + MyHttpExceptionFormatter(bool describeErrors, + OrthancPlugins* plugins) : + describeErrors_(describeErrors), + plugins_(plugins) + { + } + + virtual void Format(HttpOutput& output, + const OrthancException& exception, + HttpMethod method, + const char* uri) + { + if (!describeErrors_) + { + output.SendStatus(exception.GetHttpStatus()); + return; + } + + Json::Value message = Json::objectValue; + message["Method"] = EnumerationToString(method); + message["Uri"] = uri; + + ErrorCode errorCode = exception.GetErrorCode(); + HttpStatus httpStatus = exception.GetHttpStatus(); + + bool isPlugin = false; + +#if ORTHANC_PLUGINS_ENABLED == 1 + if (plugins_ != NULL && + plugins_->GetErrorDictionary().Format(message, httpStatus, exception)) + { + errorCode = ErrorCode_Plugin; + isPlugin = true; + } +#endif + + if (!isPlugin) + { + message["Message"] = exception.What(); + } + + message["HttpError"] = EnumerationToString(httpStatus); + message["HttpStatus"] = httpStatus; + message["OrthancError"] = EnumerationToString(errorCode); + message["OrthancStatus"] = errorCode; + + std::string info = message.toStyledString(); + output.SendStatus(httpStatus, info); + } +}; + + + static void PrintHelp(char* path) { std::cout @@ -413,7 +474,8 @@ static bool StartHttpServer(ServerContext& context, - OrthancRestApi& restApi) + OrthancRestApi& restApi, + OrthancPlugins* plugins) { if (!Configuration::GetGlobalBoolParameter("HttpServerEnabled", true)) { @@ -421,6 +483,9 @@ return WaitForExit(context, restApi); } + MyHttpExceptionFormatter exceptionFormatter(Configuration::GetGlobalBoolParameter("HttpDescribeErrors", true), plugins); + + // HTTP server MyIncomingHttpRequestFilter httpFilter(context); MongooseServer httpServer; @@ -428,8 +493,8 @@ httpServer.SetRemoteAccessAllowed(Configuration::GetGlobalBoolParameter("RemoteAccessAllowed", false)); httpServer.SetKeepAliveEnabled(Configuration::GetGlobalBoolParameter("KeepAlive", false)); httpServer.SetHttpCompressionEnabled(Configuration::GetGlobalBoolParameter("HttpCompressionEnabled", true)); - httpServer.SetDescribeErrorsEnabled(Configuration::GetGlobalBoolParameter("HttpDescribeErrors", true)); httpServer.SetIncomingHttpRequestFilter(httpFilter); + httpServer.SetHttpExceptionFormatter(exceptionFormatter); httpServer.SetAuthenticationEnabled(Configuration::GetGlobalBoolParameter("AuthenticationEnabled", false)); Configuration::SetupRegisteredUsers(httpServer); @@ -461,12 +526,13 @@ static bool StartDicomServer(ServerContext& context, - OrthancRestApi& restApi) + OrthancRestApi& restApi, + OrthancPlugins* plugins) { if (!Configuration::GetGlobalBoolParameter("DicomServerEnabled", true)) { LOG(WARNING) << "The DICOM server is disabled"; - return StartHttpServer(context, restApi); + return StartHttpServer(context, restApi, plugins); } MyDicomServerFactory serverFactory(context); @@ -485,7 +551,7 @@ dicomServer.Start(); LOG(WARNING) << "DICOM server listening on port: " << dicomServer.GetPortNumber(); - bool restart = StartHttpServer(context, restApi); + bool restart = StartHttpServer(context, restApi, plugins); dicomServer.Stop(); LOG(WARNING) << " DICOM server has stopped"; @@ -522,7 +588,7 @@ OrthancRestApi restApi(context); context.GetHttpHandler().Register(restApi, true); - return StartDicomServer(context, restApi); + return StartDicomServer(context, restApi, plugins); } diff -r 939b921b2c81 -r 1558b3226b18 Plugins/Engine/OrthancPlugins.h --- a/Plugins/Engine/OrthancPlugins.h Wed Sep 23 22:05:27 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Thu Sep 24 15:55:17 2015 +0200 @@ -42,14 +42,6 @@ { class OrthancPlugins : public boost::noncopyable { - private: - PluginsErrorDictionary dictionary_; - - public: - PluginsErrorDictionary& GetErrorDictionary() - { - return dictionary_; - } }; } diff -r 939b921b2c81 -r 1558b3226b18 Plugins/Engine/PluginsEnumerations.cpp --- a/Plugins/Engine/PluginsEnumerations.cpp Wed Sep 23 22:05:27 2015 +0200 +++ b/Plugins/Engine/PluginsEnumerations.cpp Thu Sep 24 15:55:17 2015 +0200 @@ -316,7 +316,7 @@ return ErrorCode_DatabaseNotInitialized; default: - return ErrorCode_Plugin; + return ErrorCode_InternalError; } } diff -r 939b921b2c81 -r 1558b3226b18 Plugins/Engine/PluginsErrorDictionary.cpp --- a/Plugins/Engine/PluginsErrorDictionary.cpp Wed Sep 23 22:05:27 2015 +0200 +++ b/Plugins/Engine/PluginsErrorDictionary.cpp Thu Sep 24 15:55:17 2015 +0200 @@ -38,6 +38,7 @@ #endif + #include "PluginsEnumerations.h" #include "PluginsManager.h" @@ -61,17 +62,17 @@ } - OrthancPluginErrorCode PluginsErrorDictionary::Register(SharedLibrary& library, - int32_t pluginCode, - const char* description, - uint16_t httpStatus) + OrthancPluginErrorCode PluginsErrorDictionary::Register(const std::string& pluginName, + int32_t pluginCode, + uint16_t httpStatus, + const char* description) { std::auto_ptr error(new Error); + error->pluginName_ = pluginName; error->pluginCode_ = pluginCode; error->description_ = description; error->httpStatus_ = static_cast(httpStatus); - error->pluginName_ = PluginsManager::GetPluginName(library); OrthancPluginErrorCode code; @@ -86,12 +87,10 @@ } - void PluginsErrorDictionary::GetExceptionMessage(Json::Value& message, /* out */ - HttpStatus& httpStatus, /* out */ - const OrthancException& exception) + bool PluginsErrorDictionary::Format(Json::Value& message, /* out */ + HttpStatus& httpStatus, /* out */ + const OrthancException& exception) { - bool done = false; - if (exception.GetErrorCode() >= ErrorCode_START_PLUGINS) { boost::mutex::scoped_lock lock(mutex_); @@ -104,20 +103,10 @@ message["PluginCode"] = error->second->pluginCode_; message["Message"] = error->second->description_; - done = true; + return true; } } - if (!done) - { - httpStatus = exception.GetHttpStatus(); - message["Message"] = exception.What(); - } - - message["HttpError"] = EnumerationToString(httpStatus); - message["HttpStatus"] = httpStatus; - message["OrthancError"] = EnumerationToString(exception.GetErrorCode()); - message["OrthancStatus"] = exception.GetErrorCode(); + return false; } - } diff -r 939b921b2c81 -r 1558b3226b18 Plugins/Engine/PluginsErrorDictionary.h --- a/Plugins/Engine/PluginsErrorDictionary.h Wed Sep 23 22:05:27 2015 +0200 +++ b/Plugins/Engine/PluginsErrorDictionary.h Thu Sep 24 15:55:17 2015 +0200 @@ -36,7 +36,6 @@ #include "../Include/orthanc/OrthancCPlugin.h" #include "../../Core/OrthancException.h" -#include "SharedLibrary.h" #include #include @@ -52,10 +51,10 @@ private: struct Error { + std::string pluginName_; int32_t pluginCode_; + HttpStatus httpStatus_; std::string description_; - HttpStatus httpStatus_; - std::string pluginName_; }; typedef std::map Errors; @@ -69,14 +68,14 @@ ~PluginsErrorDictionary(); - OrthancPluginErrorCode Register(SharedLibrary& library, + OrthancPluginErrorCode Register(const std::string& pluginName, int32_t pluginCode, - const char* description, - uint16_t httpStatus); + uint16_t httpStatus, + const char* description); - void GetExceptionMessage(Json::Value& message, /* out */ - HttpStatus& httpStatus, /* out */ - const OrthancException& exception); + bool Format(Json::Value& message, /* out */ + HttpStatus& httpStatus, /* out */ + const OrthancException& exception); }; }