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