xref: /openbmc/bmcweb/redfish-core/include/query.hpp (revision 05916cef0fce4dd2532e1e7e33f6abc4dcf339be)
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