Properly encode URLs in Icinga Studio

fixes #10241
This commit is contained in:
Gunnar Beutner 2015-09-30 14:02:18 +02:00
parent f3fdcb0f6b
commit f779b20ec0
4 changed files with 43 additions and 15 deletions

View File

@ -36,7 +36,15 @@ ApiClient::ApiClient(const String& host, const String& port,
void ApiClient::GetTypes(const TypesCompletionCallback& callback) const void ApiClient::GetTypes(const TypesCompletionCallback& callback) const
{ {
Url::Ptr url = new Url("https://" + m_Connection->GetHost() + ":" + m_Connection->GetPort() + "/v1/types"); Url::Ptr url = new Url();
url->SetScheme("https");
url->SetHost(m_Connection->GetHost());
url->SetPort(m_Connection->GetPort());
std::vector<String> path;
path.push_back("v1");
path.push_back("types");
url->SetPath(path);
try { try {
boost::shared_ptr<HttpRequest> req = m_Connection->NewRequest(); boost::shared_ptr<HttpRequest> req = m_Connection->NewRequest();
@ -98,29 +106,34 @@ void ApiClient::TypesHttpCompletionCallback(HttpRequest& request, HttpResponse&
void ApiClient::GetObjects(const String& pluralType, const ObjectsCompletionCallback& callback, void ApiClient::GetObjects(const String& pluralType, const ObjectsCompletionCallback& callback,
const std::vector<String>& names, const std::vector<String>& attrs) const const std::vector<String>& names, const std::vector<String>& attrs) const
{ {
String url = "https://" + m_Connection->GetHost() + ":" + m_Connection->GetPort() + "/v1/objects/" + pluralType; Url::Ptr url = new Url();
url->SetScheme("https");
url->SetHost(m_Connection->GetHost());
url->SetPort(m_Connection->GetPort());
std::vector<String> path;
path.push_back("v1");
path.push_back("objects");
path.push_back(pluralType);
url->SetPath(path);
String qp; String qp;
BOOST_FOREACH(const String& name, names) { std::map<String, std::vector<String> > params;
if (!qp.IsEmpty())
qp += "&";
qp += pluralType.ToLower() + "=" + name; BOOST_FOREACH(const String& name, names) {
params[pluralType.ToLower()].push_back(name);
} }
BOOST_FOREACH(const String& attr, attrs) { BOOST_FOREACH(const String& attr, attrs) {
if (!qp.IsEmpty()) params["attrs"].push_back(attr);
qp += "&";
qp += "attrs[]=" + attr;
} }
Url::Ptr pUrl = new Url(url + "?" + qp); url->SetQuery(params);
try { try {
boost::shared_ptr<HttpRequest> req = m_Connection->NewRequest(); boost::shared_ptr<HttpRequest> req = m_Connection->NewRequest();
req->RequestMethod = "GET"; req->RequestMethod = "GET";
req->RequestUrl = pUrl; req->RequestUrl = url;
req->AddHeader("Authorization", "Basic " + Base64::Encode(m_User + ":" + m_Password)); req->AddHeader("Authorization", "Basic " + Base64::Encode(m_User + ":" + m_Password));
m_Connection->SubmitRequest(req, boost::bind(ObjectsHttpCompletionCallback, _1, _2, callback)); m_Connection->SubmitRequest(req, boost::bind(ObjectsHttpCompletionCallback, _1, _2, callback));
} catch (const std::exception& ex) { } catch (const std::exception& ex) {

View File

@ -16,6 +16,7 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef URL_CHARACTERS_H #ifndef URL_CHARACTERS_H
#define URL_CHARACTERS_H #define URL_CHARACTERS_H

View File

@ -27,7 +27,8 @@
using namespace icinga; using namespace icinga;
Url::Url() {} Url::Url()
{ }
Url::Url(const String& base_url) Url::Url(const String& base_url)
{ {
@ -170,6 +171,7 @@ String Url::GetFragment(void) const
{ {
return m_Fragment; return m_Fragment;
} }
void Url::SetScheme(const String& scheme) void Url::SetScheme(const String& scheme)
{ {
m_Scheme = scheme; m_Scheme = scheme;
@ -183,6 +185,16 @@ void Url::SetAuthority(const String& username, const String& password, const Str
m_Port = port; m_Port = port;
} }
void Url::SetHost(const String& host)
{
m_Host = host;
}
void Url::SetPort(const String& port)
{
m_Port = port;
}
void Url::SetPath(const std::vector<String>& path) void Url::SetPath(const std::vector<String>& path)
{ {
m_Path = path; m_Path = path;
@ -227,9 +239,9 @@ String Url::Format(bool print_credentials) const
if (m_Path.empty()) if (m_Path.empty())
url += "/"; url += "/";
else { else {
BOOST_FOREACH (const String p, m_Path) { BOOST_FOREACH (const String& segment, m_Path) {
url += "/"; url += "/";
url += Utility::EscapeString(p, ACPATHSEGMENT, false); url += Utility::EscapeString(segment, ACPATHSEGMENT, false);
} }
} }

View File

@ -61,6 +61,8 @@ public:
void SetScheme(const String& scheme); void SetScheme(const String& scheme);
void SetAuthority(const String& username, const String& password, void SetAuthority(const String& username, const String& password,
const String& host, const String& port); const String& host, const String& port);
void SetHost(const String& host);
void SetPort(const String& port);
void SetPath(const std::vector<String>& path); void SetPath(const std::vector<String>& path);
void SetQuery(const std::map<String, std::vector<String> >& query); void SetQuery(const std::map<String, std::vector<String> >& query);
void AddQueryElement(const String& name, const String& query); void AddQueryElement(const String& name, const String& query);