123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- /*
- * 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_URL_HPP__
- #define __ASIO2_HTTP_URL_HPP__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <asio2/http/detail/http_util.hpp>
- #ifdef ASIO2_HEADER_ONLY
- namespace bho::beast::http
- #else
- namespace boost::beast::http
- #endif
- {
- /**
- * The object wrapped for a url string like "http://www.github.com"
- * <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fragment>
- */
- class url
- {
- public:
- /**
- * @brief constructor
- */
- url()
- {
- this->reset("");
- }
- /**
- * @brief constructor
- */
- url(std::string str)
- {
- this->reset(std::move(str));
- }
- url(std::string_view str)
- {
- this->reset(str);
- }
- url(const char* str)
- {
- this->reset(str);
- }
- url(url&&) noexcept = default;
- url(url const&) = default;
- url& operator=(url&&) noexcept = default;
- url& operator=(url const&) = default;
- url& reset(std::string str)
- {
- string_ = std::move(str);
- std::memset((void*)(std::addressof(parser_)), 0, sizeof(http::parses::http_parser_url));
- if (!string_.empty())
- {
- if (0 != http::parses::http_parser_parse_url(
- string_.data(), string_.size(), 0, std::addressof(parser_)))
- {
- asio2::set_last_error(asio::error::invalid_argument);
- }
- }
- return *this;
- }
- url& reset(std::string_view str)
- {
- return reset(std::string(str));
- }
- url& reset(const char* str)
- {
- return reset(std::string(str));
- }
- /**
- * @brief Gets the content of the "schema" section, maybe empty
- * The return value is usually http or https
- */
- inline std::string_view get_schema() const noexcept
- {
- return this->field(http::parses::url_fields::UF_SCHEMA);
- }
- /**
- * @brief Gets the content of the "schema" section, maybe empty
- * The return value is usually http or https
- * 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
- */
- inline std::string_view get_host() const noexcept
- {
- return this->field(http::parses::url_fields::UF_HOST);
- }
- /**
- * @brief Gets the content of the "host" section, maybe empty
- * same as get_host
- */
- inline std::string_view host() const noexcept
- {
- return this->get_host();
- }
- inline std::string_view get_default_port() const noexcept
- {
- std::string_view schema = this->schema();
- if (asio2::iequals(schema, "http"))
- return std::string_view{ "80" };
- if (asio2::iequals(schema, "https"))
- return std::string_view{ "443" };
- return std::string_view{ "80" };
- }
- inline std::string_view default_port() const noexcept
- {
- return this->get_default_port();
- }
- /**
- * @brief Gets the content of the "port" section
- */
- inline std::string_view get_port() const noexcept
- {
- std::string_view p = this->field(http::parses::url_fields::UF_PORT);
- if (p.empty())
- return this->default_port();
- return p;
- }
- /**
- * @brief Gets the content of the "port" section
- * same as get_port
- */
- inline std::string_view port() const noexcept
- {
- return this->get_port();
- }
- /**
- * @brief Gets the content of the "path" section
- * the return value maybe has undecoded char, you can use http::url_decode(...) to decoded it.
- */
- inline std::string_view get_path() const noexcept
- {
- std::string_view p = this->field(http::parses::url_fields::UF_PATH);
- if (p.empty())
- return std::string_view{ "/" };
- return p;
- }
- /**
- * @brief Gets the content of the "path" section
- * the return value maybe has undecoded char, you can use http::url_decode(...) to decoded it.
- * same as get_path
- */
- inline std::string_view path() const noexcept
- {
- return this->get_path();
- }
- /**
- * @brief Gets the content of the "query" section, maybe empty
- * the return value maybe has undecoded char, you can use http::url_decode(...) to decoded it.
- */
- inline std::string_view get_query() const noexcept
- {
- return this->field(http::parses::url_fields::UF_QUERY);
- }
- /**
- * @brief Gets the content of the "query" section, maybe empty
- * the return value maybe has undecoded char, you can use http::url_decode(...) to decoded it.
- * same as get_query
- */
- inline std::string_view query() const noexcept
- {
- return this->get_query();
- }
- /**
- * @brief Gets the "target", which composed by path and query
- * the return value maybe has undecoded char, you can use http::url_decode(...) to decoded it.
- */
- inline std::string_view get_target() const noexcept
- {
- if (parser_.field_set & (1 << (int)http::parses::url_fields::UF_PATH))
- {
- return std::string_view{ &string_[
- parser_.field_data[(int)http::parses::url_fields::UF_PATH].off],
- string_.size() -
- parser_.field_data[(int)http::parses::url_fields::UF_PATH].off };
- }
- return std::string_view{ "/" };
- }
- /**
- * @brief Gets the "target", which composed by path and query
- * the return value maybe has undecoded char, you can use http::url_decode(...) to decoded it.
- * same as get_target
- */
- inline std::string_view target() const noexcept
- {
- return this->get_target();
- }
- /**
- * @brief Gets the content of the specific section, maybe empty
- */
- inline std::string_view get_field(http::parses::url_fields f) const noexcept
- {
- if (!(parser_.field_set & (1 << int(f))))
- return std::string_view{};
- return std::string_view{ &string_[parser_.field_data[int(f)].off], parser_.field_data[int(f)].len };
- }
- /**
- * @brief Gets the content of the specific section, maybe empty
- * same as get_field
- */
- inline std::string_view field(http::parses::url_fields f) const noexcept
- {
- return this->get_field(std::move(f));
- }
- inline http::parses::http_parser_url & parser() noexcept { return this->parser_; }
- inline std::string & string() noexcept { return this->string_; }
- inline http::parses::http_parser_url & get_parser() noexcept { return this->parser_; }
- inline std::string & get_string() noexcept { return this->string_; }
- inline http::parses::http_parser_url const& parser() const noexcept { return this->parser_; }
- inline std::string const& string() const noexcept { return this->string_; }
- inline http::parses::http_parser_url const& get_parser() const noexcept { return this->parser_; }
- inline std::string const& get_string() const noexcept { return this->string_; }
- protected:
- http::parses::http_parser_url parser_;
- std::string string_;
- };
- template<class derived_t>
- std::string make_url_string(derived_t& derive, std::string_view target)
- {
- std::string url;
- if constexpr (std::is_base_of_v<asio2::detail::ssl_stream_tag, derived_t>)
- {
- url += "https://";
- url += derive.get_local_address();
- if (unsigned short n = derive.get_local_port(); n != 443)
- {
- url += ":";
- url += std::to_string(n);
- }
- }
- else
- {
- url = "http://";
- url += derive.get_local_address();
- if (unsigned short n = derive.get_local_port(); n != 80)
- {
- url += ":";
- url += std::to_string(n);
- }
- }
- url += target;
- return url;
- }
- template<class derived_t>
- std::string make_url_string(std::shared_ptr<derived_t>& derive_ptr, std::string_view target)
- {
- return make_url_string(*derive_ptr, target);
- }
- template<class derived_t>
- http::url make_url(derived_t& derive, std::string_view target)
- {
- return http::url(make_url_string(derive, target));
- }
- template<class derived_t>
- http::url make_url(std::shared_ptr<derived_t>& derive_ptr, std::string_view target)
- {
- return http::url(make_url_string(derive_ptr, target));
- }
- }
- #endif // !__ASIO2_HTTP_URL_HPP__
|