1 #pragma once
2 
3 #include "utils/query_param.hpp"
4 
5 #include <bmcweb_config.h>
6 
7 namespace redfish
8 {
9 
10 // Sets up the Redfish Route and delegates some of the query parameter
11 // processing. |queryCapabilities| stores which query parameters will be
12 // handled by redfish-core/lib codes, then default query parameter handler won't
13 // process these parameters.
14 [[nodiscard]] inline bool setUpRedfishRouteWithDelegation(
15     crow::App& app, const crow::Request& req,
16     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
17     query_param::Query& delegated,
18     const query_param::QueryCapabilities& queryCapabilities)
19 {
20     BMCWEB_LOG_DEBUG << "setup redfish route";
21 
22     // Section 7.4 of the redfish spec "Redfish Services shall process the
23     // [OData-Version header] in the following table as defined by the HTTP 1.1
24     // specification..."
25     // Required to pass redfish-protocol-validator REQ_HEADERS_ODATA_VERSION
26     std::string_view odataHeader = req.getHeaderValue("OData-Version");
27     if (!odataHeader.empty() && odataHeader != "4.0")
28     {
29         messages::preconditionFailed(asyncResp->res);
30         return false;
31     }
32 
33     asyncResp->res.addHeader("OData-Version", "4.0");
34 
35     std::optional<query_param::Query> queryOpt =
36         query_param::parseParameters(req.urlView.params(), asyncResp->res);
37     if (queryOpt == std::nullopt)
38     {
39         return false;
40     }
41 
42     // If this isn't a get, no need to do anything with parameters
43     if (req.method() != boost::beast::http::verb::get)
44     {
45         return true;
46     }
47 
48     delegated = query_param::delegate(queryCapabilities, *queryOpt);
49     std::function<void(crow::Response&)> handler =
50         asyncResp->res.releaseCompleteRequestHandler();
51     asyncResp->res.setCompleteRequestHandler(
52         [&app, handler(std::move(handler)),
53          query{*queryOpt}](crow::Response& res) mutable {
54         processAllParams(app, query, handler, res);
55     });
56     return true;
57 }
58 
59 // Sets up the Redfish Route. All parameters are handled by the default handler.
60 [[nodiscard]] inline bool
61     setUpRedfishRoute(crow::App& app, const crow::Request& req,
62                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
63 {
64     // This route |delegated| is never used
65     query_param::Query delegated;
66     return setUpRedfishRouteWithDelegation(app, req, asyncResp, delegated,
67                                            query_param::QueryCapabilities{});
68 }
69 } // namespace redfish
70