Mercurial > hg > orthanc
diff Core/WebServiceParameters.cpp @ 2800:dc7330089736
"OrthancPeers" configuration option now allows to specify HTTP headers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 23 Aug 2018 13:11:48 +0200 |
parents | d67298eec14e |
children | 807169f85ba9 |
line wrap: on
line diff
--- a/Core/WebServiceParameters.cpp Wed Aug 22 16:55:07 2018 +0200 +++ b/Core/WebServiceParameters.cpp Thu Aug 23 13:11:48 2018 +0200 @@ -37,20 +37,31 @@ #include "Logging.h" #include "OrthancException.h" #include "SerializationToolbox.h" +#include "Toolbox.h" #if ORTHANC_SANDBOXED == 0 -# include "../Core/SystemToolbox.h" +# include "SystemToolbox.h" #endif #include <cassert> namespace Orthanc { + static const char* KEY_CERTIFICATE_FILE = "CertificateFile"; + static const char* KEY_CERTIFICATE_KEY_FILE = "CertificateKeyFile"; + static const char* KEY_CERTIFICATE_KEY_PASSWORD = "CertificateKeyPassword"; + static const char* KEY_HTTP_HEADERS = "HttpHeaders"; + static const char* KEY_PASSWORD = "Password"; + static const char* KEY_PKCS11 = "Pkcs11"; + static const char* KEY_URL = "Url"; + static const char* KEY_URL_2 = "URL"; + static const char* KEY_USERNAME = "Username"; + + WebServiceParameters::WebServiceParameters() : - advancedFormat_(false), - url_("http://127.0.0.1:8042/"), pkcs11Enabled_(false) { + SetUrl("http://127.0.0.1:8042/"); } @@ -62,7 +73,50 @@ } -#if ORTHANC_SANDBOXED == 0 + void WebServiceParameters::SetUrl(const std::string& url) + { + if (!Toolbox::StartsWith(url, "http://") && + !Toolbox::StartsWith(url, "https://")) + { + LOG(ERROR) << "Bad URL: " << url; + throw OrthancException(ErrorCode_BadFileFormat); + } + + // Add trailing slash if needed + if (url[url.size() - 1] == '/') + { + url_ = url; + } + else + { + url_ = url + '/'; + } + } + + + void WebServiceParameters::ClearCredentials() + { + username_.clear(); + password_.clear(); + } + + + void WebServiceParameters::SetCredentials(const std::string& username, + const std::string& password) + { + if (username.empty() && + !password.empty()) + { + throw OrthancException(ErrorCode_BadFileFormat); + } + else + { + username_ = username; + password_ = password; + } + } + + void WebServiceParameters::SetClientCertificate(const std::string& certificateFile, const std::string& certificateKeyFile, const std::string& certificateKeyPassword) @@ -72,43 +126,24 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } - if (!SystemToolbox::IsRegularFile(certificateFile)) + if (certificateKeyPassword.empty()) { - LOG(ERROR) << "Cannot open certificate file: " << certificateFile; - throw OrthancException(ErrorCode_InexistentFile); + LOG(ERROR) << "The password for the HTTPS certificate is not provided: " << certificateFile; + throw OrthancException(ErrorCode_BadFileFormat); } - if (!certificateKeyFile.empty() && - !SystemToolbox::IsRegularFile(certificateKeyFile)) - { - LOG(ERROR) << "Cannot open key file: " << certificateKeyFile; - throw OrthancException(ErrorCode_InexistentFile); - } - - advancedFormat_ = true; certificateFile_ = certificateFile; certificateKeyFile_ = certificateKeyFile; certificateKeyPassword_ = certificateKeyPassword; } -#endif - static void AddTrailingSlash(std::string& url) - { - if (url.size() != 0 && - url[url.size() - 1] != '/') - { - url += '/'; - } - } - - - void WebServiceParameters::FromJsonArray(const Json::Value& peer) + void WebServiceParameters::FromSimpleFormat(const Json::Value& peer) { assert(peer.isArray()); - advancedFormat_ = false; pkcs11Enabled_ = false; + ClearClientCertificate(); if (peer.size() != 1 && peer.size() != 3) @@ -116,19 +151,11 @@ throw OrthancException(ErrorCode_BadFileFormat); } - std::string url = peer.get(0u, "").asString(); - if (url.empty()) - { - throw OrthancException(ErrorCode_BadFileFormat); - } - - AddTrailingSlash(url); - SetUrl(url); + SetUrl(peer.get(0u, "").asString()); if (peer.size() == 1) { - SetUsername(""); - SetPassword(""); + ClearCredentials(); } else if (peer.size() == 2) { @@ -137,8 +164,8 @@ } else if (peer.size() == 3) { - SetUsername(peer.get(1u, "").asString()); - SetPassword(peer.get(2u, "").asString()); + SetCredentials(peer.get(1u, "").asString(), + peer.get(2u, "").asString()); } else { @@ -166,70 +193,90 @@ } - void WebServiceParameters::FromJsonObject(const Json::Value& peer) + void WebServiceParameters::FromAdvancedFormat(const Json::Value& peer) { assert(peer.isObject()); - advancedFormat_ = true; - std::string url = GetStringMember(peer, "Url", ""); + std::string url = GetStringMember(peer, KEY_URL, ""); if (url.empty()) { - throw OrthancException(ErrorCode_BadFileFormat); + SetUrl(GetStringMember(peer, KEY_URL_2, "")); + } + else + { + SetUrl(url); } - AddTrailingSlash(url); - SetUrl(url); - - SetUsername(GetStringMember(peer, "Username", "")); - SetPassword(GetStringMember(peer, "Password", "")); + SetCredentials(GetStringMember(peer, KEY_USERNAME, ""), + GetStringMember(peer, KEY_PASSWORD, "")); - if (!username_.empty() && - !peer.isMember("Password")) + std::string file = GetStringMember(peer, KEY_CERTIFICATE_FILE, ""); + if (!file.empty()) { - LOG(ERROR) << "The HTTP password is not provided"; - throw OrthancException(ErrorCode_BadFileFormat); + SetClientCertificate(file, GetStringMember(peer, KEY_CERTIFICATE_KEY_FILE, ""), + GetStringMember(peer, KEY_CERTIFICATE_KEY_PASSWORD, "")); + } + else + { + ClearClientCertificate(); } -#if ORTHANC_SANDBOXED == 0 - if (peer.isMember("CertificateFile")) + if (peer.isMember(KEY_PKCS11)) { - SetClientCertificate(GetStringMember(peer, "CertificateFile", ""), - GetStringMember(peer, "CertificateKeyFile", ""), - GetStringMember(peer, "CertificateKeyPassword", "")); - - if (!peer.isMember("CertificateKeyPassword")) + if (peer[KEY_PKCS11].type() == Json::booleanValue) { - LOG(ERROR) << "The password for the HTTPS certificate is not provided"; - throw OrthancException(ErrorCode_BadFileFormat); - } - } -#endif - - if (peer.isMember("Pkcs11")) - { - if (peer["Pkcs11"].type() == Json::booleanValue) - { - pkcs11Enabled_ = peer["Pkcs11"].asBool(); + pkcs11Enabled_ = peer[KEY_PKCS11].asBool(); } else { throw OrthancException(ErrorCode_BadFileFormat); } } + else + { + pkcs11Enabled_ = false; + } + + headers_.clear(); + + if (peer.isMember(KEY_HTTP_HEADERS)) + { + const Json::Value& h = peer[KEY_HTTP_HEADERS]; + if (h.type() != Json::objectValue) + { + throw OrthancException(ErrorCode_BadFileFormat); + } + else + { + Json::Value::Members keys = h.getMemberNames(); + for (size_t i = 0; i < keys.size(); i++) + { + const Json::Value& value = h[keys[i]]; + if (value.type() != Json::stringValue) + { + throw OrthancException(ErrorCode_BadFileFormat); + } + else + { + headers_[keys[i]] = value.asString(); + } + } + } + } } - void WebServiceParameters::FromJson(const Json::Value& peer) + void WebServiceParameters::Unserialize(const Json::Value& peer) { try { if (peer.isArray()) { - FromJsonArray(peer); + FromSimpleFormat(peer); } else if (peer.isObject()) { - FromJsonObject(peer); + FromAdvancedFormat(peer); } else { @@ -247,39 +294,89 @@ } - void WebServiceParameters::ToJson(Json::Value& value, - bool includePasswords) const + void WebServiceParameters::ListHttpHeaders(std::set<std::string>& target) const + { + target.clear(); + + for (HttpHeaders::const_iterator it = headers_.begin(); + it != headers_.end(); ++it) + { + target.insert(it->first); + } + } + + + bool WebServiceParameters::LookupHttpHeader(std::string& value, + const std::string& key) const { - if (advancedFormat_) + HttpHeaders::const_iterator found = headers_.find(key); + + if (found == headers_.end()) + { + return false; + } + else + { + value = found->second; + return true; + } + } + + + bool WebServiceParameters::IsAdvancedFormatNeeded() const + { + return (!certificateFile_.empty() || + !certificateKeyFile_.empty() || + !certificateKeyPassword_.empty() || + pkcs11Enabled_ || + !headers_.empty()); + } + + + void WebServiceParameters::Serialize(Json::Value& value, + bool forceAdvancedFormat, + bool includePasswords) const + { + if (forceAdvancedFormat || + IsAdvancedFormatNeeded()) { value = Json::objectValue; - value["Url"] = url_; + value[KEY_URL] = url_; if (!username_.empty() || !password_.empty()) { - value["Username"] = username_; + value[KEY_USERNAME] = username_; if (includePasswords) { - value["Password"] = password_; + value[KEY_PASSWORD] = password_; } } if (!certificateFile_.empty()) { - value["CertificateFile"] = certificateFile_; + value[KEY_CERTIFICATE_FILE] = certificateFile_; } if (!certificateKeyFile_.empty()) { - value["CertificateKeyFile"] = certificateKeyFile_; + value[KEY_CERTIFICATE_KEY_FILE] = certificateKeyFile_; } if (!certificateKeyPassword_.empty() && includePasswords) { - value["CertificateKeyPassword"] = certificateKeyPassword_; + value[KEY_CERTIFICATE_KEY_PASSWORD] = certificateKeyPassword_; + } + + value[KEY_PKCS11] = pkcs11Enabled_; + + value[KEY_HTTP_HEADERS] = Json::objectValue; + for (HttpHeaders::const_iterator it = headers_.begin(); + it != headers_.end(); ++it) + { + value[KEY_HTTP_HEADERS][it->first] = it->second; } } else @@ -291,50 +388,30 @@ !password_.empty()) { value.append(username_); - - if (includePasswords) - { - value.append(password_); - } + value.append(includePasswords ? password_ : ""); } } } - - void WebServiceParameters::Serialize(Json::Value& target) const - { - target = Json::objectValue; - target["URL"] = url_; - target["Username"] = username_; - target["Password"] = password_; - target["CertificateFile"] = certificateFile_; - target["CertificateKeyFile"] = certificateKeyFile_; - target["CertificateKeyPassword"] = certificateKeyPassword_; - target["PKCS11"] = pkcs11Enabled_; - target["AdvancedFormat"] = advancedFormat_; - } - #if ORTHANC_SANDBOXED == 0 - WebServiceParameters::WebServiceParameters(const Json::Value& serialized) : - advancedFormat_(true) + void WebServiceParameters::CheckClientCertificate() const { - url_ = SerializationToolbox::ReadString(serialized, "URL"); - username_ = SerializationToolbox::ReadString(serialized, "Username"); - password_ = SerializationToolbox::ReadString(serialized, "Password"); + if (!certificateFile_.empty()) + { + if (!SystemToolbox::IsRegularFile(certificateFile_)) + { + LOG(ERROR) << "Cannot open certificate file: " << certificateFile_; + throw OrthancException(ErrorCode_InexistentFile); + } - std::string a, b, c; - a = SerializationToolbox::ReadString(serialized, "CertificateFile"); - b = SerializationToolbox::ReadString(serialized, "CertificateKeyFile"); - c = SerializationToolbox::ReadString(serialized, "CertificateKeyPassword"); - - if (!a.empty()) - { - SetClientCertificate(a, b, c); + if (!certificateKeyFile_.empty() && + !SystemToolbox::IsRegularFile(certificateKeyFile_)) + { + LOG(ERROR) << "Cannot open key file: " << certificateKeyFile_; + throw OrthancException(ErrorCode_InexistentFile); + } } - - pkcs11Enabled_ = SerializationToolbox::ReadBoolean(serialized, "PKCS11"); - advancedFormat_ = SerializationToolbox::ReadBoolean(serialized, "AdvancedFormat"); } #endif }