xref: /openbmc/bmcweb/http/http_request.hpp (revision 1873a04f43bb414408d1da9a5a775c05474603d2)
1 #pragma once
2 
3 #include "common.hpp"
4 #include "http_body.hpp"
5 #include "sessions.hpp"
6 
7 #include <boost/asio/io_context.hpp>
8 #include <boost/asio/ip/address.hpp>
9 #include <boost/beast/http/message.hpp>
10 #include <boost/beast/websocket.hpp>
11 #include <boost/url/url.hpp>
12 
13 #include <string>
14 #include <string_view>
15 #include <system_error>
16 
17 namespace crow
18 {
19 
20 struct Request
21 {
22     boost::beast::http::request<bmcweb::HttpBody> req;
23 
24   private:
25     boost::urls::url urlBase;
26 
27   public:
28     bool isSecure{false};
29 
30     boost::asio::io_context* ioService = nullptr;
31     boost::asio::ip::address ipAddress;
32 
33     std::shared_ptr<persistent_data::UserSession> session;
34 
35     std::string userRole;
36     Request(boost::beast::http::request<bmcweb::HttpBody> reqIn,
37             std::error_code& ec) :
38         req(std::move(reqIn))
39     {
40         if (!setUrlInfo())
41         {
42             ec = std::make_error_code(std::errc::invalid_argument);
43         }
44     }
45 
46     Request(std::string_view bodyIn, std::error_code& /*ec*/) : req({}, bodyIn)
47     {}
48 
49     Request() = default;
50 
51     Request(const Request& other) = default;
52     Request(Request&& other) = default;
53 
54     Request& operator=(const Request&) = default;
55     Request& operator=(Request&&) = default;
56     ~Request() = default;
57 
58     void addHeader(std::string_view key, std::string_view value)
59     {
60         req.insert(key, value);
61     }
62 
63     void addHeader(boost::beast::http::field key, std::string_view value)
64     {
65         req.insert(key, value);
66     }
67 
68     void clear()
69     {
70         req.clear();
71         urlBase.clear();
72         isSecure = false;
73         ioService = nullptr;
74         ipAddress = boost::asio::ip::address();
75         session = nullptr;
76         userRole = "";
77     }
78 
79     boost::beast::http::verb method() const
80     {
81         return req.method();
82     }
83     void method(boost::beast::http::verb verb)
84     {
85         return req.method(verb);
86     }
87 
88     std::string_view getHeaderValue(std::string_view key) const
89     {
90         return req[key];
91     }
92 
93     std::string_view getHeaderValue(boost::beast::http::field key) const
94     {
95         return req[key];
96     }
97 
98     void clearHeader(boost::beast::http::field key)
99     {
100         req.erase(key);
101     }
102 
103     std::string_view methodString() const
104     {
105         return req.method_string();
106     }
107 
108     std::string_view target() const
109     {
110         return req.target();
111     }
112 
113     boost::urls::url_view url() const
114     {
115         return {urlBase};
116     }
117 
118     const boost::beast::http::fields& fields() const
119     {
120         return req.base();
121     }
122 
123     const std::string& body() const
124     {
125         return req.body().str();
126     }
127 
128     bool target(std::string_view target)
129     {
130         req.target(target);
131         return setUrlInfo();
132     }
133 
134     unsigned version() const
135     {
136         return req.version();
137     }
138 
139     bool isUpgrade() const
140     {
141         return boost::beast::websocket::is_upgrade(req);
142     }
143 
144     bool keepAlive() const
145     {
146         return req.keep_alive();
147     }
148 
149   private:
150     bool setUrlInfo()
151     {
152         auto result = boost::urls::parse_relative_ref(target());
153 
154         if (!result)
155         {
156             return false;
157         }
158         urlBase = *result;
159         return true;
160     }
161 };
162 
163 } // namespace crow
164