blob: 007b2622448d853a060d71a5ab81370e21b4def7 [file] [log] [blame]
Ed Tanousf4c99e72021-10-04 17:02:43 -07001#pragma once
2
Nan Zhoue796c262022-08-02 19:56:29 +00003#include "bmcweb_config.h"
4
5#include "app.hpp"
6#include "async_resp.hpp"
7#include "error_messages.hpp"
8#include "http_request.hpp"
9#include "http_response.hpp"
10#include "logging.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070011#include "utils/query_param.hpp"
12
Nan Zhoue796c262022-08-02 19:56:29 +000013#include <boost/beast/http/verb.hpp>
14#include <boost/url/params_view.hpp>
15#include <boost/url/url_view.hpp>
16
17#include <functional>
18#include <memory>
19#include <new>
20#include <optional>
21#include <string>
22#include <string_view>
23#include <type_traits>
24#include <utility>
25
26// IWYU pragma: no_forward_declare crow::App
27// IWYU pragma: no_include <boost/url/impl/params_view.hpp>
28// IWYU pragma: no_include <boost/url/impl/url_view.hpp>
Ed Tanousf4c99e72021-10-04 17:02:43 -070029
Carson Labrado05916ce2022-08-01 19:38:18 +000030#include <redfish_aggregator.hpp>
31
Ed Tanousf4c99e72021-10-04 17:02:43 -070032namespace redfish
33{
34
Nan Zhoua6b91252022-04-04 13:10:40 -070035// Sets up the Redfish Route and delegates some of the query parameter
36// processing. |queryCapabilities| stores which query parameters will be
37// handled by redfish-core/lib codes, then default query parameter handler won't
38// process these parameters.
39[[nodiscard]] inline bool setUpRedfishRouteWithDelegation(
Carson Labrado3ba00072022-06-06 19:40:56 +000040 crow::App& app, const crow::Request& req,
41 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Nan Zhoua6b91252022-04-04 13:10:40 -070042 query_param::Query& delegated,
43 const query_param::QueryCapabilities& queryCapabilities)
Ed Tanousf4c99e72021-10-04 17:02:43 -070044{
Ed Tanous142ec9a2022-03-24 18:20:45 -070045 BMCWEB_LOG_DEBUG << "setup redfish route";
46
47 // Section 7.4 of the redfish spec "Redfish Services shall process the
48 // [OData-Version header] in the following table as defined by the HTTP 1.1
49 // specification..."
50 // Required to pass redfish-protocol-validator REQ_HEADERS_ODATA_VERSION
51 std::string_view odataHeader = req.getHeaderValue("OData-Version");
52 if (!odataHeader.empty() && odataHeader != "4.0")
53 {
Carson Labrado3ba00072022-06-06 19:40:56 +000054 messages::preconditionFailed(asyncResp->res);
Ed Tanous142ec9a2022-03-24 18:20:45 -070055 return false;
56 }
57
Carson Labrado3ba00072022-06-06 19:40:56 +000058 asyncResp->res.addHeader("OData-Version", "4.0");
Ed Tanousc02a74f2022-05-11 14:46:44 -070059
Ed Tanousf4c99e72021-10-04 17:02:43 -070060 std::optional<query_param::Query> queryOpt =
Carson Labrado3ba00072022-06-06 19:40:56 +000061 query_param::parseParameters(req.urlView.params(), asyncResp->res);
Ed Tanousf4c99e72021-10-04 17:02:43 -070062 if (queryOpt == std::nullopt)
63 {
64 return false;
65 }
66
Carson Labrado05916ce2022-08-01 19:38:18 +000067 bool needToCallHandlers = true;
68
69#ifdef BMCWEB_ENABLE_REDFISH_AGGREGATION
70 needToCallHandlers = RedfishAggregator::getInstance().beginAggregation(
71 req, asyncResp) == Result::LocalHandle;
72
73 // If the request should be forwarded to a satellite BMC then we don't want
74 // to write anything to the asyncResp since it will get overwritten later.
75#endif
76
Ed Tanous7cf436c2022-03-22 23:53:51 -070077 // If this isn't a get, no need to do anything with parameters
78 if (req.method() != boost::beast::http::verb::get)
79 {
Carson Labrado05916ce2022-08-01 19:38:18 +000080 return needToCallHandlers;
Ed Tanous7cf436c2022-03-22 23:53:51 -070081 }
82
Nan Zhoua6b91252022-04-04 13:10:40 -070083 delegated = query_param::delegate(queryCapabilities, *queryOpt);
Ed Tanousf4c99e72021-10-04 17:02:43 -070084 std::function<void(crow::Response&)> handler =
Carson Labrado3ba00072022-06-06 19:40:56 +000085 asyncResp->res.releaseCompleteRequestHandler();
Nan Zhou827c4902022-08-03 04:57:55 +000086
Carson Labrado3ba00072022-06-06 19:40:56 +000087 asyncResp->res.setCompleteRequestHandler(
Ed Tanousf4c99e72021-10-04 17:02:43 -070088 [&app, handler(std::move(handler)),
Nan Zhou827c4902022-08-03 04:57:55 +000089 query{std::move(*queryOpt)}](crow::Response& resIn) mutable {
Ed Tanous8a592812022-06-04 09:06:59 -070090 processAllParams(app, query, handler, resIn);
Ed Tanous002d39b2022-05-31 08:59:27 -070091 });
Nan Zhou827c4902022-08-03 04:57:55 +000092
Carson Labrado05916ce2022-08-01 19:38:18 +000093 return needToCallHandlers;
Ed Tanousf4c99e72021-10-04 17:02:43 -070094}
Nan Zhoua6b91252022-04-04 13:10:40 -070095
96// Sets up the Redfish Route. All parameters are handled by the default handler.
Carson Labrado3ba00072022-06-06 19:40:56 +000097[[nodiscard]] inline bool
98 setUpRedfishRoute(crow::App& app, const crow::Request& req,
99 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Nan Zhoua6b91252022-04-04 13:10:40 -0700100{
101 // This route |delegated| is never used
102 query_param::Query delegated;
Carson Labrado3ba00072022-06-06 19:40:56 +0000103 return setUpRedfishRouteWithDelegation(app, req, asyncResp, delegated,
Nan Zhoua6b91252022-04-04 13:10:40 -0700104 query_param::QueryCapabilities{});
105}
Ed Tanousf4c99e72021-10-04 17:02:43 -0700106} // namespace redfish