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