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 Request(const Request& other) = default; 36 37 public: 38 boost::asio::ip::address ipAddress; 39 40 std::shared_ptr<persistent_data::UserSession> session; 41 42 std::string userRole; Requestcrow::Request43 Request(Body reqIn, std::error_code& ec) : req(std::move(reqIn)) 44 { 45 if (!setUrlInfo()) 46 { 47 ec = std::make_error_code(std::errc::invalid_argument); 48 } 49 } 50 Requestcrow::Request51 Request(std::string_view bodyIn, std::error_code& /*ec*/) : req({}, bodyIn) 52 {} 53 54 Request() = default; 55 56 Request(Request&& other) = default; 57 58 Request& operator=(const Request&) = delete; 59 Request& operator=(Request&&) = default; 60 ~Request() = default; 61 copycrow::Request62 Request copy() const 63 { 64 return {*this}; 65 } 66 addHeadercrow::Request67 void addHeader(std::string_view key, std::string_view value) 68 { 69 req.insert(key, value); 70 } 71 addHeadercrow::Request72 void addHeader(boost::beast::http::field key, std::string_view value) 73 { 74 req.insert(key, value); 75 } 76 clearcrow::Request77 void clear() 78 { 79 req.clear(); 80 urlBase.clear(); 81 ipAddress = boost::asio::ip::address(); 82 session = nullptr; 83 userRole = ""; 84 } 85 methodcrow::Request86 boost::beast::http::verb method() const 87 { 88 return req.method(); 89 } 90 methodcrow::Request91 void method(boost::beast::http::verb verb) 92 { 93 req.method(verb); 94 } 95 methodStringcrow::Request96 std::string_view methodString() 97 { 98 return req.method_string(); 99 } 100 getHeaderValuecrow::Request101 std::string_view getHeaderValue(std::string_view key) const 102 { 103 return req[key]; 104 } 105 getHeaderValuecrow::Request106 std::string_view getHeaderValue(boost::beast::http::field key) const 107 { 108 return req[key]; 109 } 110 clearHeadercrow::Request111 void clearHeader(boost::beast::http::field key) 112 { 113 req.erase(key); 114 } 115 methodStringcrow::Request116 std::string_view methodString() const 117 { 118 return req.method_string(); 119 } 120 targetcrow::Request121 std::string_view target() const 122 { 123 return req.target(); 124 } 125 urlcrow::Request126 boost::urls::url& url() 127 { 128 return urlBase; 129 } 130 urlcrow::Request131 boost::urls::url_view url() const 132 { 133 return {urlBase}; 134 } 135 fieldscrow::Request136 const boost::beast::http::fields& fields() const 137 { 138 return req.base(); 139 } 140 bodycrow::Request141 const std::string& body() const 142 { 143 return req.body().str(); 144 } 145 targetcrow::Request146 bool target(std::string_view target) 147 { 148 req.target(target); 149 return setUrlInfo(); 150 } 151 versioncrow::Request152 unsigned version() const 153 { 154 return req.version(); 155 } 156 isUpgradecrow::Request157 bool isUpgrade() const 158 { 159 // NOLINTNEXTLINE(misc-include-cleaner) 160 return boost::beast::websocket::is_upgrade(req); 161 } 162 keepAlivecrow::Request163 bool keepAlive() const 164 { 165 return req.keep_alive(); 166 } 167 168 private: setUrlInfocrow::Request169 bool setUrlInfo() 170 { 171 auto result = boost::urls::parse_relative_ref(target()); 172 173 if (!result) 174 { 175 return false; 176 } 177 urlBase = *result; 178 return true; 179 } 180 }; 181 182 } // namespace crow 183