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 using Body = boost::beast::http::request<bmcweb::HttpBody>; 22 Body req; 23 24 private: 25 boost::urls::url urlBase; 26 27 public: 28 bool isSecure{false}; 29 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 isSecure = false; 71 ioService = nullptr; 72 ipAddress = boost::asio::ip::address(); 73 session = nullptr; 74 userRole = ""; 75 } 76 77 boost::beast::http::verb method() const 78 { 79 return req.method(); 80 } 81 void method(boost::beast::http::verb verb) 82 { 83 req.method(verb); 84 } 85 86 std::string_view getHeaderValue(std::string_view key) const 87 { 88 return req[key]; 89 } 90 91 std::string_view getHeaderValue(boost::beast::http::field key) const 92 { 93 return req[key]; 94 } 95 96 void clearHeader(boost::beast::http::field key) 97 { 98 req.erase(key); 99 } 100 101 std::string_view methodString() const 102 { 103 return req.method_string(); 104 } 105 106 std::string_view target() const 107 { 108 return req.target(); 109 } 110 111 boost::urls::url_view url() const 112 { 113 return {urlBase}; 114 } 115 116 const boost::beast::http::fields& fields() const 117 { 118 return req.base(); 119 } 120 121 const std::string& body() const 122 { 123 return req.body().str(); 124 } 125 126 bool target(std::string_view target) 127 { 128 req.target(target); 129 return setUrlInfo(); 130 } 131 132 unsigned version() const 133 { 134 return req.version(); 135 } 136 137 bool isUpgrade() const 138 { 139 return boost::beast::websocket::is_upgrade(req); 140 } 141 142 bool keepAlive() const 143 { 144 return req.keep_alive(); 145 } 146 147 private: 148 bool setUrlInfo() 149 { 150 auto result = boost::urls::parse_relative_ref(target()); 151 152 if (!result) 153 { 154 return false; 155 } 156 urlBase = *result; 157 return true; 158 } 159 }; 160 161 } // namespace crow 162