// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 // // 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) // #pragma once #include "td/mtproto/ProxySecret.h" #include "td/utils/common.h" #include "td/utils/Slice.h" #include "td/utils/StringBuilder.h" #include "td/utils/tl_helpers.h" namespace td { class Proxy { public: static Proxy socks5(string server, int32 port, string user, string password) { Proxy proxy; proxy.type_ = Type::Socks5; proxy.server_ = std::move(server); proxy.port_ = std::move(port); proxy.user_ = std::move(user); proxy.password_ = std::move(password); return proxy; } static Proxy http_tcp(string server, int32 port, string user, string password) { Proxy proxy; proxy.type_ = Type::HttpTcp; proxy.server_ = std::move(server); proxy.port_ = std::move(port); proxy.user_ = std::move(user); proxy.password_ = std::move(password); return proxy; } static Proxy http_caching(string server, int32 port, string user, string password) { Proxy proxy; proxy.type_ = Type::HttpCaching; proxy.server_ = std::move(server); proxy.port_ = std::move(port); proxy.user_ = std::move(user); proxy.password_ = std::move(password); return proxy; } static Proxy mtproto(string server, int32 port, mtproto::ProxySecret secret) { Proxy proxy; proxy.type_ = Type::Mtproto; proxy.server_ = std::move(server); proxy.port_ = std::move(port); proxy.secret_ = std::move(secret); return proxy; } CSlice server() const { return server_; } int32 port() const { return port_; } CSlice user() const { return user_; } CSlice password() const { return password_; } const mtproto::ProxySecret &secret() const { return secret_; } enum class Type : int32 { None, Socks5, Mtproto, HttpTcp, HttpCaching }; Type type() const { return type_; } template void store(StorerT &storer) const { using td::store; store(type_, storer); if (type_ == Proxy::Type::Socks5 || type_ == Proxy::Type::HttpTcp || type_ == Proxy::Type::HttpCaching) { store(server_, storer); store(port_, storer); store(user_, storer); store(password_, storer); } else if (type_ == Proxy::Type::Mtproto) { store(server_, storer); store(port_, storer); store(secret_.get_encoded_secret(), storer); } else { CHECK(type_ == Proxy::Type::None); } } template void parse(ParserT &parser) { using td::parse; parse(type_, parser); if (type_ == Proxy::Type::Socks5 || type_ == Proxy::Type::HttpTcp || type_ == Proxy::Type::HttpCaching) { parse(server_, parser); parse(port_, parser); parse(user_, parser); parse(password_, parser); } else if (type_ == Proxy::Type::Mtproto) { parse(server_, parser); parse(port_, parser); secret_ = mtproto::ProxySecret::from_link(parser.template fetch_string()).move_as_ok(); } else { LOG_CHECK(type_ == Proxy::Type::None) << static_cast(type_); } } private: Type type_{Type::None}; string server_; int32 port_ = 0; string user_; string password_; mtproto::ProxySecret secret_; }; inline bool operator==(const Proxy &lhs, const Proxy &rhs) { return lhs.type() == rhs.type() && lhs.server() == rhs.server() && lhs.port() == rhs.port() && lhs.user() == rhs.user() && lhs.password() == rhs.password() && lhs.secret() == rhs.secret(); } inline bool operator!=(const Proxy &lhs, const Proxy &rhs) { return !(lhs == rhs); } inline StringBuilder &operator<<(StringBuilder &string_builder, const Proxy &proxy) { switch (proxy.type()) { case Proxy::Type::Socks5: return string_builder << "ProxySocks5 " << proxy.server() << ":" << proxy.port(); case Proxy::Type::HttpTcp: return string_builder << "ProxyHttpTcp " << proxy.server() << ":" << proxy.port(); case Proxy::Type::HttpCaching: return string_builder << "ProxyHttpCaching " << proxy.server() << ":" << proxy.port(); case Proxy::Type::Mtproto: return string_builder << "ProxyMtproto " << proxy.server() << ":" << proxy.port() << "/" << proxy.secret().get_encoded_secret(); case Proxy::Type::None: return string_builder << "ProxyEmpty"; default: UNREACHABLE(); return string_builder; } } } // namespace td