xref: /openbmc/bmcweb/http/http_request.hpp (revision d98a2f9388b9cab1100d30de401da43c32c98ef4)
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/ip/address.hpp>
9 #include <boost/beast/http/field.hpp>
10 #include <boost/beast/http/fields.hpp>
11 #include <boost/beast/http/message.hpp>
12 #include <boost/beast/http/verb.hpp>
13 #include <boost/beast/websocket/rfc6455.hpp>
14 #include <boost/url/parse.hpp>
15 #include <boost/url/url.hpp>
16 #include <boost/url/url_view.hpp>
17 
18 #include <memory>
19 #include <string>
20 #include <string_view>
21 #include <system_error>
22 #include <utility>
23 
24 namespace crow
25 {
26 
27 struct Request
28 {
29     using Body = boost::beast::http::request<bmcweb::HttpBody>;
30     Body req;
31 
32   private:
33     boost::urls::url urlBase;
34 
35   public:
36     boost::asio::ip::address ipAddress;
37 
38     std::shared_ptr<persistent_data::UserSession> session;
39 
40     std::string userRole;
Requestcrow::Request41     Request(Body reqIn, std::error_code& ec) : req(std::move(reqIn))
42     {
43         if (!setUrlInfo())
44         {
45             ec = std::make_error_code(std::errc::invalid_argument);
46         }
47     }
48 
Requestcrow::Request49     Request(std::string_view bodyIn, std::error_code& /*ec*/) : req({}, bodyIn)
50     {}
51 
52     Request() = default;
53 
54     Request(const Request& other) = default;
55     Request(Request&& other) = default;
56 
57     Request& operator=(const Request&) = default;
58     Request& operator=(Request&&) = default;
59     ~Request() = default;
60 
addHeadercrow::Request61     void addHeader(std::string_view key, std::string_view value)
62     {
63         req.insert(key, value);
64     }
65 
addHeadercrow::Request66     void addHeader(boost::beast::http::field key, std::string_view value)
67     {
68         req.insert(key, value);
69     }
70 
clearcrow::Request71     void clear()
72     {
73         req.clear();
74         urlBase.clear();
75         ipAddress = boost::asio::ip::address();
76         session = nullptr;
77         userRole = "";
78     }
79 
methodcrow::Request80     boost::beast::http::verb method() const
81     {
82         return req.method();
83     }
84 
methodcrow::Request85     void method(boost::beast::http::verb verb)
86     {
87         req.method(verb);
88     }
89 
methodStringcrow::Request90     std::string_view methodString()
91     {
92         return req.method_string();
93     }
94 
getHeaderValuecrow::Request95     std::string_view getHeaderValue(std::string_view key) const
96     {
97         return req[key];
98     }
99 
getHeaderValuecrow::Request100     std::string_view getHeaderValue(boost::beast::http::field key) const
101     {
102         return req[key];
103     }
104 
clearHeadercrow::Request105     void clearHeader(boost::beast::http::field key)
106     {
107         req.erase(key);
108     }
109 
methodStringcrow::Request110     std::string_view methodString() const
111     {
112         return req.method_string();
113     }
114 
targetcrow::Request115     std::string_view target() const
116     {
117         return req.target();
118     }
119 
urlcrow::Request120     boost::urls::url& url()
121     {
122         return urlBase;
123     }
124 
urlcrow::Request125     boost::urls::url_view url() const
126     {
127         return {urlBase};
128     }
129 
fieldscrow::Request130     const boost::beast::http::fields& fields() const
131     {
132         return req.base();
133     }
134 
bodycrow::Request135     const std::string& body() const
136     {
137         return req.body().str();
138     }
139 
targetcrow::Request140     bool target(std::string_view target)
141     {
142         req.target(target);
143         return setUrlInfo();
144     }
145 
versioncrow::Request146     unsigned version() const
147     {
148         return req.version();
149     }
150 
isUpgradecrow::Request151     bool isUpgrade() const
152     {
153         // NOLINTNEXTLINE(misc-include-cleaner)
154         return boost::beast::websocket::is_upgrade(req);
155     }
156 
keepAlivecrow::Request157     bool keepAlive() const
158     {
159         return req.keep_alive();
160     }
161 
162   private:
setUrlInfocrow::Request163     bool setUrlInfo()
164     {
165         auto result = boost::urls::parse_relative_ref(target());
166 
167         if (!result)
168         {
169             return false;
170         }
171         urlBase = *result;
172         return true;
173     }
174 };
175 
176 } // namespace crow
177