Add SendJsonBody() overload for streaming HTTP response

This is similar to the already existing `HttpUtility::SendJsonBody()`
function but for streaming.
This commit is contained in:
Yonas Habteab 2025-09-11 13:12:23 +02:00
parent ccf4eebc3d
commit 5ca244c72f
3 changed files with 26 additions and 6 deletions

View File

@ -52,6 +52,28 @@ Value HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String&
return arr->Get(arr->GetLength() - 1);
}
/**
* Stream a JSON-encoded body to the client.
*
* This function sets the Content-Type header to "application/json", starts the streaming of the response,
* and encodes the given value as JSON to the client. If pretty-print is requested, the JSON output will be
* formatted accordingly. It is assumed that the response status code and other necessary headers have already
* been set.
*
* @param response The HTTP response to send the body to.
* @param params The request parameters.
* @param val The value to encode as JSON and stream to the client.
* @param yc The yield context to use for asynchronous operations.
*/
void HttpUtility::SendJsonBody(HttpResponse& response, const Dictionary::Ptr& params, const Value& val, boost::asio::yield_context& yc)
{
namespace http = boost::beast::http;
response.set(http::field::content_type, "application/json");
response.StartStreaming();
response.GetJsonEncoder(params && GetLastParameter(params, "pretty")).Encode(val, &yc);
}
void HttpUtility::SendJsonBody(HttpResponse& response, const Dictionary::Ptr& params, const Value& val)
{
namespace http = boost::beast::http;

View File

@ -6,6 +6,7 @@
#include "remote/url.hpp"
#include "base/dictionary.hpp"
#include "remote/httpmessage.hpp"
#include <boost/asio/spawn.hpp>
#include <string>
namespace icinga
@ -23,6 +24,7 @@ public:
static Dictionary::Ptr FetchRequestParameters(const Url::Ptr& url, const std::string& body);
static Value GetLastParameter(const Dictionary::Ptr& params, const String& key);
static void SendJsonBody(HttpResponse& response, const Dictionary::Ptr& params, const Value& val, boost::asio::yield_context& yc);
static void SendJsonBody(HttpResponse& response, const Dictionary::Ptr& params, const Value& val);
static void SendJsonError(HttpResponse& response, const Dictionary::Ptr& params, const int code,
const String& info = {}, const String& diagnosticInformation = {});

View File

@ -318,15 +318,11 @@ bool ObjectQueryHandler::HandleRequest(
return new Dictionary{std::move(result1)};
};
response.result(http::status::ok);
response.set(http::field::content_type, "application/json");
response.StartStreaming();
Dictionary::Ptr results = new Dictionary{{"results", new ValueGenerator{objs, generatorFunc}}};
results->Freeze();
bool pretty = HttpUtility::GetLastParameter(params, "pretty");
response.GetJsonEncoder(pretty).Encode(results, &yc);
response.result(http::status::ok);
HttpUtility::SendJsonBody(response, params, results, yc);
return true;
}