diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 02ab3fc3..5150ddbe 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3272,6 +3272,9 @@ getDeepLinkInfo link:string = DeepLinkInfo; //@description Adds a proxy server for network requests. Can be called before authorization @server Proxy server IP address @port Proxy server port @enable True, if the proxy should be enabled @type Proxy type addProxy server:string port:int32 enable:Bool type:ProxyType = Proxy; +//@description Edits an existing proxy server for network requests. Can be called before authorization @proxy_id Proxy identifier @server Proxy server IP address @port Proxy server port @enable True, if the proxy should be enabled @type Proxy type +editProxy proxy_id:int32 server:string port:int32 enable:Bool type:ProxyType = Proxy; + //@description Enables a proxy. Only one proxy can be enabled at a time. Can be called before authorization @proxy_id Proxy identifier enableProxy proxy_id:int32 = Ok; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index eaeefa00..c9c876ba 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index dbe1fbc2..1bec26e9 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3276,6 +3276,7 @@ bool Td::is_preauthentication_request(int32 id) { case td_api::getCountryCode::ID: case td_api::getDeepLinkInfo::ID: case td_api::addProxy::ID: + case td_api::editProxy::ID: case td_api::enableProxy::ID: case td_api::disableProxy::ID: case td_api::removeProxy::ID: @@ -3981,6 +3982,7 @@ Status Td::init(DbKey key) { case td_api::addNetworkStatistics::ID: case td_api::resetNetworkStatistics::ID: case td_api::addProxy::ID: + case td_api::editProxy::ID: case td_api::enableProxy::ID: case td_api::disableProxy::ID: case td_api::removeProxy::ID: @@ -6550,10 +6552,20 @@ void Td::on_request(uint64 id, td_api::getDeepLinkInfo &request) { void Td::on_request(uint64 id, td_api::addProxy &request) { CLEAN_INPUT_STRING(request.server_); CREATE_REQUEST_PROMISE(); - send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, std::move(request.server_), request.port_, + send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, -1, std::move(request.server_), request.port_, request.enable_, std::move(request.type_), std::move(promise)); } +void Td::on_request(uint64 id, td_api::editProxy &request) { + if (request.proxy_id_ < 0) { + return send_error_raw(id, 400, "Proxy identifier invalid"); + } + CLEAN_INPUT_STRING(request.server_); + CREATE_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, request.proxy_id_, std::move(request.server_), + request.port_, request.enable_, std::move(request.type_), std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::enableProxy &request) { CREATE_OK_REQUEST_PROMISE(); send_closure(G()->connection_creator(), &ConnectionCreator::enable_proxy, request.proxy_id_, std::move(promise)); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index a1d27eaf..42b47c53 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -849,6 +849,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::addProxy &request); + void on_request(uint64 id, td_api::editProxy &request); + void on_request(uint64 id, const td_api::enableProxy &request); void on_request(uint64 id, const td_api::disableProxy &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 6564691e..70d6af66 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3232,25 +3232,36 @@ class CliClient final : public Actor { send_request(make_tl_object(as_proxy_id(args))); } else if (op == "rproxy") { send_request(make_tl_object(as_proxy_id(args))); - } else if (op == "aproxy" || op == "aeproxy" || op == "aeproxytcp") { + } else if (op == "aproxy" || op == "aeproxy" || op == "aeproxytcp" || op == "editproxy" || op == "editeproxy" || + op == "editeproxytcp") { + string proxy_id; string server; string port; string user; string password; + if (op[0] == 'e') { + std::tie(proxy_id, args) = split(args); + } std::tie(server, args) = split(args); std::tie(port, args) = split(args); std::tie(user, password) = split(args); + bool enable = op != "aproxy" && op != "editproxy"; td_api::object_ptr type; if (!user.empty() && password.empty()) { type = make_tl_object(user); } else { if (port == "80") { - type = make_tl_object(user, password, op != "aeproxytcp"); + type = make_tl_object(user, password, op.back() != 'p'); } else { type = make_tl_object(user, password); } } - send_request(make_tl_object(server, to_integer(port), op == "aeproxy", std::move(type))); + if (op[0] == 'e') { + send_request(make_tl_object(as_proxy_id(proxy_id), server, to_integer(port), enable, + std::move(type))); + } else { + send_request(make_tl_object(server, to_integer(port), enable, std::move(type))); + } } else if (op == "gproxy" || op == "gproxies") { send_request(make_tl_object()); } else if (op == "gproxyl" || op == "gpl") { diff --git a/td/telegram/net/ConnectionCreator.cpp b/td/telegram/net/ConnectionCreator.cpp index 5e322b10..480df4f0 100644 --- a/td/telegram/net/ConnectionCreator.cpp +++ b/td/telegram/net/ConnectionCreator.cpp @@ -280,7 +280,7 @@ void ConnectionCreator::set_net_stats_callback(std::shared_ptr media_net_stats_callback_ = std::move(media_callback); } -void ConnectionCreator::add_proxy(string server, int32 port, bool enable, +void ConnectionCreator::add_proxy(int32 old_proxy_id, string server, int32 port, bool enable, td_api::object_ptr proxy_type, Promise> promise) { if (proxy_type == nullptr) { @@ -333,6 +333,27 @@ void ConnectionCreator::add_proxy(string server, int32 port, bool enable, default: UNREACHABLE(); } + if (old_proxy_id >= 0) { + if (proxies_.count(old_proxy_id) == 0) { + return promise.set_error(Status::Error(400, "Proxy not found")); + } + auto &old_proxy = proxies_[old_proxy_id]; + if (old_proxy == new_proxy) { + if (enable) { + enable_proxy_impl(old_proxy_id); + } + return promise.set_value(get_proxy_object(old_proxy_id)); + } + if (old_proxy_id == active_proxy_id_) { + enable = true; + disable_proxy_impl(); + } + + proxies_.erase(old_proxy_id); + G()->td_db()->get_binlog_pmc()->erase(get_proxy_used_database_key(old_proxy_id)); + proxy_last_used_date_.erase(old_proxy_id); + proxy_last_used_saved_date_.erase(old_proxy_id); + } auto proxy_id = [&] { for (auto &proxy : proxies_) { @@ -341,9 +362,12 @@ void ConnectionCreator::add_proxy(string server, int32 port, bool enable, } } - CHECK(max_proxy_id_ >= 2); - auto proxy_id = max_proxy_id_++; - G()->td_db()->get_binlog_pmc()->set("proxy_max_id", to_string(max_proxy_id_)); + int32 proxy_id = old_proxy_id; + if (proxy_id < 0) { + CHECK(max_proxy_id_ >= 2); + proxy_id = max_proxy_id_++; + G()->td_db()->get_binlog_pmc()->set("proxy_max_id", to_string(max_proxy_id_)); + } CHECK(proxies_.count(proxy_id) == 0); proxies_.emplace(proxy_id, std::move(new_proxy)); G()->td_db()->get_binlog_pmc()->set(get_proxy_database_key(proxy_id), diff --git a/td/telegram/net/ConnectionCreator.h b/td/telegram/net/ConnectionCreator.h index d234a1a5..3434e19b 100644 --- a/td/telegram/net/ConnectionCreator.h +++ b/td/telegram/net/ConnectionCreator.h @@ -158,8 +158,8 @@ class ConnectionCreator : public NetQueryCallback { void set_net_stats_callback(std::shared_ptr common_callback, std::shared_ptr media_callback); - void add_proxy(string server, int32 port, bool enable, td_api::object_ptr proxy_type, - Promise> promise); + void add_proxy(int32 old_proxy_id, string server, int32 port, bool enable, + td_api::object_ptr proxy_type, Promise> promise); void enable_proxy(int32 proxy_id, Promise promise); void disable_proxy(Promise promise); void remove_proxy(int32 proxy_id, Promise promise);