xref: /openbmc/bmcweb/http/http_request.hpp (revision 079360ae)
1 #pragma once
2 
3 #include "common.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/http/string_body.hpp>
10 #include <boost/beast/websocket.hpp>
11 #include <boost/url/url_view.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<boost::beast::http::string_body> req;
23     boost::beast::http::fields& fields;
24     std::string_view url{};
25     boost::urls::url_view urlView{};
26 
27     bool isSecure{false};
28 
29     std::string& body;
30 
31     boost::asio::io_context* ioService{};
32     boost::asio::ip::address ipAddress{};
33 
34     std::shared_ptr<persistent_data::UserSession> session;
35 
36     std::string userRole{};
37     Request(boost::beast::http::request<boost::beast::http::string_body> reqIn,
38             std::error_code& ec) :
39         req(std::move(reqIn)),
40         fields(req.base()), body(req.body())
41     {
42         if (!setUrlInfo())
43         {
44             ec = std::make_error_code(std::errc::invalid_argument);
45         }
46     }
47 
48     Request(const Request& other) :
49         req(other.req), fields(req.base()), isSecure(other.isSecure),
50         body(req.body()), ioService(other.ioService),
51         ipAddress(other.ipAddress), session(other.session),
52         userRole(other.userRole)
53     {
54         setUrlInfo();
55     }
56 
57     Request(Request&& other) noexcept :
58         req(std::move(other.req)), fields(req.base()), isSecure(other.isSecure),
59         body(req.body()), ioService(other.ioService),
60         ipAddress(std::move(other.ipAddress)),
61         session(std::move(other.session)), userRole(std::move(other.userRole))
62     {
63         setUrlInfo();
64     }
65 
66     Request& operator=(const Request&) = delete;
67     Request& operator=(const Request&&) = delete;
68     ~Request() = default;
69 
70     boost::beast::http::verb method() const
71     {
72         return req.method();
73     }
74 
75     std::string_view getHeaderValue(std::string_view key) const
76     {
77         return req[key];
78     }
79 
80     std::string_view getHeaderValue(boost::beast::http::field key) const
81     {
82         return req[key];
83     }
84 
85     std::string_view methodString() const
86     {
87         return req.method_string();
88     }
89 
90     std::string_view target() const
91     {
92         return req.target();
93     }
94 
95     bool target(const std::string_view target)
96     {
97         req.target(target);
98         return setUrlInfo();
99     }
100 
101     unsigned version() const
102     {
103         return req.version();
104     }
105 
106     bool isUpgrade() const
107     {
108         return boost::beast::websocket::is_upgrade(req);
109     }
110 
111     bool keepAlive() const
112     {
113         return req.keep_alive();
114     }
115 
116   private:
117     bool setUrlInfo()
118     {
119         auto result = boost::urls::parse_relative_ref(target());
120 
121         if (!result)
122         {
123             return false;
124         }
125         urlView = *result;
126         url = urlView.encoded_path();
127         return true;
128     }
129 };
130 
131 } // namespace crow
132