xref: /openbmc/bmcweb/http/http_request.hpp (revision a529a6aa)
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     void method(boost::beast::http::verb verb)
79     {
80         req.method(verb);
81     }
82 
83     std::string_view getHeaderValue(std::string_view key) const
84     {
85         return req[key];
86     }
87 
88     std::string_view getHeaderValue(boost::beast::http::field key) const
89     {
90         return req[key];
91     }
92 
93     void clearHeader(boost::beast::http::field key)
94     {
95         req.erase(key);
96     }
97 
98     std::string_view methodString() const
99     {
100         return req.method_string();
101     }
102 
103     std::string_view target() const
104     {
105         return req.target();
106     }
107 
108     boost::urls::url_view url() const
109     {
110         return {urlBase};
111     }
112 
113     const boost::beast::http::fields& fields() const
114     {
115         return req.base();
116     }
117 
118     const std::string& body() const
119     {
120         return req.body().str();
121     }
122 
123     bool target(std::string_view target)
124     {
125         req.target(target);
126         return setUrlInfo();
127     }
128 
129     unsigned version() const
130     {
131         return req.version();
132     }
133 
134     bool isUpgrade() const
135     {
136         return boost::beast::websocket::is_upgrade(req);
137     }
138 
139     bool keepAlive() const
140     {
141         return req.keep_alive();
142     }
143 
144   private:
145     bool setUrlInfo()
146     {
147         auto result = boost::urls::parse_relative_ref(target());
148 
149         if (!result)
150         {
151             return false;
152         }
153         urlBase = *result;
154         return true;
155     }
156 };
157 
158 } // namespace crow
159