Adjust all HTTP handlers (ex. /v1/events)

This commit is contained in:
Alexander A. Klimov 2019-02-15 10:33:01 +01:00
parent 9ae1d732af
commit 1941c1da28
30 changed files with 461 additions and 180 deletions

View File

@ -12,15 +12,23 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/actions", ActionsHandler);
bool ActionsHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool ActionsHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() != 3)
namespace http = boost::beast::http;
if (url->GetPath().size() != 3)
return false;
if (request.RequestMethod != "POST")
if (request.method() != http::verb::post)
return false;
String actionName = request.RequestUrl->GetPath()[2];
String actionName = url->GetPath()[2];
ApiAction::Ptr action = ApiAction::GetByName(actionName);
@ -81,17 +89,15 @@ bool ActionsHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& reques
}
int statusCode = 500;
String statusMessage = "No action executed successfully";
for (const Dictionary::Ptr& res : results) {
if (res->Contains("code") && res->Get("code") == 200) {
statusCode = 200;
statusMessage = "OK";
break;
}
}
response.SetStatus(statusCode, statusMessage);
response.result(statusCode);
Dictionary::Ptr result = new Dictionary({
{ "results", new Array(std::move(results)) }

View File

@ -13,8 +13,13 @@ class ActionsHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(ActionsHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -12,12 +12,20 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/config/files", ConfigFilesHandler);
bool ConfigFilesHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool ConfigFilesHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestMethod != "GET")
namespace http = boost::beast::http;
if (request.method() != http::verb::get)
return false;
const std::vector<String>& urlPath = request.RequestUrl->GetPath();
const std::vector<String>& urlPath = url->GetPath();
if (urlPath.size() >= 4)
params->Set("package", urlPath[3]);
@ -30,7 +38,7 @@ bool ConfigFilesHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& re
params->Set("path", boost::algorithm::join(tmpPath, "/"));
}
if (request.Headers->Get("accept") == "application/json") {
if (request[http::field::accept] == "application/json") {
HttpUtility::SendJsonError(response, params, 400, "Invalid Accept header. Either remove the Accept header or set it to 'application/octet-stream'.");
return true;
}
@ -69,9 +77,10 @@ bool ConfigFilesHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& re
fp.exceptions(std::ifstream::badbit);
String content((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
response.SetStatus(200, "OK");
response.AddHeader("Content-Type", "application/octet-stream");
response.WriteBody(content.CStr(), content.GetLength());
response.result(http::status::ok);
response.set(http::field::content_type, "application/octet-stream");
response.body() = content;
response.set(http::field::content_length, response.body().size());
} catch (const std::exception& ex) {
HttpUtility::SendJsonError(response, params, 500, "Could not read file.",
DiagnosticInformation(ex));

View File

@ -13,8 +13,13 @@ class ConfigFilesHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(ConfigFilesHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -10,25 +10,41 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/config/packages", ConfigPackagesHandler);
bool ConfigPackagesHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool ConfigPackagesHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() > 4)
namespace http = boost::beast::http;
if (url->GetPath().size() > 4)
return false;
if (request.RequestMethod == "GET")
HandleGet(user, request, response, params);
else if (request.RequestMethod == "POST")
HandlePost(user, request, response, params);
else if (request.RequestMethod == "DELETE")
HandleDelete(user, request, response, params);
if (request.method() == http::verb::get)
HandleGet(user, request, url, response, params);
else if (request.method() == http::verb::post)
HandlePost(user, request, url, response, params);
else if (request.method() == http::verb::delete_)
HandleDelete(user, request, url, response, params);
else
return false;
return true;
}
void ConfigPackagesHandler::HandleGet(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
void ConfigPackagesHandler::HandleGet(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
namespace http = boost::beast::http;
FilterUtility::CheckPermission(user, "config/query");
std::vector<String> packages;
@ -58,16 +74,24 @@ void ConfigPackagesHandler::HandleGet(const ApiUser::Ptr& user, HttpRequest& req
{ "results", new Array(std::move(results)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
}
void ConfigPackagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
void ConfigPackagesHandler::HandlePost(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
namespace http = boost::beast::http;
FilterUtility::CheckPermission(user, "config/modify");
if (request.RequestUrl->GetPath().size() >= 4)
params->Set("package", request.RequestUrl->GetPath()[3]);
if (url->GetPath().size() >= 4)
params->Set("package", url->GetPath()[3]);
String packageName = HttpUtility::GetLastParameter(params, "package");
@ -95,16 +119,24 @@ void ConfigPackagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& re
{ "results", new Array({ result1 }) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
}
void ConfigPackagesHandler::HandleDelete(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
void ConfigPackagesHandler::HandleDelete(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
namespace http = boost::beast::http;
FilterUtility::CheckPermission(user, "config/modify");
if (request.RequestUrl->GetPath().size() >= 4)
params->Set("package", request.RequestUrl->GetPath()[3]);
if (url->GetPath().size() >= 4)
params->Set("package", url->GetPath()[3]);
String packageName = HttpUtility::GetLastParameter(params, "package");
@ -131,6 +163,6 @@ void ConfigPackagesHandler::HandleDelete(const ApiUser::Ptr& user, HttpRequest&
{ "results", new Array({ result1 }) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
}

View File

@ -13,16 +13,36 @@ class ConfigPackagesHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(ConfigPackagesHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
private:
void HandleGet(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params);
void HandlePost(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params);
void HandleDelete(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params);
void HandleGet(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
);
void HandlePost(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
);
void HandleDelete(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
);
};

View File

@ -11,32 +11,48 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/config/stages", ConfigStagesHandler);
bool ConfigStagesHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool ConfigStagesHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() > 5)
namespace http = boost::beast::http;
if (url->GetPath().size() > 5)
return false;
if (request.RequestMethod == "GET")
HandleGet(user, request, response, params);
else if (request.RequestMethod == "POST")
HandlePost(user, request, response, params);
else if (request.RequestMethod == "DELETE")
HandleDelete(user, request, response, params);
if (request.method() == http::verb::get)
HandleGet(user, request, url, response, params);
else if (request.method() == http::verb::post)
HandlePost(user, request, url, response, params);
else if (request.method() == http::verb::delete_)
HandleDelete(user, request, url, response, params);
else
return false;
return true;
}
void ConfigStagesHandler::HandleGet(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
void ConfigStagesHandler::HandleGet(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
namespace http = boost::beast::http;
FilterUtility::CheckPermission(user, "config/query");
if (request.RequestUrl->GetPath().size() >= 4)
params->Set("package", request.RequestUrl->GetPath()[3]);
if (url->GetPath().size() >= 4)
params->Set("package", url->GetPath()[3]);
if (request.RequestUrl->GetPath().size() >= 5)
params->Set("stage", request.RequestUrl->GetPath()[4]);
if (url->GetPath().size() >= 5)
params->Set("stage", url->GetPath()[4]);
String packageName = HttpUtility::GetLastParameter(params, "package");
String stageName = HttpUtility::GetLastParameter(params, "stage");
@ -64,16 +80,24 @@ void ConfigStagesHandler::HandleGet(const ApiUser::Ptr& user, HttpRequest& reque
{ "results", new Array(std::move(results)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
}
void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
void ConfigStagesHandler::HandlePost(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
namespace http = boost::beast::http;
FilterUtility::CheckPermission(user, "config/modify");
if (request.RequestUrl->GetPath().size() >= 4)
params->Set("package", request.RequestUrl->GetPath()[3]);
if (url->GetPath().size() >= 4)
params->Set("package", url->GetPath()[3]);
String packageName = HttpUtility::GetLastParameter(params, "package");
@ -123,19 +147,27 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
{ "results", new Array({ result1 }) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
}
void ConfigStagesHandler::HandleDelete(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
void ConfigStagesHandler::HandleDelete(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
namespace http = boost::beast::http;
FilterUtility::CheckPermission(user, "config/modify");
if (request.RequestUrl->GetPath().size() >= 4)
params->Set("package", request.RequestUrl->GetPath()[3]);
if (url->GetPath().size() >= 4)
params->Set("package", url->GetPath()[3]);
if (request.RequestUrl->GetPath().size() >= 5)
params->Set("stage", request.RequestUrl->GetPath()[4]);
if (url->GetPath().size() >= 5)
params->Set("stage", url->GetPath()[4]);
String packageName = HttpUtility::GetLastParameter(params, "package");
String stageName = HttpUtility::GetLastParameter(params, "stage");
@ -165,7 +197,7 @@ void ConfigStagesHandler::HandleDelete(const ApiUser::Ptr& user, HttpRequest& re
{ "results", new Array({ result1 }) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
}

View File

@ -13,16 +13,36 @@ class ConfigStagesHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(ConfigStagesHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
private:
void HandleGet(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params);
void HandlePost(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params);
void HandleDelete(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params);
void HandleGet(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
);
void HandlePost(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
);
void HandleDelete(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
);
};

View File

@ -53,17 +53,25 @@ static void EnsureFrameCleanupTimer()
});
}
bool ConsoleHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool ConsoleHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() != 3)
namespace http = boost::beast::http;
if (url->GetPath().size() != 3)
return false;
if (request.RequestMethod != "POST")
if (request.method() != http::verb::post)
return false;
QueryDescription qd;
String methodName = request.RequestUrl->GetPath()[2];
String methodName = url->GetPath()[2];
FilterUtility::CheckPermission(user, "console");
@ -85,9 +93,12 @@ bool ConsoleHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& reques
return true;
}
bool ConsoleHandler::ExecuteScriptHelper(HttpRequest& request, HttpResponse& response,
bool ConsoleHandler::ExecuteScriptHelper(boost::beast::http::request<boost::beast::http::string_body>& request,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed)
{
namespace http = boost::beast::http;
Log(LogNotice, "Console")
<< "Executing expression: " << command;
@ -151,15 +162,18 @@ bool ConsoleHandler::ExecuteScriptHelper(HttpRequest& request, HttpResponse& res
{ "results", new Array({ resultInfo }) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;
}
bool ConsoleHandler::AutocompleteScriptHelper(HttpRequest& request, HttpResponse& response,
bool ConsoleHandler::AutocompleteScriptHelper(boost::beast::http::request<boost::beast::http::string_body>& request,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed)
{
namespace http = boost::beast::http;
Log(LogInformation, "Console")
<< "Auto-completing expression: " << command;
@ -187,7 +201,7 @@ bool ConsoleHandler::AutocompleteScriptHelper(HttpRequest& request, HttpResponse
{ "results", new Array({ result1 }) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -22,15 +22,22 @@ class ConsoleHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(ConsoleHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
static std::vector<String> GetAutocompletionSuggestions(const String& word, ScriptFrame& frame);
private:
static bool ExecuteScriptHelper(HttpRequest& request, HttpResponse& response,
static bool ExecuteScriptHelper(boost::beast::http::request<boost::beast::http::string_body>& request,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed);
static bool AutocompleteScriptHelper(HttpRequest& request, HttpResponse& response,
static bool AutocompleteScriptHelper(boost::beast::http::request<boost::beast::http::string_body>& request,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params, const String& command, const String& session, bool sandboxed);
};

View File

@ -14,15 +14,23 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/objects", CreateObjectHandler);
bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool CreateObjectHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() != 4)
namespace http = boost::beast::http;
if (url->GetPath().size() != 4)
return false;
if (request.RequestMethod != "PUT")
if (request.method() != http::verb::put)
return false;
Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
if (!type) {
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
@ -31,7 +39,7 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
FilterUtility::CheckPermission(user, "objects/create/" + type->GetName());
String name = request.RequestUrl->GetPath()[3];
String name = url->GetPath()[3];
Array::Ptr templates = params->Get("templates");
Dictionary::Ptr attrs = params->Get("attrs");
@ -99,7 +107,7 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
result1->Set("code", 500);
result1->Set("status", "Object could not be created.");
response.SetStatus(500, "Object could not be created");
response.result(http::status::internal_server_error);
HttpUtility::SendJsonBody(response, params, result);
return true;
@ -113,7 +121,7 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
if (verbose)
result1->Set("diagnostic_information", diagnosticInformation);
response.SetStatus(500, "Object could not be created");
response.result(http::status::internal_server_error);
HttpUtility::SendJsonBody(response, params, result);
return true;
@ -129,7 +137,7 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
else if (!obj && ignoreOnError)
result1->Set("status", "Object was not created but 'ignore_on_error' was set to true");
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -13,8 +13,13 @@ class CreateObjectHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(CreateObjectHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -14,15 +14,23 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/objects", DeleteObjectHandler);
bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool DeleteObjectHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
namespace http = boost::beast::http;
if (url->GetPath().size() < 3 || url->GetPath().size() > 4)
return false;
if (request.RequestMethod != "DELETE")
if (request.method() != http::verb::delete_)
return false;
Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
if (!type) {
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
@ -35,10 +43,10 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
params->Set("type", type->GetName());
if (request.RequestUrl->GetPath().size() >= 4) {
if (url->GetPath().size() >= 4) {
String attr = type->GetName();
boost::algorithm::to_lower(attr);
params->Set(attr, request.RequestUrl->GetPath()[3]);
params->Set(attr, url->GetPath()[3]);
}
std::vector<Value> objs;
@ -93,9 +101,9 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
});
if (!success)
response.SetStatus(500, "One or more objects could not be deleted");
response.result(http::status::internal_server_error);
else
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);

View File

@ -13,8 +13,13 @@ class DeleteObjectHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(DeleteObjectHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -13,15 +13,23 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/events", EventsHandler);
bool EventsHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool EventsHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() != 2)
namespace http = boost::beast::http;
if (url->GetPath().size() != 2)
return false;
if (request.RequestMethod != "POST")
if (request.method() != http::verb::post)
return false;
if (request.ProtocolVersion == HttpVersion10) {
if (request.version() == 10) {
HttpUtility::SendJsonError(response, params, 400, "HTTP/1.0 not supported for event streams.");
return true;
}
@ -67,8 +75,8 @@ bool EventsHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request
queue->AddClient(&request);
response.SetStatus(200, "OK");
response.AddHeader("Content-Type", "application/json");
response.result(http::status::ok);
response.set(http::field::content_type, "application/json");
for (;;) {
Dictionary::Ptr result = queue->WaitForEvent(&request);

View File

@ -14,8 +14,13 @@ class EventsHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(EventsHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -8,24 +8,32 @@ using namespace icinga;
REGISTER_URLHANDLER("/", InfoHandler);
bool InfoHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool InfoHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() > 2)
namespace http = boost::beast::http;
if (url->GetPath().size() > 2)
return false;
if (request.RequestMethod != "GET")
if (request.method() != http::verb::get)
return false;
if (request.RequestUrl->GetPath().empty()) {
response.SetStatus(302, "Found");
response.AddHeader("Location", "/v1");
if (url->GetPath().empty()) {
response.result(http::status::found);
response.set(http::field::location, "/v1");
return true;
}
if (request.RequestUrl->GetPath()[0] != "v1" || request.RequestUrl->GetPath().size() != 1)
if (url->GetPath()[0] != "v1" || url->GetPath().size() != 1)
return false;
response.SetStatus(200, "OK");
response.result(http::status::ok);
std::vector<String> permInfo;
Array::Ptr permissions = user->GetPermissions();
@ -49,7 +57,7 @@ bool InfoHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
}
}
if (request.Headers->Get("accept") == "application/json") {
if (request[http::field::accept] == "application/json") {
Dictionary::Ptr result1 = new Dictionary({
{ "user", user->GetName() },
{ "permissions", Array::FromVector(permInfo) },
@ -63,7 +71,7 @@ bool InfoHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpUtility::SendJsonBody(response, params, result);
} else {
response.AddHeader("Content-Type", "text/html");
response.set(http::field::content_type, "text/html");
String body = "<html><head><title>Icinga 2</title></head><h1>Hello from Icinga 2 (Version: " + Application::GetAppVersion() + ")!</h1>";
body += "<p>You are authenticated as <b>" + user->GetName() + "</b>. ";
@ -80,7 +88,8 @@ bool InfoHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
body += "Your user does not have any permissions.</p>";
body += R"(<p>More information about API requests is available in the <a href="https://docs.icinga.com/icinga2/latest" target="_blank">documentation</a>.</p></html>)";
response.WriteBody(body.CStr(), body.GetLength());
response.body() = body;
response.set(http::field::content_length, response.body().size());
}
return true;

View File

@ -13,8 +13,13 @@ class InfoHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(InfoHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -12,15 +12,23 @@ using namespace icinga;
REGISTER_URLHANDLER("/v1/objects", ModifyObjectHandler);
bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool ModifyObjectHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
namespace http = boost::beast::http;
if (url->GetPath().size() < 3 || url->GetPath().size() > 4)
return false;
if (request.RequestMethod != "POST")
if (request.method() != http::verb::post)
return false;
Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
if (!type) {
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
@ -33,10 +41,10 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
params->Set("type", type->GetName());
if (request.RequestUrl->GetPath().size() >= 4) {
if (url->GetPath().size() >= 4) {
String attr = type->GetName();
boost::algorithm::to_lower(attr);
params->Set(attr, request.RequestUrl->GetPath()[3]);
params->Set(attr, url->GetPath()[3]);
}
std::vector<Value> objs;
@ -101,7 +109,7 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
{ "results", new Array(std::move(results)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -13,8 +13,13 @@ class ModifyObjectHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(ModifyObjectHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -87,15 +87,23 @@ Dictionary::Ptr ObjectQueryHandler::SerializeObjectAttrs(const Object::Ptr& obje
return new Dictionary(std::move(resultAttrs));
}
bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool ObjectQueryHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
namespace http = boost::beast::http;
if (url->GetPath().size() < 3 || url->GetPath().size() > 4)
return false;
if (request.RequestMethod != "GET")
if (request.method() != http::verb::get)
return false;
Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
if (!type) {
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
@ -136,10 +144,10 @@ bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& re
params->Set("type", type->GetName());
if (request.RequestUrl->GetPath().size() >= 4) {
if (url->GetPath().size() >= 4) {
String attr = type->GetName();
boost::algorithm::to_lower(attr);
params->Set(attr, request.RequestUrl->GetPath()[3]);
params->Set(attr, url->GetPath()[3]);
}
std::vector<Value> objs;
@ -265,7 +273,7 @@ bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& re
{ "results", new Array(std::move(results)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -13,8 +13,13 @@ class ObjectQueryHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(ObjectQueryHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
private:
static Dictionary::Ptr SerializeObjectAttrs(const Object::Ptr& object, const String& attrPrefix,

View File

@ -68,12 +68,20 @@ public:
}
};
bool StatusHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool StatusHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() > 3)
namespace http = boost::beast::http;
if (url->GetPath().size() > 3)
return false;
if (request.RequestMethod != "GET")
if (request.method() != http::verb::get)
return false;
QueryDescription qd;
@ -83,8 +91,8 @@ bool StatusHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request
params->Set("type", "Status");
if (request.RequestUrl->GetPath().size() >= 3)
params->Set("status", request.RequestUrl->GetPath()[2]);
if (url->GetPath().size() >= 3)
params->Set("status", url->GetPath()[2]);
std::vector<Value> objs;
@ -101,7 +109,7 @@ bool StatusHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request
{ "results", new Array(std::move(objs)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -13,8 +13,13 @@ class StatusHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(StatusHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -75,15 +75,23 @@ public:
}
};
bool TemplateQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool TemplateQueryHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
namespace http = boost::beast::http;
if (url->GetPath().size() < 3 || url->GetPath().size() > 4)
return false;
if (request.RequestMethod != "GET")
if (request.method() != http::verb::get)
return false;
Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
if (!type) {
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
@ -97,10 +105,10 @@ bool TemplateQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest&
params->Set("type", type->GetName());
if (request.RequestUrl->GetPath().size() >= 4) {
if (url->GetPath().size() >= 4) {
String attr = type->GetName();
boost::algorithm::to_lower(attr);
params->Set(attr, request.RequestUrl->GetPath()[3]);
params->Set(attr, url->GetPath()[3]);
}
std::vector<Value> objs;
@ -118,7 +126,7 @@ bool TemplateQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest&
{ "results", new Array(std::move(objs)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -13,8 +13,13 @@ class TemplateQueryHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(TemplateQueryHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -46,12 +46,20 @@ public:
}
};
bool TypeQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool TypeQueryHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() > 3)
namespace http = boost::beast::http;
if (url->GetPath().size() > 3)
return false;
if (request.RequestMethod != "GET")
if (request.method() != http::verb::get)
return false;
QueryDescription qd;
@ -64,8 +72,8 @@ bool TypeQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& requ
params->Set("type", "Type");
if (request.RequestUrl->GetPath().size() >= 3)
params->Set("name", request.RequestUrl->GetPath()[2]);
if (url->GetPath().size() >= 3)
params->Set("name", url->GetPath()[2]);
std::vector<Value> objs;
@ -138,7 +146,7 @@ bool TypeQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& requ
{ "results", new Array(std::move(results)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -13,8 +13,13 @@ class TypeQueryHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(TypeQueryHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}

View File

@ -56,12 +56,20 @@ public:
}
};
bool VariableQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
bool VariableQueryHandler::HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
)
{
if (request.RequestUrl->GetPath().size() > 3)
namespace http = boost::beast::http;
if (url->GetPath().size() > 3)
return false;
if (request.RequestMethod != "GET")
if (request.method() != http::verb::get)
return false;
QueryDescription qd;
@ -71,8 +79,8 @@ bool VariableQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest&
params->Set("type", "Variable");
if (request.RequestUrl->GetPath().size() >= 3)
params->Set("variable", request.RequestUrl->GetPath()[2]);
if (url->GetPath().size() >= 3)
params->Set("variable", url->GetPath()[2]);
std::vector<Value> objs;
@ -99,7 +107,7 @@ bool VariableQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest&
{ "results", new Array(std::move(results)) }
});
response.SetStatus(200, "OK");
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, result);
return true;

View File

@ -13,8 +13,13 @@ class VariableQueryHandler final : public HttpHandler
public:
DECLARE_PTR_TYPEDEFS(VariableQueryHandler);
bool HandleRequest(const ApiUser::Ptr& user, HttpRequest& request,
HttpResponse& response, const Dictionary::Ptr& params) override;
bool HandleRequest(
const ApiUser::Ptr& user,
boost::beast::http::request<boost::beast::http::string_body>& request,
const Url::Ptr& url,
boost::beast::http::response<boost::beast::http::string_body>& response,
const Dictionary::Ptr& params
) override;
};
}