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 boost::asio::io_context* ioService = nullptr; 29 boost::asio::ip::address ipAddress; 30 31 std::shared_ptr<persistent_data::UserSession> session; 32 33 std::string userRole; 34 Request(Body reqIn, std::error_code& ec) : req(std::move(reqIn)) 35 { 36 if (!setUrlInfo()) 37 { 38 ec = std::make_error_code(std::errc::invalid_argument); 39 } 40 } 41 42 Request(std::string_view bodyIn, std::error_code& /*ec*/) : req({}, bodyIn) 43 {} 44 45 Request() = default; 46 47 Request(const Request& other) = default; 48 Request(Request&& other) = default; 49 50 Request& operator=(const Request&) = default; 51 Request& operator=(Request&&) = default; 52 ~Request() = default; 53 54 void addHeader(std::string_view key, std::string_view value) 55 { 56 req.insert(key, value); 57 } 58 59 void addHeader(boost::beast::http::field key, std::string_view value) 60 { 61 req.insert(key, value); 62 } 63 64 void clear() 65 { 66 req.clear(); 67 urlBase.clear(); 68 ioService = nullptr; 69 ipAddress = boost::asio::ip::address(); 70 session = nullptr; 71 userRole = ""; 72 } 73 74 boost::beast::http::verb method() const 75 { 76 return req.method(); 77 } 78 79 void method(boost::beast::http::verb verb) 80 { 81 req.method(verb); 82 } 83 84 std::string_view methodString() 85 { 86 return req.method_string(); 87 } 88 89 std::string_view getHeaderValue(std::string_view key) const 90 { 91 return req[key]; 92 } 93 94 std::string_view getHeaderValue(boost::beast::http::field key) const 95 { 96 return req[key]; 97 } 98 99 void clearHeader(boost::beast::http::field key) 100 { 101 req.erase(key); 102 } 103 104 std::string_view methodString() const 105 { 106 return req.method_string(); 107 } 108 109 std::string_view target() const 110 { 111 return req.target(); 112 } 113 114 boost::urls::url_view url() const 115 { 116 return {urlBase}; 117 } 118 119 const boost::beast::http::fields& fields() const 120 { 121 return req.base(); 122 } 123 124 const std::string& body() const 125 { 126 return req.body().str(); 127 } 128 129 bool target(std::string_view target) 130 { 131 req.target(target); 132 return setUrlInfo(); 133 } 134 135 unsigned version() const 136 { 137 return req.version(); 138 } 139 140 bool isUpgrade() const 141 { 142 return boost::beast::websocket::is_upgrade(req); 143 } 144 145 bool keepAlive() const 146 { 147 return req.keep_alive(); 148 } 149 150 private: 151 bool setUrlInfo() 152 { 153 auto result = boost::urls::parse_relative_ref(target()); 154 155 if (!result) 156 { 157 return false; 158 } 159 urlBase = *result; 160 return true; 161 } 162 }; 163 164 } // namespace crow 165