# HG changeset patch # User Sebastien Jodogne # Date 1466521689 -7200 # Node ID 9f61ca1e3eb3bdaed9d80326b5f593fdcb584b55 # Parent 6ea2e264ca50719fa1ddc6ba7e728b4610008b21 OrthancPluginHttpClient can return the HTTP headers of the answer diff -r 6ea2e264ca50 -r 9f61ca1e3eb3 Core/HttpClient.cpp --- a/Core/HttpClient.cpp Tue Jun 21 16:34:30 2016 +0200 +++ b/Core/HttpClient.cpp Tue Jun 21 17:08:09 2016 +0200 @@ -388,13 +388,13 @@ } - bool HttpClient::ApplyInternal(std::string& answer, - HttpHeaders* headers) + bool HttpClient::ApplyInternal(std::string& answerBody, + HttpHeaders* answerHeaders) { - answer.clear(); + answerBody.clear(); CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_URL, url_.c_str())); - if (headers == NULL) + if (answerHeaders == NULL) { CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERFUNCTION, NULL)); CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, NULL)); @@ -402,7 +402,7 @@ else { CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERFUNCTION, &CurlHeaderCallback)); - CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, headers)); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, answerHeaders)); } #if ORTHANC_SSL_ENABLED == 1 @@ -593,11 +593,11 @@ if (success) { - buffer.Flatten(answer); + buffer.Flatten(answerBody); } else { - answer.clear(); + answerBody.clear(); LOG(INFO) << "Error in HTTP request, received HTTP status " << status << " (" << EnumerationToString(lastStatus_) << ")"; } @@ -606,14 +606,14 @@ } - bool HttpClient::ApplyInternal(Json::Value& answer, + bool HttpClient::ApplyInternal(Json::Value& answerBody, HttpClient::HttpHeaders* answerHeaders) { std::string s; if (ApplyInternal(s, answerHeaders)) { Json::Reader reader; - return reader.parse(s, answer); + return reader.parse(s, answerBody); } else { @@ -689,17 +689,38 @@ } - void HttpClient::ApplyAndThrowException(std::string& answer) + void HttpClient::ApplyAndThrowException(std::string& answerBody) + { + if (!Apply(answerBody)) + { + ThrowException(GetLastStatus()); + } + } + + + void HttpClient::ApplyAndThrowException(Json::Value& answerBody) { - if (!Apply(answer)) + if (!Apply(answerBody)) + { + ThrowException(GetLastStatus()); + } + } + + + void HttpClient::ApplyAndThrowException(std::string& answerBody, + HttpHeaders& answerHeaders) + { + if (!Apply(answerBody, answerHeaders)) { ThrowException(GetLastStatus()); } } - void HttpClient::ApplyAndThrowException(Json::Value& answer) + + void HttpClient::ApplyAndThrowException(Json::Value& answerBody, + HttpHeaders& answerHeaders) { - if (!Apply(answer)) + if (!Apply(answerBody, answerHeaders)) { ThrowException(GetLastStatus()); } diff -r 6ea2e264ca50 -r 9f61ca1e3eb3 Core/HttpClient.h --- a/Core/HttpClient.h Tue Jun 21 16:34:30 2016 +0200 +++ b/Core/HttpClient.h Tue Jun 21 17:08:09 2016 +0200 @@ -72,10 +72,10 @@ void operator= (const HttpClient&); // Assignment forbidden HttpClient(const HttpClient& base); // Copy forbidden - bool ApplyInternal(std::string& answer, + bool ApplyInternal(std::string& answerBody, HttpHeaders* answerHeaders); - bool ApplyInternal(Json::Value& answer, + bool ApplyInternal(Json::Value& answerBody, HttpHeaders* answerHeaders); public: @@ -148,26 +148,26 @@ void ClearHeaders(); - bool Apply(std::string& answer) + bool Apply(std::string& answerBody) { - return ApplyInternal(answer, NULL); + return ApplyInternal(answerBody, NULL); } - bool Apply(Json::Value& answer) + bool Apply(Json::Value& answerBody) { - return ApplyInternal(answer, NULL); + return ApplyInternal(answerBody, NULL); } - bool Apply(std::string& answer, + bool Apply(std::string& answerBody, HttpHeaders& answerHeaders) { - return ApplyInternal(answer, &answerHeaders); + return ApplyInternal(answerBody, &answerHeaders); } - bool Apply(Json::Value& answer, + bool Apply(Json::Value& answerBody, HttpHeaders& answerHeaders) { - return ApplyInternal(answer, &answerHeaders); + return ApplyInternal(answerBody, &answerHeaders); } HttpStatus GetLastStatus() const @@ -247,8 +247,14 @@ static void SetDefaultTimeout(long timeout); - void ApplyAndThrowException(std::string& answer); + void ApplyAndThrowException(std::string& answerBody); + + void ApplyAndThrowException(Json::Value& answerBody); - void ApplyAndThrowException(Json::Value& answer); + void ApplyAndThrowException(std::string& answerBody, + HttpHeaders& answerHeaders); + + void ApplyAndThrowException(Json::Value& answerBody, + HttpHeaders& answerHeaders); }; } diff -r 6ea2e264ca50 -r 9f61ca1e3eb3 Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Tue Jun 21 16:34:30 2016 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Tue Jun 21 17:08:09 2016 +0200 @@ -1811,7 +1811,7 @@ client.SetClientCertificate(certificate, key, password); } - client.SetPkcs11Enabled(p.pkcs11 ? true : false); + client.SetPkcs11Enabled(p.pkcs11 ? true : false); for (uint32_t i = 0; i < p.headersCount; i++) { @@ -1848,19 +1848,33 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } - std::string s; - - if (!client.Apply(s)) + std::string body; + HttpClient::HttpHeaders headers; + + client.ApplyAndThrowException(body, headers); + + // The HTTP request has succeeded + *p.httpStatus = static_cast(client.GetLastStatus()); + + // Copy the HTTP headers of the answer, if the plugin requested them + if (p.answerHeaders != NULL) { - *p.httpStatus = 0; - throw OrthancException(ErrorCode_NetworkProtocol); + Json::Value json = Json::objectValue; + + for (HttpClient::HttpHeaders::const_iterator + it = headers.begin(); it != headers.end(); ++it) + { + json[it->first] = it->second; + } + + std::string s = json.toStyledString(); + CopyToMemoryBuffer(*p.answerHeaders, s); } - *p.httpStatus = static_cast(client.GetLastStatus()); - + // Copy the body of the answer if it makes sense if (p.method != OrthancPluginHttpMethod_Delete) { - CopyToMemoryBuffer(*p.target, s); + CopyToMemoryBuffer(*p.answerBody, body); } } diff -r 6ea2e264ca50 -r 9f61ca1e3eb3 Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Tue Jun 21 16:34:30 2016 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Tue Jun 21 17:08:09 2016 +0200 @@ -4931,7 +4931,8 @@ typedef struct { - OrthancPluginMemoryBuffer* target; + OrthancPluginMemoryBuffer* answerBody; + OrthancPluginMemoryBuffer* answerHeaders; uint16_t* httpStatus; OrthancPluginHttpMethod method; const char* url; @@ -4955,10 +4956,19 @@ * @brief Issue a HTTP call with full flexibility. * * Make a HTTP call to the given URL. The result to the query is - * stored into a newly allocated memory buffer. + * stored into a newly allocated memory buffer. The HTTP request + * will be done accordingly to the global configuration of Orthanc + * (in particular, the options "HttpProxy", "HttpTimeout", + * "HttpsVerifyPeers", "HttpsCACertificates", and "Pkcs11" will be + * taken into account). * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). - * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer() (out argument). + * @param answerBody The target memory buffer (out argument). + * It must be freed with OrthancPluginFreeMemoryBuffer(). + * @param answerHeaders The target memory buffer for the HTTP headers in the answers (out argument). + * The answer headers are formatted as a JSON object (associative array). + * The buffer must be freed with OrthancPluginFreeMemoryBuffer(). + * This argument can be set to NULL if the plugin has no interest in the HTTP headers. * @param httpStatus The HTTP status after the execution of the request (out argument). * @param method HTTP method to be used. * @param url The URL of interest. @@ -4981,7 +4991,8 @@ **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginHttpClient( OrthancPluginContext* context, - OrthancPluginMemoryBuffer* target, + OrthancPluginMemoryBuffer* answerBody, + OrthancPluginMemoryBuffer* answerHeaders, uint16_t* httpStatus, OrthancPluginHttpMethod method, const char* url, @@ -5001,7 +5012,8 @@ _OrthancPluginCallHttpClient2 params; memset(¶ms, 0, sizeof(params)); - params.target = target; + params.answerBody = answerBody; + params.answerHeaders = answerHeaders; params.httpStatus = httpStatus; params.method = method; params.url = url;