xref: /openbmc/bmcweb/http/http_request.hpp (revision 608ad2cc0e17bf62ff34bae7ceb499816fe13fbb)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 #pragma once
4 
5 #include "http_body.hpp"
6 #include "sessions.hpp"
7 
8 #include <boost/asio/ip/address.hpp>
9 #include <boost/beast/http/field.hpp>
10 #include <boost/beast/http/fields.hpp>
11 #include <boost/beast/http/message.hpp>
12 #include <boost/beast/http/verb.hpp>
13 #include <boost/beast/websocket/rfc6455.hpp>
14 #include <boost/url/parse.hpp>
15 #include <boost/url/url.hpp>
16 #include <boost/url/url_view.hpp>
17 
18 #include <memory>
19 #include <string>
20 #include <string_view>
21 #include <system_error>
22 #include <utility>
23 
24 namespace crow
25 {
26 
27 struct Request
28 {
29     using Body = boost::beast::http::request<bmcweb::HttpBody>;
30     Body req;
31 
32   private:
33     boost::urls::url urlBase;
34 
35     Request(const Request& other) = default;
36 
37   public:
38     boost::asio::ip::address ipAddress;
39 
40     std::shared_ptr<persistent_data::UserSession> session;
41 
42     std::string userRole;
Requestcrow::Request43     Request(Body reqIn, std::error_code& ec) : req(std::move(reqIn))
44     {
45         if (!setUrlInfo())
46         {
47             ec = std::make_error_code(std::errc::invalid_argument);
48         }
49     }
50 
Requestcrow::Request51     Request(std::string_view bodyIn, std::error_code& /*ec*/) : req({}, bodyIn)
52     {}
53 
54     Request() = default;
55 
56     Request(Request&& other) = default;
57 
58     Request& operator=(const Request&) = delete;
59     Request& operator=(Request&&) = default;
60     ~Request() = default;
61 
copycrow::Request62     Request copy() const
63     {
64         return {*this};
65     }
66 
addHeadercrow::Request67     void addHeader(std::string_view key, std::string_view value)
68     {
69         req.insert(key, value);
70     }
71 
addHeadercrow::Request72     void addHeader(boost::beast::http::field key, std::string_view value)
73     {
74         req.insert(key, value);
75     }
76 
clearcrow::Request77     void clear()
78     {
79         req.clear();
80         urlBase.clear();
81         ipAddress = boost::asio::ip::address();
82         session = nullptr;
83         userRole = "";
84     }
85 
methodcrow::Request86     boost::beast::http::verb method() const
87     {
88         return req.method();
89     }
90 
methodcrow::Request91     void method(boost::beast::http::verb verb)
92     {
93         req.method(verb);
94     }
95 
methodStringcrow::Request96     std::string_view methodString()
97     {
98         return req.method_string();
99     }
100 
getHeaderValuecrow::Request101     std::string_view getHeaderValue(std::string_view key) const
102     {
103         return req[key];
104     }
105 
getHeaderValuecrow::Request106     std::string_view getHeaderValue(boost::beast::http::field key) const
107     {
108         return req[key];
109     }
110 
clearHeadercrow::Request111     void clearHeader(boost::beast::http::field key)
112     {
113         req.erase(key);
114     }
115 
methodStringcrow::Request116     std::string_view methodString() const
117     {
118         return req.method_string();
119     }
120 
targetcrow::Request121     std::string_view target() const
122     {
123         return req.target();
124     }
125 
urlcrow::Request126     boost::urls::url& url()
127     {
128         return urlBase;
129     }
130 
urlcrow::Request131     boost::urls::url_view url() const
132     {
133         return {urlBase};
134     }
135 
fieldscrow::Request136     const boost::beast::http::fields& fields() const
137     {
138         return req.base();
139     }
140 
bodycrow::Request141     const std::string& body() const
142     {
143         return req.body().str();
144     }
145 
targetcrow::Request146     bool target(std::string_view target)
147     {
148         req.target(target);
149         return setUrlInfo();
150     }
151 
versioncrow::Request152     unsigned version() const
153     {
154         return req.version();
155     }
156 
isUpgradecrow::Request157     bool isUpgrade() const
158     {
159         // NOLINTNEXTLINE(misc-include-cleaner)
160         return boost::beast::websocket::is_upgrade(req);
161     }
162 
keepAlivecrow::Request163     bool keepAlive() const
164     {
165         return req.keep_alive();
166     }
167 
168   private:
setUrlInfocrow::Request169     bool setUrlInfo()
170     {
171         auto result = boost::urls::parse_relative_ref(target());
172 
173         if (!result)
174         {
175             return false;
176         }
177         urlBase = *result;
178         return true;
179     }
180 };
181 
182 } // namespace crow
183