From 44c70412e763a63310ef9451f24714c4decef91a Mon Sep 17 00:00:00 2001 From: Ed Tanous Date: Sun, 31 Jul 2022 16:48:29 -0700 Subject: Add 405 handler for redfish Redfish has specific error messages for OperationNotSupported in the Base registry. This commit allows bmcweb to return both the correct return code (405) and the correct error message, while not effecting the rest of the tree. We didn't have the equivalent call in error_messages, so this adds the required call. Tested: GET /redfish/v1 returns ServiceRoot GET /redfish/v1/foo Returns 404 PATCH /redfish/v1 returns 405 OperationNotSupported POST /redfish/v1/Chassis returns 405 OperationNotSupported DELETE /redfish/v1/Chassis returns 405 ResourceCannotBeDeleted POST /redfish/v1/foo/bar Returns 404 Signed-off-by: Ed Tanous Change-Id: I6f980af7307af602344b65a12a2b7589cc9ec959 Signed-off-by: Carson Labrado --- redfish-core/include/error_messages.hpp | 8 ++++++++ redfish-core/lib/redfish_v1.hpp | 26 +++++++++++++++++++++++++ redfish-core/src/error_messages.cpp | 34 +++++++++++++++++++++++++-------- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp index 76052fcf15..50bcfa02bc 100644 --- a/redfish-core/include/error_messages.hpp +++ b/redfish-core/include/error_messages.hpp @@ -1033,6 +1033,14 @@ nlohmann::json insufficientStorage(); void insufficientStorage(crow::Response& res); +/** + * @brief Formats OperationNotAllowed message into JSON + * Message body: "he HTTP method is not allowed on this resource." + * @returns Message OperationNotAllowed formatted to JSON */ +nlohmann::json operationNotAllowed(); + +void operationNotAllowed(crow::Response& res); + } // namespace messages } // namespace redfish diff --git a/redfish-core/lib/redfish_v1.hpp b/redfish-core/lib/redfish_v1.hpp index 6aa3ee6d5a..8907709c42 100644 --- a/redfish-core/lib/redfish_v1.hpp +++ b/redfish-core/lib/redfish_v1.hpp @@ -46,6 +46,29 @@ inline void redfish404(App& app, const crow::Request& req, messages::resourceNotFound(asyncResp->res, "", nameStr); } +inline void redfish405(App& app, const crow::Request& req, + const std::shared_ptr& asyncResp, + const std::string& path) +{ + // If we fall to this route, we didn't have a more specific route, so return + // 405 + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + BMCWEB_LOG_ERROR << "405 on path " << path; + asyncResp->res.result(boost::beast::http::status::method_not_allowed); + if (req.method() == boost::beast::http::verb::delete_) + { + messages::resourceCannotBeDeleted(asyncResp->res); + } + else + { + messages::operationNotAllowed(asyncResp->res); + } +} + inline void jsonSchemaIndexGet(App& app, const crow::Request& req, const std::shared_ptr& asyncResp) @@ -138,6 +161,9 @@ inline void requestRoutesRedfish(App& app) // Note, this route must always be registered last BMCWEB_ROUTE(app, "/redfish/") .notFound()(std::bind_front(redfish404, std::ref(app))); + + BMCWEB_ROUTE(app, "/redfish/") + .methodNotAllowed()(std::bind_front(redfish405, std::ref(app))); } } // namespace redfish diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp index c6d27a9788..60689056f1 100644 --- a/redfish-core/src/error_messages.cpp +++ b/redfish-core/src/error_messages.cpp @@ -309,7 +309,7 @@ nlohmann::json resourceCannotBeDeleted(void) void resourceCannotBeDeleted(crow::Response& res) { - res.result(boost::beast::http::status::forbidden); + res.result(boost::beast::http::status::method_not_allowed); addMessageToErrorJson(res.jsonValue, resourceCannotBeDeleted()); } @@ -1673,13 +1673,6 @@ void passwordChangeRequired(crow::Response& res, messages::addMessageToJsonRoot(res.jsonValue, passwordChangeRequired(arg1)); } -void invalidUpload(crow::Response& res, std::string_view arg1, - std::string_view arg2) -{ - res.result(boost::beast::http::status::bad_request); - addMessageToErrorJson(res.jsonValue, invalidUpload(arg1, arg2)); -} - /** * @internal * @brief Formats InsufficientStorage message into JSON @@ -1698,6 +1691,31 @@ void insufficientStorage(crow::Response& res) addMessageToErrorJson(res.jsonValue, insufficientStorage()); } +/** + * @internal + * @brief Formats OperationNotAllowed message into JSON + * + * See header file for more information + * @endinternal + */ +nlohmann::json operationNotAllowed() +{ + return getLog(redfish::registries::base::Index::operationNotAllowed, {}); +} + +void operationNotAllowed(crow::Response& res) +{ + res.result(boost::beast::http::status::method_not_allowed); + addMessageToErrorJson(res.jsonValue, operationNotAllowed()); +} + +void invalidUpload(crow::Response& res, std::string_view arg1, + std::string_view arg2) +{ + res.result(boost::beast::http::status::bad_request); + addMessageToErrorJson(res.jsonValue, invalidUpload(arg1, arg2)); +} + /** * @internal * @brief Formats Invalid File message into JSON -- cgit v1.2.3