xref: /openbmc/bmcweb/redfish-core/include/query.hpp (revision c02a74f8504bc42d6e03721aa426d043b6658820)
1f4c99e70SEd Tanous #pragma once
2f4c99e70SEd Tanous 
3f4c99e70SEd Tanous #include "utils/query_param.hpp"
4f4c99e70SEd Tanous 
5f4c99e70SEd Tanous #include <bmcweb_config.h>
6f4c99e70SEd Tanous 
7f4c99e70SEd Tanous namespace redfish
8f4c99e70SEd Tanous {
9f4c99e70SEd Tanous 
10a6b9125fSNan Zhou // Sets up the Redfish Route and delegates some of the query parameter
11a6b9125fSNan Zhou // processing. |queryCapabilities| stores which query parameters will be
12a6b9125fSNan Zhou // handled by redfish-core/lib codes, then default query parameter handler won't
13a6b9125fSNan Zhou // process these parameters.
14a6b9125fSNan Zhou [[nodiscard]] inline bool setUpRedfishRouteWithDelegation(
15a6b9125fSNan Zhou     crow::App& app, const crow::Request& req, crow::Response& res,
16a6b9125fSNan Zhou     query_param::Query& delegated,
17a6b9125fSNan Zhou     const query_param::QueryCapabilities& queryCapabilities)
18f4c99e70SEd Tanous {
19142ec9aeSEd Tanous     BMCWEB_LOG_DEBUG << "setup redfish route";
20142ec9aeSEd Tanous 
21142ec9aeSEd Tanous     // Section 7.4 of the redfish spec "Redfish Services shall process the
22142ec9aeSEd Tanous     // [OData-Version header] in the following table as defined by the HTTP 1.1
23142ec9aeSEd Tanous     // specification..."
24142ec9aeSEd Tanous     // Required to pass redfish-protocol-validator REQ_HEADERS_ODATA_VERSION
25142ec9aeSEd Tanous     std::string_view odataHeader = req.getHeaderValue("OData-Version");
26142ec9aeSEd Tanous     if (!odataHeader.empty() && odataHeader != "4.0")
27142ec9aeSEd Tanous     {
28142ec9aeSEd Tanous         messages::preconditionFailed(res);
29142ec9aeSEd Tanous         return false;
30142ec9aeSEd Tanous     }
31142ec9aeSEd Tanous 
32*c02a74f8SEd Tanous     res.addHeader("OData-Version", "4.0");
33*c02a74f8SEd Tanous 
34f4c99e70SEd Tanous     std::optional<query_param::Query> queryOpt =
35f4c99e70SEd Tanous         query_param::parseParameters(req.urlView.params(), res);
36f4c99e70SEd Tanous     if (queryOpt == std::nullopt)
37f4c99e70SEd Tanous     {
38f4c99e70SEd Tanous         return false;
39f4c99e70SEd Tanous     }
40f4c99e70SEd Tanous 
417cf436c9SEd Tanous     // If this isn't a get, no need to do anything with parameters
427cf436c9SEd Tanous     if (req.method() != boost::beast::http::verb::get)
437cf436c9SEd Tanous     {
447cf436c9SEd Tanous         return true;
457cf436c9SEd Tanous     }
467cf436c9SEd Tanous 
47a6b9125fSNan Zhou     delegated = query_param::delegate(queryCapabilities, *queryOpt);
48f4c99e70SEd Tanous     std::function<void(crow::Response&)> handler =
49f4c99e70SEd Tanous         res.releaseCompleteRequestHandler();
50f4c99e70SEd Tanous     res.setCompleteRequestHandler(
51f4c99e70SEd Tanous         [&app, handler(std::move(handler)),
52f4c99e70SEd Tanous          query{*queryOpt}](crow::Response& res) mutable {
537cf436c9SEd Tanous             processAllParams(app, query, handler, res);
54f4c99e70SEd Tanous         });
55f4c99e70SEd Tanous     return true;
56f4c99e70SEd Tanous }
57a6b9125fSNan Zhou 
58a6b9125fSNan Zhou // Sets up the Redfish Route. All parameters are handled by the default handler.
59a6b9125fSNan Zhou [[nodiscard]] inline bool setUpRedfishRoute(crow::App& app,
60a6b9125fSNan Zhou                                             const crow::Request& req,
61a6b9125fSNan Zhou                                             crow::Response& res)
62a6b9125fSNan Zhou {
63a6b9125fSNan Zhou     // This route |delegated| is never used
64a6b9125fSNan Zhou     query_param::Query delegated;
65a6b9125fSNan Zhou     return setUpRedfishRouteWithDelegation(app, req, res, delegated,
66a6b9125fSNan Zhou                                            query_param::QueryCapabilities{});
67a6b9125fSNan Zhou }
68f4c99e70SEd Tanous } // namespace redfish
69