mirror of
https://github.com/Icinga/icinga2.git
synced 2026-06-08 16:26:42 -04:00
Always call HttpUtility::SendJsonBody() with a boost::asio::yield_context
to respect `l_FlushThreshold` in all messages. Especially `l_FlushThreshold` may now be lowered in the future without re-evaluating all possible responses. Side effect: all HTTP responses use chunked encoding now.
This commit is contained in:
parent
3312ed7ec4
commit
a56388940e
24 changed files with 107 additions and 116 deletions
|
|
@ -37,7 +37,7 @@ bool ActionsHandler::HandleRequest(
|
|||
ApiAction::Ptr action = ApiAction::GetByName(actionName);
|
||||
|
||||
if (!action) {
|
||||
HttpUtility::SendJsonError(response, params, 404, "Action '" + actionName + "' does not exist.");
|
||||
HttpUtility::SendJsonError(response, params, 404, yc, "Action '" + actionName + "' does not exist.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -55,14 +55,14 @@ bool ActionsHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No objects found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (objs.empty()) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No objects found.");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ bool ActionsHandler::HandleRequest(
|
|||
|
||||
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||
if (!wgLock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Shutting down.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ bool ConfigFilesHandler::HandleRequest(
|
|||
}
|
||||
|
||||
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'.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid Accept header. Either remove the Accept header or set it to 'application/octet-stream'.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -54,26 +54,26 @@ bool ConfigFilesHandler::HandleRequest(
|
|||
String stageName = HttpUtility::GetLastParameter(params, "stage");
|
||||
|
||||
if (!ConfigPackageUtility::ValidatePackageName(packageName)) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid package name.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid package name.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ConfigPackageUtility::ValidateStageName(stageName)) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid stage name.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid stage name.");
|
||||
return true;
|
||||
}
|
||||
|
||||
String relativePath = HttpUtility::GetLastParameter(params, "path");
|
||||
|
||||
if (ConfigPackageUtility::ContainsDotDot(relativePath)) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Path contains '..' (not allowed).");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Path contains '..' (not allowed).");
|
||||
return true;
|
||||
}
|
||||
|
||||
String path = ConfigPackageUtility::GetPackageDir() + "/" + packageName + "/" + stageName + "/" + relativePath;
|
||||
|
||||
if (!Utility::PathExists(path)) {
|
||||
HttpUtility::SendJsonError(response, params, 404, "Path not found.");
|
||||
HttpUtility::SendJsonError(response, params, 404, yc, "Path not found.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ bool ConfigFilesHandler::HandleRequest(
|
|||
response.set(http::field::content_type, "application/octet-stream");
|
||||
response.SendFile(path, yc);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 500, "Could not read file.",
|
||||
HttpUtility::SendJsonError(response, params, 500, yc, "Could not read file.",
|
||||
DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ bool ConfigPackagesHandler::HandleRequest(
|
|||
if (request.method() == http::verb::get)
|
||||
HandleGet(request, response, yc);
|
||||
else if (request.method() == http::verb::post)
|
||||
HandlePost(request, response);
|
||||
HandlePost(request, response, yc);
|
||||
else if (request.method() == http::verb::delete_)
|
||||
HandleDelete(request, response);
|
||||
HandleDelete(request, response, yc);
|
||||
else
|
||||
return false;
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ void ConfigPackagesHandler::HandleGet(const HttpApiRequest& request, HttpApiResp
|
|||
try {
|
||||
packages = ConfigPackageUtility::GetPackages();
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 500, "Could not retrieve packages.",
|
||||
HttpUtility::SendJsonError(response, params, 500, yc, "Could not retrieve packages.",
|
||||
DiagnosticInformation(ex));
|
||||
return;
|
||||
}
|
||||
|
|
@ -90,7 +90,7 @@ void ConfigPackagesHandler::HandleGet(const HttpApiRequest& request, HttpApiResp
|
|||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
}
|
||||
|
||||
void ConfigPackagesHandler::HandlePost(const HttpApiRequest& request, HttpApiResponse& response)
|
||||
void ConfigPackagesHandler::HandlePost(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
||||
|
|
@ -106,13 +106,13 @@ void ConfigPackagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRes
|
|||
String packageName = HttpUtility::GetLastParameter(params, "package");
|
||||
|
||||
if (!ConfigPackageUtility::ValidatePackageName(packageName)) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid package name '" + packageName + "'.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid package name '" + packageName + "'.");
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigObjectsSharedLock configObjectsSharedLock(std::try_to_lock);
|
||||
if (!configObjectsSharedLock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ void ConfigPackagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRes
|
|||
|
||||
ConfigPackageUtility::CreatePackage(packageName);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 500, "Could not create package '" + packageName + "'.",
|
||||
HttpUtility::SendJsonError(response, params, 500, yc, "Could not create package '" + packageName + "'.",
|
||||
DiagnosticInformation(ex));
|
||||
return;
|
||||
}
|
||||
|
|
@ -137,10 +137,10 @@ void ConfigPackagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRes
|
|||
});
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
}
|
||||
|
||||
void ConfigPackagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiResponse& response)
|
||||
void ConfigPackagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
||||
|
|
@ -156,20 +156,20 @@ void ConfigPackagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiR
|
|||
String packageName = HttpUtility::GetLastParameter(params, "package");
|
||||
|
||||
if (!ConfigPackageUtility::ValidatePackageName(packageName)) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid package name '" + packageName + "'.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid package name '" + packageName + "'.");
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigObjectsSharedLock lock(std::try_to_lock);
|
||||
if (!lock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ConfigPackageUtility::DeletePackage(packageName);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 500, "Failed to delete package '" + packageName + "'.",
|
||||
HttpUtility::SendJsonError(response, params, 500, yc, "Failed to delete package '" + packageName + "'.",
|
||||
DiagnosticInformation(ex));
|
||||
return;
|
||||
}
|
||||
|
|
@ -185,5 +185,5 @@ void ConfigPackagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiR
|
|||
});
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ public:
|
|||
|
||||
private:
|
||||
void HandleGet(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc);
|
||||
void HandlePost(const HttpApiRequest& request, HttpApiResponse& response);
|
||||
void HandleDelete(const HttpApiRequest& request, HttpApiResponse& response);
|
||||
void HandlePost(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc);
|
||||
void HandleDelete(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ bool ConfigStagesHandler::HandleRequest(
|
|||
if (request.method() == http::verb::get)
|
||||
HandleGet(request, response, yc);
|
||||
else if (request.method() == http::verb::post)
|
||||
HandlePost(request, response);
|
||||
HandlePost(request, response, yc);
|
||||
else if (request.method() == http::verb::delete_)
|
||||
HandleDelete(request, response);
|
||||
HandleDelete(request, response, yc);
|
||||
else
|
||||
return false;
|
||||
|
||||
|
|
@ -67,10 +67,10 @@ void ConfigStagesHandler::HandleGet(const HttpApiRequest& request, HttpApiRespon
|
|||
String stageName = HttpUtility::GetLastParameter(params, "stage");
|
||||
|
||||
if (!ConfigPackageUtility::ValidatePackageName(packageName))
|
||||
return HttpUtility::SendJsonError(response, params, 400, "Invalid package name '" + packageName + "'.");
|
||||
return HttpUtility::SendJsonError(response, params, 400, yc, "Invalid package name '" + packageName + "'.");
|
||||
|
||||
if (!ConfigPackageUtility::ValidateStageName(stageName))
|
||||
return HttpUtility::SendJsonError(response, params, 400, "Invalid stage name '" + stageName + "'.");
|
||||
return HttpUtility::SendJsonError(response, params, 400, yc, "Invalid stage name '" + stageName + "'.");
|
||||
|
||||
std::vector<std::pair<String, bool> > paths = ConfigPackageUtility::GetFiles(packageName, stageName);
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ void ConfigStagesHandler::HandleGet(const HttpApiRequest& request, HttpApiRespon
|
|||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
}
|
||||
|
||||
void ConfigStagesHandler::HandlePost(const HttpApiRequest& request, HttpApiResponse& response)
|
||||
void ConfigStagesHandler::HandlePost(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ void ConfigStagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRespo
|
|||
String packageName = HttpUtility::GetLastParameter(params, "package");
|
||||
|
||||
if (!ConfigPackageUtility::ValidatePackageName(packageName))
|
||||
return HttpUtility::SendJsonError(response, params, 400, "Invalid package name '" + packageName + "'.");
|
||||
return HttpUtility::SendJsonError(response, params, 400, yc, "Invalid package name '" + packageName + "'.");
|
||||
|
||||
bool reload = true;
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ void ConfigStagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRespo
|
|||
|
||||
ConfigObjectsSharedLock configObjectsSharedLock(std::try_to_lock);
|
||||
if (!configObjectsSharedLock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ void ConfigStagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRespo
|
|||
*/
|
||||
if (l_RunningPackageUpdates && l_LastReloadFailedTime == currentReloadFailedTime) {
|
||||
return HttpUtility::SendJsonError(
|
||||
response, params, 423,
|
||||
response, params, 423, yc,
|
||||
"Conflicting request, there is already an ongoing package update in progress. Please try it again later."
|
||||
);
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ void ConfigStagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRespo
|
|||
/* validate the config. on success, activate stage and reload */
|
||||
ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName, activate, reload, resetPackageUpdates);
|
||||
} catch (const std::exception& ex) {
|
||||
return HttpUtility::SendJsonError(response, params, 500,
|
||||
return HttpUtility::SendJsonError(response, params, 500, yc,
|
||||
"Stage creation failed.",
|
||||
DiagnosticInformation(ex));
|
||||
}
|
||||
|
|
@ -198,10 +198,10 @@ void ConfigStagesHandler::HandlePost(const HttpApiRequest& request, HttpApiRespo
|
|||
});
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
}
|
||||
|
||||
void ConfigStagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiResponse& response)
|
||||
void ConfigStagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
||||
|
|
@ -221,21 +221,21 @@ void ConfigStagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiRes
|
|||
String stageName = HttpUtility::GetLastParameter(params, "stage");
|
||||
|
||||
if (!ConfigPackageUtility::ValidatePackageName(packageName))
|
||||
return HttpUtility::SendJsonError(response, params, 400, "Invalid package name '" + packageName + "'.");
|
||||
return HttpUtility::SendJsonError(response, params, 400, yc, "Invalid package name '" + packageName + "'.");
|
||||
|
||||
if (!ConfigPackageUtility::ValidateStageName(stageName))
|
||||
return HttpUtility::SendJsonError(response, params, 400, "Invalid stage name '" + stageName + "'.");
|
||||
return HttpUtility::SendJsonError(response, params, 400, yc, "Invalid stage name '" + stageName + "'.");
|
||||
|
||||
ConfigObjectsSharedLock lock(std::try_to_lock);
|
||||
if (!lock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ConfigPackageUtility::DeleteStage(packageName, stageName);
|
||||
} catch (const std::exception& ex) {
|
||||
return HttpUtility::SendJsonError(response, params, 500,
|
||||
return HttpUtility::SendJsonError(response, params, 500, yc,
|
||||
"Failed to delete stage '" + stageName + "' in package '" + packageName + "'.",
|
||||
DiagnosticInformation(ex));
|
||||
}
|
||||
|
|
@ -252,5 +252,5 @@ void ConfigStagesHandler::HandleDelete(const HttpApiRequest& request, HttpApiRes
|
|||
});
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ public:
|
|||
|
||||
private:
|
||||
void HandleGet(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc);
|
||||
void HandlePost(const HttpApiRequest& request, HttpApiResponse& response);
|
||||
void HandleDelete(const HttpApiRequest& request, HttpApiResponse& response);
|
||||
void HandlePost(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc);
|
||||
void HandleDelete(const HttpApiRequest& request, HttpApiResponse& response, boost::asio::yield_context& yc);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ bool ConsoleHandler::HandleRequest(
|
|||
const WaitGroup::Ptr&,
|
||||
const HttpApiRequest& request,
|
||||
HttpApiResponse& response,
|
||||
boost::asio::yield_context&
|
||||
boost::asio::yield_context& yc
|
||||
)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
|
@ -106,21 +106,21 @@ bool ConsoleHandler::HandleRequest(
|
|||
ConfigObjectsSharedLock lock (std::try_to_lock);
|
||||
|
||||
if (!lock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading.");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (methodName == "execute-script")
|
||||
return ExecuteScriptHelper(request, response, command, session, sandboxed);
|
||||
return ExecuteScriptHelper(request, response, command, session, sandboxed, yc);
|
||||
else if (methodName == "auto-complete-script")
|
||||
return AutocompleteScriptHelper(request, response, command, session, sandboxed);
|
||||
return AutocompleteScriptHelper(request, response, command, session, sandboxed, yc);
|
||||
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid method specified: " + methodName);
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid method specified: " + methodName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConsoleHandler::ExecuteScriptHelper(const HttpApiRequest& request, HttpApiResponse& response,
|
||||
const String& command, const String& session, bool sandboxed)
|
||||
const String& command, const String& session, bool sandboxed, boost::asio::yield_context& yc)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ bool ConsoleHandler::ExecuteScriptHelper(const HttpApiRequest& request, HttpApiR
|
|||
|
||||
std::unique_lock frameLock(lsf->Mutex, std::try_to_lock);
|
||||
if (!frameLock) {
|
||||
HttpUtility::SendJsonError(response, request.Params(), 409, "Session is currently in use by another request.");
|
||||
HttpUtility::SendJsonError(response, request.Params(), 409, yc, "Session is currently in use by another request.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -195,13 +195,13 @@ bool ConsoleHandler::ExecuteScriptHelper(const HttpApiRequest& request, HttpApiR
|
|||
});
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, request.Params(), result);
|
||||
HttpUtility::SendJsonBody(response, request.Params(), result, yc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConsoleHandler::AutocompleteScriptHelper(const HttpApiRequest& request, HttpApiResponse& response,
|
||||
const String& command, const String& session, bool sandboxed)
|
||||
const String& command, const String& session, bool sandboxed, boost::asio::yield_context& yc)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ bool ConsoleHandler::AutocompleteScriptHelper(const HttpApiRequest& request, Htt
|
|||
|
||||
std::unique_lock frameLock(lsf->Mutex, std::try_to_lock);
|
||||
if (!frameLock) {
|
||||
HttpUtility::SendJsonError(response, request.Params(), 409, "Session is currently in use by another request.");
|
||||
HttpUtility::SendJsonError(response, request.Params(), 409, yc, "Session is currently in use by another request.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +240,7 @@ bool ConsoleHandler::AutocompleteScriptHelper(const HttpApiRequest& request, Htt
|
|||
});
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, request.Params(), result);
|
||||
HttpUtility::SendJsonBody(response, request.Params(), result, yc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ public:
|
|||
|
||||
private:
|
||||
static bool ExecuteScriptHelper(const HttpApiRequest& request, HttpApiResponse& response,
|
||||
const String& command, const String& session, bool sandboxed);
|
||||
const String& command, const String& session, bool sandboxed, boost::asio::yield_context& yc);
|
||||
static bool AutocompleteScriptHelper(const HttpApiRequest& request, HttpApiResponse& response,
|
||||
const String& command, const String& session, bool sandboxed);
|
||||
const String& command, const String& session, bool sandboxed, boost::asio::yield_context& yc);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ bool CreateObjectHandler::HandleRequest(
|
|||
const WaitGroup::Ptr& waitGroup,
|
||||
const HttpApiRequest& request,
|
||||
HttpApiResponse& response,
|
||||
boost::asio::yield_context&
|
||||
boost::asio::yield_context& yc
|
||||
)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
|
@ -38,7 +38,7 @@ bool CreateObjectHandler::HandleRequest(
|
|||
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
|
||||
|
||||
if (!type) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid type specified.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -99,13 +99,13 @@ bool CreateObjectHandler::HandleRequest(
|
|||
ConfigObjectsSharedLock lock (std::try_to_lock);
|
||||
|
||||
if (!lock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||
if (!wgLock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Shutting down.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ bool CreateObjectHandler::HandleRequest(
|
|||
result1->Set("status", "Object could not be created.");
|
||||
|
||||
response.result(http::status::internal_server_error);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ bool CreateObjectHandler::HandleRequest(
|
|||
result1->Set("diagnostic_information", diagnosticInformation);
|
||||
|
||||
response.result(http::status::internal_server_error);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ bool CreateObjectHandler::HandleRequest(
|
|||
result1->Set("status", "Object was not created but 'ignore_on_error' was set to true");
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ bool DeleteObjectHandler::HandleRequest(
|
|||
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
|
||||
|
||||
if (!type) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid type specified.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ bool DeleteObjectHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No objects found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
|
|
@ -71,7 +71,7 @@ bool DeleteObjectHandler::HandleRequest(
|
|||
ConfigObjectsSharedLock lock (std::try_to_lock);
|
||||
|
||||
if (!lock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ bool DeleteObjectHandler::HandleRequest(
|
|||
|
||||
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||
if (!wgLock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Shutting down.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,14 +61,14 @@ bool EventsHandler::HandleRequest(
|
|||
return false;
|
||||
|
||||
if (request.version() == 10) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "HTTP/1.0 not supported for event streams.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "HTTP/1.0 not supported for event streams.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Array::Ptr types = params->Get("types");
|
||||
|
||||
if (!types) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "'types' query parameter is required.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "'types' query parameter is required.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ void HttpHandler::ProcessRequest(
|
|||
try {
|
||||
request.DecodeParams();
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, request.Params(), 400, "Invalid request body: " + DiagnosticInformation(ex, false));
|
||||
HttpUtility::SendJsonError(response, request.Params(), 400, yc, "Invalid request body: " + DiagnosticInformation(ex, false));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ void HttpHandler::ProcessRequest(
|
|||
}
|
||||
|
||||
if (!processed) {
|
||||
HttpUtility::SendJsonError(response, request.Params(), 404, "The requested path '" + boost::algorithm::join(path, "/") +
|
||||
HttpUtility::SendJsonError(response, request.Params(), 404, yc, "The requested path '" + boost::algorithm::join(path, "/") +
|
||||
"' could not be found or the request method is not valid for this path.");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ bool EnsureValidHeaders(
|
|||
response.result(http::status::bad_request);
|
||||
|
||||
if (!httpError && request[http::field::accept] == "application/json") {
|
||||
HttpUtility::SendJsonError(response, nullptr, 400, "Bad Request: " + errorMsg);
|
||||
HttpUtility::SendJsonError(response, nullptr, 400, yc, "Bad Request: " + errorMsg);
|
||||
} else {
|
||||
response.set(http::field::content_type, "text/html");
|
||||
response.body() << "<h1>Bad Request</h1><p><pre>" << errorMsg << "</pre></p>";
|
||||
|
|
@ -315,7 +315,7 @@ bool EnsureAuthenticatedUser(
|
|||
response.set(http::field::connection, "close");
|
||||
|
||||
if (request[http::field::accept] == "application/json") {
|
||||
HttpUtility::SendJsonError(response, nullptr, 401, "Unauthorized. Please check your user credentials.");
|
||||
HttpUtility::SendJsonError(response, nullptr, 401, yc, "Unauthorized. Please check your user credentials.");
|
||||
} else {
|
||||
response.set(http::field::content_type, "text/html");
|
||||
response.body() << "<h1>Unauthorized. Please check your user credentials.</h1>";
|
||||
|
|
@ -396,7 +396,7 @@ bool EnsureValidBody(
|
|||
response.result(http::status::bad_request);
|
||||
|
||||
if (request[http::field::accept] == "application/json") {
|
||||
HttpUtility::SendJsonError(response, nullptr, 400, "Bad Request: " + ec.message());
|
||||
HttpUtility::SendJsonError(response, nullptr, 400, yc, "Bad Request: " + ec.message());
|
||||
} else {
|
||||
response.set(http::field::content_type, "text/html");
|
||||
response.body() << "<h1>Bad Request</h1><p><pre>" << ec.message() << "</pre></p>";
|
||||
|
|
@ -438,7 +438,7 @@ void ProcessRequest(
|
|||
throw;
|
||||
}
|
||||
|
||||
HttpUtility::SendJsonError(response, request.Params(), 500, "Unhandled exception", DiagnosticInformation(ex));
|
||||
HttpUtility::SendJsonError(response, request.Params(), 500, yc, "Unhandled exception", DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
response.Flush(yc);
|
||||
|
|
|
|||
|
|
@ -75,16 +75,8 @@ void HttpUtility::SendJsonBody(HttpApiResponse& response, const Dictionary::Ptr&
|
|||
response.GetJsonEncoder(params && GetLastParameter(params, "pretty")).Encode(val, &yc);
|
||||
}
|
||||
|
||||
void HttpUtility::SendJsonBody(HttpApiResponse& response, const Dictionary::Ptr& params, const Value& val)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
||||
response.set(http::field::content_type, "application/json");
|
||||
response.GetJsonEncoder(params && GetLastParameter(params, "pretty")).Encode(val);
|
||||
}
|
||||
|
||||
void HttpUtility::SendJsonError(HttpApiResponse& response,
|
||||
const Dictionary::Ptr& params, int code, const String& info, const String& diagnosticInformation)
|
||||
void HttpUtility::SendJsonError(HttpApiResponse& response, const Dictionary::Ptr& params,
|
||||
int code, boost::asio::yield_context& yc, const String& info, const String& diagnosticInformation)
|
||||
{
|
||||
Dictionary::Ptr result = new Dictionary({ { "error", code } });
|
||||
|
||||
|
|
@ -99,7 +91,7 @@ void HttpUtility::SendJsonError(HttpApiResponse& response,
|
|||
response.Clear();
|
||||
response.result(code);
|
||||
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -26,9 +26,8 @@ public:
|
|||
static Value GetLastParameter(const Dictionary::Ptr& params, const String& key);
|
||||
|
||||
static void SendJsonBody(HttpApiResponse& response, const Dictionary::Ptr& params, const Value& val, boost::asio::yield_context& yc);
|
||||
static void SendJsonBody(HttpApiResponse& response, const Dictionary::Ptr& params, const Value& val);
|
||||
static void SendJsonError(HttpApiResponse& response, const Dictionary::Ptr& params, const int code,
|
||||
const String& info = {}, const String& diagnosticInformation = {});
|
||||
boost::asio::yield_context& yc, const String& info = {}, const String& diagnosticInformation = {});
|
||||
|
||||
static bool IsValidHeaderName(std::string_view name);
|
||||
static bool IsValidHeaderValue(std::string_view value);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ bool InfoHandler::HandleRequest(
|
|||
const WaitGroup::Ptr&,
|
||||
const HttpApiRequest& request,
|
||||
HttpApiResponse& response,
|
||||
boost::asio::yield_context&
|
||||
boost::asio::yield_context& yc
|
||||
)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
|
@ -73,7 +73,7 @@ bool InfoHandler::HandleRequest(
|
|||
{ "results", new Array({ result1 }) }
|
||||
});
|
||||
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
} else {
|
||||
response.set(http::field::content_type, "text/html");
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ bool MallocInfoHandler::HandleRequest(
|
|||
const WaitGroup::Ptr&,
|
||||
const HttpApiRequest& request,
|
||||
HttpApiResponse& response,
|
||||
boost::asio::yield_context&
|
||||
boost::asio::yield_context& yc
|
||||
)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
|
@ -42,7 +42,7 @@ bool MallocInfoHandler::HandleRequest(
|
|||
FilterUtility::CheckPermission(user, "debug");
|
||||
|
||||
#ifndef HAVE_MALLOC_INFO
|
||||
HttpUtility::SendJsonError(response, params, 501, "malloc_info(3) not available.");
|
||||
HttpUtility::SendJsonError(response, params, 501, yc, "malloc_info(3) not available.");
|
||||
#else /* HAVE_MALLOC_INFO */
|
||||
char* buf = nullptr;
|
||||
size_t bufSize = 0;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ bool ModifyObjectHandler::HandleRequest(
|
|||
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
|
||||
|
||||
if (!type) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid type specified.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ bool ModifyObjectHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No objects found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
|
|
@ -66,7 +66,7 @@ bool ModifyObjectHandler::HandleRequest(
|
|||
Value attrsVal = params->Get("attrs");
|
||||
|
||||
if (attrsVal.GetReflectionType() != Dictionary::TypeInstance && attrsVal.GetType() != ValueEmpty) {
|
||||
HttpUtility::SendJsonError(response, params, 400,
|
||||
HttpUtility::SendJsonError(response, params, 400, yc,
|
||||
"Invalid type for 'attrs' attribute specified. Dictionary type is required."
|
||||
"Or is this a POST query and you missed adding a 'X-HTTP-Method-Override: GET' header?");
|
||||
return true;
|
||||
|
|
@ -77,7 +77,7 @@ bool ModifyObjectHandler::HandleRequest(
|
|||
Value restoreAttrsVal = params->Get("restore_attrs");
|
||||
|
||||
if (restoreAttrsVal.GetReflectionType() != Array::TypeInstance && restoreAttrsVal.GetType() != ValueEmpty) {
|
||||
HttpUtility::SendJsonError(response, params, 400,
|
||||
HttpUtility::SendJsonError(response, params, 400, yc,
|
||||
"Invalid type for 'restore_attrs' attribute specified. Array type is required.");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ bool ModifyObjectHandler::HandleRequest(
|
|||
Array::Ptr restoreAttrs = restoreAttrsVal;
|
||||
|
||||
if (!(attrs || restoreAttrs)) {
|
||||
HttpUtility::SendJsonError(response, params, 400,
|
||||
HttpUtility::SendJsonError(response, params, 400, yc,
|
||||
"Missing both 'attrs' and 'restore_attrs'. "
|
||||
"Or is this a POST query and you missed adding a 'X-HTTP-Method-Override: GET' header?");
|
||||
return true;
|
||||
|
|
@ -99,7 +99,7 @@ bool ModifyObjectHandler::HandleRequest(
|
|||
ConfigObjectsSharedLock lock (std::try_to_lock);
|
||||
|
||||
if (!lock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Icinga is reloading");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ bool ModifyObjectHandler::HandleRequest(
|
|||
|
||||
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||
if (!wgLock) {
|
||||
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||
HttpUtility::SendJsonError(response, params, 503, yc, "Shutting down.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ bool ObjectQueryHandler::HandleRequest(
|
|||
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
|
||||
|
||||
if (!type) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid type specified.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ bool ObjectQueryHandler::HandleRequest(
|
|||
try {
|
||||
uattrs = params->Get("attrs");
|
||||
} catch (const std::exception&) {
|
||||
HttpUtility::SendJsonError(response, params, 400,
|
||||
HttpUtility::SendJsonError(response, params, 400, yc,
|
||||
"Invalid type for 'attrs' attribute specified. Array type is required.");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ bool ObjectQueryHandler::HandleRequest(
|
|||
try {
|
||||
ujoins = params->Get("joins");
|
||||
} catch (const std::exception&) {
|
||||
HttpUtility::SendJsonError(response, params, 400,
|
||||
HttpUtility::SendJsonError(response, params, 400, yc,
|
||||
"Invalid type for 'joins' attribute specified. Array type is required.");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ bool ObjectQueryHandler::HandleRequest(
|
|||
try {
|
||||
umetas = params->Get("meta");
|
||||
} catch (const std::exception&) {
|
||||
HttpUtility::SendJsonError(response, params, 400,
|
||||
HttpUtility::SendJsonError(response, params, 400, yc,
|
||||
"Invalid type for 'meta' attribute specified. Array type is required.");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ bool ObjectQueryHandler::HandleRequest(
|
|||
} else if (meta == "location") {
|
||||
includeLocation = true;
|
||||
} else {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid field specified for meta: " + meta);
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid field specified for meta: " + meta);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ bool ObjectQueryHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No objects found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ bool StatusHandler::HandleRequest(
|
|||
const WaitGroup::Ptr&,
|
||||
const HttpApiRequest& request,
|
||||
HttpApiResponse& response,
|
||||
boost::asio::yield_context&
|
||||
boost::asio::yield_context& yc
|
||||
)
|
||||
{
|
||||
namespace http = boost::beast::http;
|
||||
|
|
@ -103,7 +103,7 @@ bool StatusHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No objects found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
|
|
@ -114,7 +114,7 @@ bool StatusHandler::HandleRequest(
|
|||
});
|
||||
|
||||
response.result(http::status::ok);
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
HttpUtility::SendJsonBody(response, params, result, yc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ bool TemplateQueryHandler::HandleRequest(
|
|||
Type::Ptr type = FilterUtility::TypeFromPluralName(url->GetPath()[2]);
|
||||
|
||||
if (!type) {
|
||||
HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
|
||||
HttpUtility::SendJsonError(response, params, 400, yc, "Invalid type specified.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ bool TemplateQueryHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user, "tmpl");
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No templates found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ bool TypeQueryHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user);
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No objects found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ bool VariableQueryHandler::HandleRequest(
|
|||
try {
|
||||
objs = FilterUtility::GetFilterTargets(qd, params, user, "variable");
|
||||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
HttpUtility::SendJsonError(response, params, 404, yc,
|
||||
"No variables found.",
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE(response_sendjsonbody)
|
|||
HttpApiResponse response(server);
|
||||
response.result(http::status::ok);
|
||||
|
||||
HttpUtility::SendJsonBody(response, nullptr, new Dictionary{{"test", 1}});
|
||||
HttpUtility::SendJsonBody(response, nullptr, new Dictionary{{"test", 1}}, yc);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(response.Flush(yc));
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(response_sendjsonbody)
|
|||
|
||||
BOOST_REQUIRE(!ec);
|
||||
BOOST_REQUIRE_EQUAL(parser.get().result(), http::status::ok);
|
||||
BOOST_REQUIRE_EQUAL(parser.get().chunked(), false);
|
||||
BOOST_REQUIRE_EQUAL(parser.get().chunked(), true);
|
||||
Dictionary::Ptr body = JsonDecode(parser.get().body());
|
||||
BOOST_REQUIRE_EQUAL(body->Get("test"), 1);
|
||||
}
|
||||
|
|
@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(response_sendjsonerror)
|
|||
// This has to be overwritten in SendJsonError.
|
||||
response.result(http::status::ok);
|
||||
|
||||
HttpUtility::SendJsonError(response, nullptr, 404, "Not found.");
|
||||
HttpUtility::SendJsonError(response, nullptr, 404, yc, "Not found.");
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(response.Flush(yc));
|
||||
|
||||
|
|
@ -316,7 +316,7 @@ BOOST_AUTO_TEST_CASE(response_sendjsonerror)
|
|||
|
||||
BOOST_REQUIRE(!ec);
|
||||
BOOST_REQUIRE_EQUAL(parser.get().result(), http::status::not_found);
|
||||
BOOST_REQUIRE_EQUAL(parser.get().chunked(), false);
|
||||
BOOST_REQUIRE_EQUAL(parser.get().chunked(), true);
|
||||
Dictionary::Ptr body = JsonDecode(parser.get().body());
|
||||
BOOST_REQUIRE_EQUAL(body->Get("error"), 404);
|
||||
BOOST_REQUIRE_EQUAL(body->Get("status"), "Not found.");
|
||||
|
|
|
|||
Loading…
Reference in a new issue