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