xref: /openbmc/bmcweb/http/http_request.hpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 #pragma once
4 
5 #include "http_body.hpp"
6 #include "sessions.hpp"
7 
8 #include <boost/asio/io_context.hpp>
9 #include <boost/asio/ip/address.hpp>
10 #include <boost/beast/http/message.hpp>
11 #include <boost/beast/websocket.hpp>
12 #include <boost/url/url.hpp>
13 
14 #include <string>
15 #include <string_view>
16 #include <system_error>
17 
18 namespace crow
19 {
20 
21 struct Request
22 {
23     using Body = boost::beast::http::request<bmcweb::HttpBody>;
24     Body req;
25 
26   private:
27     boost::urls::url urlBase;
28 
29   public:
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         ioService = nullptr;
71         ipAddress = boost::asio::ip::address();
72         session = nullptr;
73         userRole = "";
74     }
75 
76     boost::beast::http::verb method() const
77     {
78         return req.method();
79     }
80 
81     void method(boost::beast::http::verb verb)
82     {
83         req.method(verb);
84     }
85 
86     std::string_view methodString()
87     {
88         return req.method_string();
89     }
90 
91     std::string_view getHeaderValue(std::string_view key) const
92     {
93         return req[key];
94     }
95 
96     std::string_view getHeaderValue(boost::beast::http::field key) const
97     {
98         return req[key];
99     }
100 
101     void clearHeader(boost::beast::http::field key)
102     {
103         req.erase(key);
104     }
105 
106     std::string_view methodString() const
107     {
108         return req.method_string();
109     }
110 
111     std::string_view target() const
112     {
113         return req.target();
114     }
115 
116     boost::urls::url& url()
117     {
118         return urlBase;
119     }
120 
121     boost::urls::url_view url() const
122     {
123         return {urlBase};
124     }
125 
126     const boost::beast::http::fields& fields() const
127     {
128         return req.base();
129     }
130 
131     const std::string& body() const
132     {
133         return req.body().str();
134     }
135 
136     bool target(std::string_view target)
137     {
138         req.target(target);
139         return setUrlInfo();
140     }
141 
142     unsigned version() const
143     {
144         return req.version();
145     }
146 
147     bool isUpgrade() const
148     {
149         return boost::beast::websocket::is_upgrade(req);
150     }
151 
152     bool keepAlive() const
153     {
154         return req.keep_alive();
155     }
156 
157   private:
158     bool setUrlInfo()
159     {
160         auto result = boost::urls::parse_relative_ref(target());
161 
162         if (!result)
163         {
164             return false;
165         }
166         urlBase = *result;
167         return true;
168     }
169 };
170 
171 } // namespace crow
172