1 #pragma once 2 3 #include "common.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/http/string_body.hpp> 10 #include <boost/beast/websocket.hpp> 11 #include <boost/url/url_view.hpp> 12 13 #include <string> 14 #include <string_view> 15 #include <system_error> 16 17 namespace crow 18 { 19 20 struct Request 21 { 22 boost::beast::http::request<boost::beast::http::string_body> req; 23 boost::beast::http::fields& fields; 24 std::string_view url{}; 25 boost::urls::url_view urlView{}; 26 27 bool isSecure{false}; 28 29 std::string& body; 30 31 boost::asio::io_context* ioService{}; 32 boost::asio::ip::address ipAddress{}; 33 34 std::shared_ptr<persistent_data::UserSession> session; 35 36 std::string userRole{}; 37 Request(boost::beast::http::request<boost::beast::http::string_body> reqIn, 38 std::error_code& ec) : 39 req(std::move(reqIn)), 40 fields(req.base()), body(req.body()) 41 { 42 if (!setUrlInfo()) 43 { 44 ec = std::make_error_code(std::errc::invalid_argument); 45 } 46 } 47 48 Request(const Request& other) : 49 req(other.req), fields(req.base()), isSecure(other.isSecure), 50 body(req.body()), ioService(other.ioService), 51 ipAddress(other.ipAddress), session(other.session), 52 userRole(other.userRole) 53 { 54 setUrlInfo(); 55 } 56 57 Request(Request&& other) noexcept : 58 req(std::move(other.req)), fields(req.base()), isSecure(other.isSecure), 59 body(req.body()), ioService(other.ioService), 60 ipAddress(std::move(other.ipAddress)), 61 session(std::move(other.session)), userRole(std::move(other.userRole)) 62 { 63 setUrlInfo(); 64 } 65 66 Request& operator=(const Request&) = delete; 67 Request& operator=(const Request&&) = delete; 68 ~Request() = default; 69 70 boost::beast::http::verb method() const 71 { 72 return req.method(); 73 } 74 75 std::string_view getHeaderValue(std::string_view key) const 76 { 77 return req[key]; 78 } 79 80 std::string_view getHeaderValue(boost::beast::http::field key) const 81 { 82 return req[key]; 83 } 84 85 std::string_view methodString() const 86 { 87 return req.method_string(); 88 } 89 90 std::string_view target() const 91 { 92 return req.target(); 93 } 94 95 bool target(const std::string_view target) 96 { 97 req.target(target); 98 return setUrlInfo(); 99 } 100 101 unsigned version() const 102 { 103 return req.version(); 104 } 105 106 bool isUpgrade() const 107 { 108 return boost::beast::websocket::is_upgrade(req); 109 } 110 111 bool keepAlive() const 112 { 113 return req.keep_alive(); 114 } 115 116 private: 117 bool setUrlInfo() 118 { 119 auto result = boost::urls::parse_relative_ref(target()); 120 121 if (!result) 122 { 123 return false; 124 } 125 urlView = *result; 126 url = urlView.encoded_path(); 127 return true; 128 } 129 }; 130 131 } // namespace crow 132