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