1f4c99e70SEd Tanous #pragma once 2f4c99e70SEd Tanous 3e796c262SNan Zhou #include "bmcweb_config.h" 4e796c262SNan Zhou 5e796c262SNan Zhou #include "app.hpp" 6e796c262SNan Zhou #include "async_resp.hpp" 7e796c262SNan Zhou #include "error_messages.hpp" 8e796c262SNan Zhou #include "http_request.hpp" 9e796c262SNan Zhou #include "http_response.hpp" 10e796c262SNan Zhou #include "logging.hpp" 11f4c99e70SEd Tanous #include "utils/query_param.hpp" 12f4c99e70SEd Tanous 13e796c262SNan Zhou #include <boost/beast/http/verb.hpp> 14e796c262SNan Zhou #include <boost/url/params_view.hpp> 15e796c262SNan Zhou #include <boost/url/url_view.hpp> 16e796c262SNan Zhou 17e796c262SNan Zhou #include <functional> 18e796c262SNan Zhou #include <memory> 19e796c262SNan Zhou #include <new> 20e796c262SNan Zhou #include <optional> 21e796c262SNan Zhou #include <string> 22e796c262SNan Zhou #include <string_view> 23e796c262SNan Zhou #include <type_traits> 24e796c262SNan Zhou #include <utility> 25e796c262SNan Zhou 26e796c262SNan Zhou // IWYU pragma: no_forward_declare crow::App 27e796c262SNan Zhou // IWYU pragma: no_include <boost/url/impl/params_view.hpp> 28e796c262SNan Zhou // IWYU pragma: no_include <boost/url/impl/url_view.hpp> 29f4c99e70SEd Tanous 30*05916cefSCarson Labrado #include <redfish_aggregator.hpp> 31*05916cefSCarson Labrado 32f4c99e70SEd Tanous namespace redfish 33f4c99e70SEd Tanous { 34f4c99e70SEd Tanous 35a6b9125fSNan Zhou // Sets up the Redfish Route and delegates some of the query parameter 36a6b9125fSNan Zhou // processing. |queryCapabilities| stores which query parameters will be 37a6b9125fSNan Zhou // handled by redfish-core/lib codes, then default query parameter handler won't 38a6b9125fSNan Zhou // process these parameters. 39a6b9125fSNan Zhou [[nodiscard]] inline bool setUpRedfishRouteWithDelegation( 403ba00073SCarson Labrado crow::App& app, const crow::Request& req, 413ba00073SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 42a6b9125fSNan Zhou query_param::Query& delegated, 43a6b9125fSNan Zhou const query_param::QueryCapabilities& queryCapabilities) 44f4c99e70SEd Tanous { 45142ec9aeSEd Tanous BMCWEB_LOG_DEBUG << "setup redfish route"; 46142ec9aeSEd Tanous 47142ec9aeSEd Tanous // Section 7.4 of the redfish spec "Redfish Services shall process the 48142ec9aeSEd Tanous // [OData-Version header] in the following table as defined by the HTTP 1.1 49142ec9aeSEd Tanous // specification..." 50142ec9aeSEd Tanous // Required to pass redfish-protocol-validator REQ_HEADERS_ODATA_VERSION 51142ec9aeSEd Tanous std::string_view odataHeader = req.getHeaderValue("OData-Version"); 52142ec9aeSEd Tanous if (!odataHeader.empty() && odataHeader != "4.0") 53142ec9aeSEd Tanous { 543ba00073SCarson Labrado messages::preconditionFailed(asyncResp->res); 55142ec9aeSEd Tanous return false; 56142ec9aeSEd Tanous } 57142ec9aeSEd Tanous 583ba00073SCarson Labrado asyncResp->res.addHeader("OData-Version", "4.0"); 59c02a74f8SEd Tanous 60f4c99e70SEd Tanous std::optional<query_param::Query> queryOpt = 613ba00073SCarson Labrado query_param::parseParameters(req.urlView.params(), asyncResp->res); 62f4c99e70SEd Tanous if (queryOpt == std::nullopt) 63f4c99e70SEd Tanous { 64f4c99e70SEd Tanous return false; 65f4c99e70SEd Tanous } 66f4c99e70SEd Tanous 67*05916cefSCarson Labrado bool needToCallHandlers = true; 68*05916cefSCarson Labrado 69*05916cefSCarson Labrado #ifdef BMCWEB_ENABLE_REDFISH_AGGREGATION 70*05916cefSCarson Labrado needToCallHandlers = RedfishAggregator::getInstance().beginAggregation( 71*05916cefSCarson Labrado req, asyncResp) == Result::LocalHandle; 72*05916cefSCarson Labrado 73*05916cefSCarson Labrado // If the request should be forwarded to a satellite BMC then we don't want 74*05916cefSCarson Labrado // to write anything to the asyncResp since it will get overwritten later. 75*05916cefSCarson Labrado #endif 76*05916cefSCarson Labrado 777cf436c9SEd Tanous // If this isn't a get, no need to do anything with parameters 787cf436c9SEd Tanous if (req.method() != boost::beast::http::verb::get) 797cf436c9SEd Tanous { 80*05916cefSCarson Labrado return needToCallHandlers; 817cf436c9SEd Tanous } 827cf436c9SEd Tanous 83a6b9125fSNan Zhou delegated = query_param::delegate(queryCapabilities, *queryOpt); 84f4c99e70SEd Tanous std::function<void(crow::Response&)> handler = 853ba00073SCarson Labrado asyncResp->res.releaseCompleteRequestHandler(); 86827c4902SNan Zhou 873ba00073SCarson Labrado asyncResp->res.setCompleteRequestHandler( 88f4c99e70SEd Tanous [&app, handler(std::move(handler)), 89827c4902SNan Zhou query{std::move(*queryOpt)}](crow::Response& resIn) mutable { 908a592810SEd Tanous processAllParams(app, query, handler, resIn); 91f4c99e70SEd Tanous }); 92827c4902SNan Zhou 93*05916cefSCarson Labrado return needToCallHandlers; 94f4c99e70SEd Tanous } 95a6b9125fSNan Zhou 96a6b9125fSNan Zhou // Sets up the Redfish Route. All parameters are handled by the default handler. 973ba00073SCarson Labrado [[nodiscard]] inline bool 983ba00073SCarson Labrado setUpRedfishRoute(crow::App& app, const crow::Request& req, 993ba00073SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 100a6b9125fSNan Zhou { 101a6b9125fSNan Zhou // This route |delegated| is never used 102a6b9125fSNan Zhou query_param::Query delegated; 1033ba00073SCarson Labrado return setUpRedfishRouteWithDelegation(app, req, asyncResp, delegated, 104a6b9125fSNan Zhou query_param::QueryCapabilities{}); 105a6b9125fSNan Zhou } 106f4c99e70SEd Tanous } // namespace redfish 107