summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJagpal Singh Gill <paligill@gmail.com>2024-04-18 02:06:14 +0300
committerEd Tanous <ed@tanous.net>2024-05-11 07:25:55 +0300
commitef93eab32e4e4157082ff16767408a610db2c190 (patch)
tree0544c5ca637863deda5953f60061dcf9e4ab919a
parenta1015048b6a60c06f9634c5756feaff8f12d5266 (diff)
downloadbmcweb-ef93eab32e4e4157082ff16767408a610db2c190.tar.xz
updateservice: refactor parse multi-part forms
Refactor parsing multi-part forms into a different function for using it in legacy vs start update flows. More more details refer to - https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/65738 https://gerrit.openbmc.org/c/openbmc/docs/+/65739 Tested: Used curl to test firmware update. Change-Id: I2ec1ec9f4ac04349a1fbd588664f2d51bae827ea Signed-off-by: Jagpal Singh Gill <paligill@gmail.com>
-rw-r--r--redfish-core/lib/update_service.hpp105
1 files changed, 72 insertions, 33 deletions
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 0d424dbb60..f66fe46a11 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -40,9 +40,11 @@
#include <array>
#include <filesystem>
+#include <memory>
#include <optional>
#include <string>
#include <string_view>
+#include <vector>
namespace redfish
{
@@ -690,22 +692,27 @@ inline void setApplyTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
"RequestedApplyTime", "ApplyTime", applyTimeNewVal);
}
-inline void
- updateMultipartContext(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const MultipartParser& parser)
+struct MultiPartUpdateParameters
+{
+ std::optional<std::string> applyTime;
+ std::string uploadData;
+ std::vector<boost::urls::url> targets;
+};
+
+inline std::optional<MultiPartUpdateParameters>
+ extractMultipartUpdateParameters(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ MultipartParser parser)
{
- const std::string* uploadData = nullptr;
- std::optional<std::string> applyTime = "OnReset";
- bool targetFound = false;
- for (const FormPart& formpart : parser.mime_fields)
+ MultiPartUpdateParameters multiRet;
+ for (FormPart& formpart : parser.mime_fields)
{
boost::beast::http::fields::const_iterator it =
formpart.fields.find("Content-Disposition");
if (it == formpart.fields.end())
{
BMCWEB_LOG_ERROR("Couldn't find Content-Disposition");
- return;
+ return std::nullopt;
}
BMCWEB_LOG_INFO("Parsing value {}", it->value());
@@ -726,63 +733,95 @@ inline void
if (param.second == "UpdateParameters")
{
- std::vector<std::string> targets;
+ std::vector<std::string> tempTargets;
nlohmann::json content =
nlohmann::json::parse(formpart.content);
nlohmann::json::object_t* obj =
content.get_ptr<nlohmann::json::object_t*>();
if (obj == nullptr)
{
- messages::propertyValueFormatError(asyncResp->res, targets,
- "UpdateParameters");
- return;
+ messages::propertyValueTypeError(
+ asyncResp->res, formpart.content, "UpdateParameters");
+ return std::nullopt;
}
if (!json_util::readJsonObject(
- *obj, asyncResp->res, "Targets", targets,
- "@Redfish.OperationApplyTime", applyTime))
+ *obj, asyncResp->res, "Targets", tempTargets,
+ "@Redfish.OperationApplyTime", multiRet.applyTime))
{
- return;
+ return std::nullopt;
}
- if (targets.size() != 1)
+
+ for (size_t urlIndex = 0; urlIndex < tempTargets.size();
+ urlIndex++)
{
- messages::propertyValueFormatError(asyncResp->res, targets,
- "Targets");
- return;
+ const std::string& target = tempTargets[urlIndex];
+ boost::system::result<boost::urls::url_view> url =
+ boost::urls::parse_origin_form(target);
+ if (!url)
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, target,
+ std::format("Targets/{}", urlIndex));
+ return std::nullopt;
+ }
+ multiRet.targets.emplace_back(*url);
}
- if (targets[0] != "/redfish/v1/Managers/bmc")
+ if (multiRet.targets.size() != 1)
{
- messages::propertyValueNotInList(asyncResp->res, targets[0],
- "Targets/0");
- return;
+ messages::propertyValueFormatError(
+ asyncResp->res, multiRet.targets, "Targets");
+ return std::nullopt;
+ }
+ if (multiRet.targets[0].path() != "/redfish/v1/Managers/bmc")
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, multiRet.targets[0], "Targets/0");
+ return std::nullopt;
}
- targetFound = true;
}
else if (param.second == "UpdateFile")
{
- uploadData = &(formpart.content);
+ multiRet.uploadData = std::move(formpart.content);
}
}
}
- if (uploadData == nullptr)
+ if (multiRet.uploadData.empty())
{
BMCWEB_LOG_ERROR("Upload data is NULL");
messages::propertyMissing(asyncResp->res, "UpdateFile");
- return;
+ return std::nullopt;
}
- if (!targetFound)
+ if (multiRet.targets.empty())
+ {
+ messages::propertyMissing(asyncResp->res, "Targets");
+ return std::nullopt;
+ }
+ return multiRet;
+}
+
+inline void
+ updateMultipartContext(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const crow::Request& req, MultipartParser&& parser)
+{
+ std::optional<MultiPartUpdateParameters> multipart =
+ extractMultipartUpdateParameters(asyncResp, std::move(parser));
+ if (!multipart)
{
- messages::propertyMissing(asyncResp->res, "targets");
return;
}
+ if (!multipart->applyTime)
+ {
+ multipart->applyTime = "OnReset";
+ }
- setApplyTime(asyncResp, *applyTime);
+ setApplyTime(asyncResp, *multipart->applyTime);
// Setup callback for when new software detected
monitorForSoftwareAvailable(asyncResp, req, "/redfish/v1/UpdateService");
- uploadImageFile(asyncResp->res, *uploadData);
+ uploadImageFile(asyncResp->res, multipart->uploadData);
}
inline void
@@ -821,7 +860,7 @@ inline void
return;
}
- updateMultipartContext(asyncResp, req, parser);
+ updateMultipartContext(asyncResp, req, std::move(parser));
}
else
{