Task: Add payload support
This adds the payload values to task responses.
Tested: passed validator
Change-Id: I50467e28ce8142d198f916ea0c63bd413edcd524
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/http/http_request.h b/http/http_request.h
index ff09bf1..b440f44 100644
--- a/http/http_request.h
+++ b/http/http_request.h
@@ -15,6 +15,7 @@
struct Request
{
boost::beast::http::request<boost::beast::http::string_body>& req;
+ boost::beast::http::fields& fields;
std::string_view url{};
QueryString urlParams{};
bool isSecure{false};
@@ -31,7 +32,7 @@
Request(
boost::beast::http::request<boost::beast::http::string_body>& reqIn) :
req(reqIn),
- body(reqIn.body())
+ fields(reqIn.base()), body(reqIn.body())
{
}
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index fd414aa..b7fe62c 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -1850,10 +1850,10 @@
{
std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
- auto generateonDemandLogCallback = [asyncResp](
- const boost::system::error_code
- ec,
- const std::string &resp) {
+ auto generateonDemandLogCallback = [asyncResp,
+ req](const boost::system::error_code
+ ec,
+ const std::string &resp) {
if (ec)
{
if (ec.value() == boost::system::errc::operation_not_supported)
@@ -1887,6 +1887,7 @@
"crashdump'");
task->startTimer(std::chrono::minutes(5));
task->populateResp(asyncResp->res);
+ task->payload.emplace(req);
};
crow::connections::systemBus->async_method_call(
std::move(generateonDemandLogCallback), crashdumpObject,
diff --git a/redfish-core/lib/task.hpp b/redfish-core/lib/task.hpp
index e95eb2e..e224d6c 100644
--- a/redfish-core/lib/task.hpp
+++ b/redfish-core/lib/task.hpp
@@ -32,6 +32,58 @@
constexpr bool completed = true;
+struct Payload
+{
+ Payload(const crow::Request &req) :
+ targetUri(req.url), httpOperation(req.methodString()),
+ httpHeaders(nlohmann::json::array())
+
+ {
+ using field_ns = boost::beast::http::field;
+ constexpr const std::array<boost::beast::http::field, 7>
+ headerWhitelist = {field_ns::accept, field_ns::accept_encoding,
+ field_ns::user_agent, field_ns::host,
+ field_ns::connection, field_ns::content_length,
+ field_ns::upgrade};
+
+ jsonBody = nlohmann::json::parse(req.body, nullptr, false);
+ if (jsonBody.is_discarded())
+ {
+ jsonBody = nullptr;
+ }
+
+ for (const auto &field : req.fields)
+ {
+ if (std::find(headerWhitelist.begin(), headerWhitelist.end(),
+ field.name()) == headerWhitelist.end())
+ {
+ continue;
+ }
+ std::string header;
+ header.reserve(field.name_string().size() + 2 +
+ field.value().size());
+ header += field.name_string();
+ header += ": ";
+ header += field.value();
+ httpHeaders.emplace_back(std::move(header));
+ }
+ }
+ Payload() = delete;
+
+ std::string targetUri;
+ std::string httpOperation;
+ nlohmann::json httpHeaders;
+ nlohmann::json jsonBody;
+};
+
+inline void to_json(nlohmann::json &j, const Payload &p)
+{
+ j = {{"TargetUri", p.targetUri},
+ {"HttpOperation", p.httpOperation},
+ {"HttpHeaders", p.httpHeaders},
+ {"JsonBody", p.jsonBody.dump()}};
+}
+
struct TaskData : std::enable_shared_from_this<TaskData>
{
private:
@@ -169,6 +221,7 @@
boost::asio::steady_timer timer;
std::unique_ptr<sdbusplus::bus::match::match> match;
std::optional<time_t> endTime;
+ std::optional<Payload> payload;
bool gave204 = false;
};
@@ -299,6 +352,10 @@
asyncResp->res.jsonValue["TaskMonitor"] =
"/redfish/v1/TaskService/Tasks/" + strParam + "/Monitor";
}
+ if (ptr->payload)
+ {
+ asyncResp->res.jsonValue["Payload"] = *(ptr->payload);
+ }
}
};
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 3ca7721..e9793eb 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -58,7 +58,8 @@
// Note that asyncResp can be either a valid pointer or nullptr. If nullptr
// then no asyncResp updates will occur
static void softwareInterfaceAdded(std::shared_ptr<AsyncResp> asyncResp,
- sdbusplus::message::message &m)
+ sdbusplus::message::message &m,
+ const crow::Request &req)
{
std::vector<std::pair<
std::string,
@@ -81,10 +82,10 @@
// Retrieve service and activate
crow::connections::systemBus->async_method_call(
- [objPath, asyncResp](
- const boost::system::error_code error_code,
- const std::vector<std::pair<
- std::string, std::vector<std::string>>> &objInfo) {
+ [objPath, asyncResp,
+ req](const boost::system::error_code error_code,
+ const std::vector<std::pair<
+ std::string, std::vector<std::string>>> &objInfo) {
if (error_code)
{
BMCWEB_LOG_DEBUG << "error_code = " << error_code;
@@ -188,6 +189,7 @@
objPath.str + "'");
task->startTimer(std::chrono::minutes(5));
task->populateResp(asyncResp->res);
+ task->payload.emplace(req);
}
fwUpdateInProgress = false;
},
@@ -244,9 +246,9 @@
}
});
- auto callback = [asyncResp](sdbusplus::message::message &m) {
+ auto callback = [asyncResp, req](sdbusplus::message::message &m) {
BMCWEB_LOG_DEBUG << "Match fired";
- softwareInterfaceAdded(asyncResp, m);
+ softwareInterfaceAdded(asyncResp, m, req);
};
fwUpdateInProgress = true;