123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- /*
- * Copyright (c) 2017-2023 zhllxt
- *
- * author : zhllxt
- * email : 37792738@qq.com
- *
- * Distributed under the Boost Software License, Version 1.0. (See accompanying
- * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
- #ifndef __ASIO2_HTTP_REQUEST_IMPL_HPP__
- #define __ASIO2_HTTP_REQUEST_IMPL_HPP__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <asio2/base/detail/push_options.hpp>
- #include <asio2/base/define.hpp>
- #include <asio2/base/impl/user_data_cp.hpp>
- #include <asio2/http/detail/http_util.hpp>
- #include <asio2/http/detail/http_url.hpp>
- #ifdef ASIO2_HEADER_ONLY
- namespace bho::beast::websocket
- #else
- namespace boost::beast::websocket
- #endif
- {
- template <class> class listener;
- }
- namespace asio2::detail
- {
- ASIO2_CLASS_FORWARD_DECLARE_BASE;
- ASIO2_CLASS_FORWARD_DECLARE_TCP_BASE;
- ASIO2_CLASS_FORWARD_DECLARE_TCP_CLIENT;
- ASIO2_CLASS_FORWARD_DECLARE_TCP_SESSION;
- template<class Body, class Fields = http::fields>
- class http_request_impl_t
- : public http::message<true, Body, Fields>
- #ifdef ASIO2_ENABLE_HTTP_REQUEST_USER_DATA
- , public user_data_cp<http_request_impl_t<Body, Fields>>
- #endif
- {
- template <class> friend class beast::websocket::listener;
- ASIO2_CLASS_FRIEND_DECLARE_BASE;
- ASIO2_CLASS_FRIEND_DECLARE_TCP_BASE;
- ASIO2_CLASS_FRIEND_DECLARE_TCP_CLIENT;
- ASIO2_CLASS_FRIEND_DECLARE_TCP_SESSION;
- public:
- using self = http_request_impl_t<Body, Fields>;
- using super = http::message<true, Body, Fields>;
- using header_type = typename super::header_type;
- using body_type = typename super::body_type;
- public:
- /**
- * @brief constructor
- */
- template<typename... Args>
- explicit http_request_impl_t(Args&&... args)
- : super(std::forward<Args>(args)...)
- #ifdef ASIO2_ENABLE_HTTP_REQUEST_USER_DATA
- , user_data_cp<http_request_impl_t<Body, Fields>>()
- #endif
- {
- }
- http_request_impl_t(const http_request_impl_t& o)
- : super()
- #ifdef ASIO2_ENABLE_HTTP_REQUEST_USER_DATA
- , user_data_cp<http_request_impl_t<Body, Fields>>()
- #endif
- {
- this->base() = o.base();
- this->url_ = o.url_;
- this->ws_frame_type_ = o.ws_frame_type_;
- this->ws_frame_data_ = o.ws_frame_data_;
- }
- http_request_impl_t(http_request_impl_t&& o)
- : super()
- #ifdef ASIO2_ENABLE_HTTP_REQUEST_USER_DATA
- , user_data_cp<http_request_impl_t<Body, Fields>>()
- #endif
- {
- this->base() = std::move(o.base());
- this->url_ = std::move(o.url_);
- this->ws_frame_type_ = o.ws_frame_type_;
- this->ws_frame_data_ = o.ws_frame_data_;
- }
- self& operator=(const http_request_impl_t& o)
- {
- this->base() = o.base();
- this->url_ = o.url_;
- this->ws_frame_type_ = o.ws_frame_type_;
- this->ws_frame_data_ = o.ws_frame_data_;
- return *this;
- }
- self& operator=(http_request_impl_t&& o)
- {
- this->base() = std::move(o.base());
- this->url_ = std::move(o.url_);
- this->ws_frame_type_ = o.ws_frame_type_;
- this->ws_frame_data_ = o.ws_frame_data_;
- return *this;
- }
- http_request_impl_t(const http::message<true, Body, Fields>& req)
- : super()
- #ifdef ASIO2_ENABLE_HTTP_REQUEST_USER_DATA
- , user_data_cp<http_request_impl_t<Body, Fields>>()
- #endif
- {
- this->base() = req;
- }
- http_request_impl_t(http::message<true, Body, Fields>&& req)
- : super()
- #ifdef ASIO2_ENABLE_HTTP_REQUEST_USER_DATA
- , user_data_cp<http_request_impl_t<Body, Fields>>()
- #endif
- {
- this->base() = std::move(req);
- }
- self& operator=(const http::message<true, Body, Fields>& req)
- {
- this->base() = req;
- return *this;
- }
- self& operator=(http::message<true, Body, Fields>&& req)
- {
- this->base() = std::move(req);
- return *this;
- }
- /**
- * @brief destructor
- */
- ~http_request_impl_t()
- {
- }
- /// Returns the base portion of the message
- inline super const& base() const noexcept
- {
- return *this;
- }
- /// Returns the base portion of the message
- inline super& base() noexcept
- {
- return *this;
- }
- inline void reset()
- {
- static_cast<super&>(*this) = {};
- }
- public:
- /**
- * @brief Returns `true` if this HTTP request is a WebSocket Upgrade.
- */
- inline bool is_upgrade() const noexcept { return websocket::is_upgrade(*this); }
- /**
- * @brief Gets the content of the "schema" section, maybe empty
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- */
- inline std::string_view get_schema() const noexcept
- {
- return this->url_.schema();
- }
- /**
- * @brief Gets the content of the "schema" section, maybe empty
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- * same as get_schema
- */
- inline std::string_view schema() const noexcept
- {
- return this->get_schema();
- }
- /**
- * @brief Gets the content of the "host" section, maybe empty
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- */
- inline std::string_view get_host() const noexcept
- {
- return this->url_.host();
- }
- /**
- * @brief Gets the content of the "host" section, maybe empty
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- * same as get_host
- */
- inline std::string_view host() const noexcept
- {
- return this->get_host();
- }
- /**
- * @brief Gets the content of the "port" section, maybe empty
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- */
- inline std::string_view get_port() const noexcept
- {
- return this->url_.port();
- }
- /**
- * @brief Gets the content of the "port" section, maybe empty
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- * same as get_port
- */
- inline std::string_view port() const noexcept
- {
- return this->get_port();
- }
- /**
- * @brief Gets the content of the "path" section of the target
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- */
- inline std::string_view get_path() const
- {
- if (!this->url_.string().empty())
- return this->url_.path();
- if (!(this->url_.parser().field_set & (1 << (int)http::parses::url_fields::UF_PATH)))
- return std::string_view{ "/" };
- std::string_view target = this->target();
- return std::string_view{ &target[
- this->url_.parser().field_data[(int)http::parses::url_fields::UF_PATH].off],
- this->url_.parser().field_data[(int)http::parses::url_fields::UF_PATH].len };
- }
- /**
- * @brief Gets the content of the "path" section of the target
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- * same as get_path
- */
- inline std::string_view path() const
- {
- return this->get_path();
- }
- /**
- * @brief Gets the content of the "query" section of the target
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- */
- inline std::string_view get_query() const
- {
- if (!this->url_.string().empty())
- return this->url_.query();
- if (!(this->url_.parser().field_set & (1 << (int)http::parses::url_fields::UF_QUERY)))
- return std::string_view{};
- std::string_view target = this->target();
- return std::string_view{ &target[
- this->url_.parser().field_data[(int)http::parses::url_fields::UF_QUERY].off],
- this->url_.parser().field_data[(int)http::parses::url_fields::UF_QUERY].len };
- }
- /**
- * @brief Gets the content of the "query" section of the target
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- * same as get_query
- */
- inline std::string_view query() const
- {
- return this->get_query();
- }
- /**
- * @brief Returns `true` if this HTTP request's Content-Type is "multipart/form-data";
- */
- inline bool has_multipart() const noexcept
- {
- return http::has_multipart(*this);
- }
- /**
- * @brief Get the "multipart/form-data" body content.
- */
- inline decltype(auto) get_multipart()
- {
- return http::multipart(*this);
- }
- /**
- * @brief Get the "multipart/form-data" body content. same as get_multipart
- */
- inline decltype(auto) multipart()
- {
- return this->get_multipart();
- }
- /**
- * @brief Get the url object reference. same as get_url
- */
- inline http::url& url() { return this->url_; }
- /**
- * @brief Get the url object reference. same as get_url
- */
- inline http::url const& url() const { return this->url_; }
- /**
- * @brief Get the url object reference.
- */
- inline http::url& get_url() { return this->url_; }
- /**
- * @brief Get the url object reference.
- */
- inline http::url const& get_url() const { return this->url_; }
- protected:
- http::url url_{ "" };
- websocket::frame ws_frame_type_ = websocket::frame::unknown;
- std::string_view ws_frame_data_;
- };
- struct http_request_convert_helper
- {
- template<class Body, class Fields>
- void from(http::request<Body, Fields>) {}
- template<class Body, class Fields>
- void from(detail::http_request_impl_t<Body, Fields>) {}
- };
- template<typename T, typename = void>
- struct can_convert_to_http_request : std::false_type {};
- template<typename T>
- struct can_convert_to_http_request<T, std::void_t<decltype(std::declval<
- http_request_convert_helper>().from(std::declval<T>()))>> : std::true_type {};
- template<class T>
- inline constexpr bool can_convert_to_http_request_v =
- can_convert_to_http_request<detail::remove_cvref_t<T>>::value;
- }
- #ifdef ASIO2_HEADER_ONLY
- namespace bho::beast::http
- #else
- namespace boost::beast::http
- #endif
- {
- using web_request = asio2::detail::http_request_impl_t<http::string_body>;
- }
- #include <asio2/base/detail/pop_options.hpp>
- #endif // !__ASIO2_HTTP_REQUEST_IMPL_HPP__
|