| // SPDX-License-Identifier: Apache-2.0 | 
 | // SPDX-FileCopyrightText: Copyright OpenBMC Authors | 
 | #pragma once | 
 |  | 
 | #include "http_body.hpp" | 
 | #include "sessions.hpp" | 
 |  | 
 | #include <boost/asio/ip/address.hpp> | 
 | #include <boost/beast/http/field.hpp> | 
 | #include <boost/beast/http/fields.hpp> | 
 | #include <boost/beast/http/message.hpp> | 
 | #include <boost/beast/http/verb.hpp> | 
 | #include <boost/beast/websocket/rfc6455.hpp> | 
 | #include <boost/url/parse.hpp> | 
 | #include <boost/url/url.hpp> | 
 | #include <boost/url/url_view.hpp> | 
 |  | 
 | #include <memory> | 
 | #include <string> | 
 | #include <string_view> | 
 | #include <system_error> | 
 | #include <utility> | 
 |  | 
 | namespace crow | 
 | { | 
 |  | 
 | struct Request | 
 | { | 
 |     using Body = boost::beast::http::request<bmcweb::HttpBody>; | 
 |     Body req; | 
 |  | 
 |   private: | 
 |     boost::urls::url urlBase; | 
 |  | 
 |     Request(const Request& other) = default; | 
 |  | 
 |   public: | 
 |     boost::asio::ip::address ipAddress; | 
 |  | 
 |     std::shared_ptr<persistent_data::UserSession> session; | 
 |  | 
 |     std::string userRole; | 
 |     Request(Body&& reqIn, std::error_code& ec) : req(std::move(reqIn)) | 
 |     { | 
 |         if (!setUrlInfo()) | 
 |         { | 
 |             ec = std::make_error_code(std::errc::invalid_argument); | 
 |         } | 
 |     } | 
 |  | 
 |     Request(std::string_view bodyIn, std::error_code& /*ec*/) : req({}, bodyIn) | 
 |     {} | 
 |  | 
 |     Request() = default; | 
 |  | 
 |     Request(Request&& other) = default; | 
 |  | 
 |     Request& operator=(const Request&) = delete; | 
 |     Request& operator=(Request&&) = default; | 
 |     ~Request() = default; | 
 |  | 
 |     Request copy() const | 
 |     { | 
 |         return {*this}; | 
 |     } | 
 |  | 
 |     void addHeader(std::string_view key, std::string_view value) | 
 |     { | 
 |         req.insert(key, value); | 
 |     } | 
 |  | 
 |     void addHeader(boost::beast::http::field key, std::string_view value) | 
 |     { | 
 |         req.insert(key, value); | 
 |     } | 
 |  | 
 |     void clear() | 
 |     { | 
 |         req.clear(); | 
 |         urlBase.clear(); | 
 |         ipAddress = boost::asio::ip::address(); | 
 |         session = nullptr; | 
 |         userRole = ""; | 
 |     } | 
 |  | 
 |     boost::beast::http::verb method() const | 
 |     { | 
 |         return req.method(); | 
 |     } | 
 |  | 
 |     void method(boost::beast::http::verb verb) | 
 |     { | 
 |         req.method(verb); | 
 |     } | 
 |  | 
 |     std::string_view methodString() | 
 |     { | 
 |         return req.method_string(); | 
 |     } | 
 |  | 
 |     std::string_view getHeaderValue(std::string_view key) const | 
 |     { | 
 |         return req[key]; | 
 |     } | 
 |  | 
 |     std::string_view getHeaderValue(boost::beast::http::field key) const | 
 |     { | 
 |         return req[key]; | 
 |     } | 
 |  | 
 |     void clearHeader(boost::beast::http::field key) | 
 |     { | 
 |         req.erase(key); | 
 |     } | 
 |  | 
 |     std::string_view methodString() const | 
 |     { | 
 |         return req.method_string(); | 
 |     } | 
 |  | 
 |     std::string_view target() const | 
 |     { | 
 |         return req.target(); | 
 |     } | 
 |  | 
 |     boost::urls::url& url() | 
 |     { | 
 |         return urlBase; | 
 |     } | 
 |  | 
 |     boost::urls::url_view url() const | 
 |     { | 
 |         return {urlBase}; | 
 |     } | 
 |  | 
 |     const boost::beast::http::fields& fields() const | 
 |     { | 
 |         return req.base(); | 
 |     } | 
 |  | 
 |     const std::string& body() const | 
 |     { | 
 |         return req.body().str(); | 
 |     } | 
 |  | 
 |     bool target(std::string_view target) | 
 |     { | 
 |         req.target(target); | 
 |         return setUrlInfo(); | 
 |     } | 
 |  | 
 |     unsigned version() const | 
 |     { | 
 |         return req.version(); | 
 |     } | 
 |  | 
 |     bool isUpgrade() const | 
 |     { | 
 |         // NOLINTNEXTLINE(misc-include-cleaner) | 
 |         return boost::beast::websocket::is_upgrade(req); | 
 |     } | 
 |  | 
 |     bool keepAlive() const | 
 |     { | 
 |         return req.keep_alive(); | 
 |     } | 
 |  | 
 |   private: | 
 |     bool setUrlInfo() | 
 |     { | 
 |         auto result = boost::urls::parse_relative_ref(target()); | 
 |  | 
 |         if (!result) | 
 |         { | 
 |             return false; | 
 |         } | 
 |         urlBase = *result; | 
 |         return true; | 
 |     } | 
 | }; | 
 |  | 
 | } // namespace crow |