From 0fd4a3b780d0c81e8fd09c61f66320572893646f Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 15 May 2018 23:04:27 +0300 Subject: [PATCH] Support for synchronous request and setAlarm before initialization. GitOrigin-RevId: cd7c803d7755437a3240816f221817e08beb33d6 --- td/generate/scheme/td_api.tl | 4 +- td/telegram/Td.cpp | 115 +++++++++++++++++++++++++++++++---- td/telegram/Td.h | 10 +++ td/telegram/cli.cpp | 13 ++-- 4 files changed, 123 insertions(+), 19 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index c3512822..1b32091e 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3143,7 +3143,7 @@ sendCustomRequest method:string parameters:string = CustomRequestResult; answerCustomQuery custom_query_id:int64 data:string = Ok; -//@description Succeeds after a specified amount of time has passed. Can be called before authorization @seconds Number of seconds before the function returns +//@description Succeeds after a specified amount of time has passed. Can be called before authorization. Can be called before initialization @seconds Number of seconds before the function returns setAlarm seconds:double = Ok; @@ -3160,7 +3160,7 @@ getTermsOfService = Text; getDeepLinkInfo link:string = DeepLinkInfo; -//@description Adds a proxy server for network requests. Can be called before authorization. Can be called before initialization @server Proxy server IP address @port Proxy server port @enable True, if the proxy should be enabled @type Type of a proxy +//@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 Type of a proxy addProxy 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 The proxy identifier diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d22fcbcc..203ce5bd 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3929,6 +3929,85 @@ bool Td::is_online() const { return is_online_; } +bool Td::is_authentication_request(int32 id) { + switch (id) { + case td_api::setTdlibParameters::ID: + case td_api::checkDatabaseEncryptionKey::ID: + case td_api::setDatabaseEncryptionKey::ID: + case td_api::getAuthorizationState::ID: + case td_api::setAuthenticationPhoneNumber::ID: + case td_api::resendAuthenticationCode::ID: + case td_api::checkAuthenticationCode::ID: + case td_api::checkAuthenticationPassword::ID: + case td_api::requestAuthenticationPasswordRecovery::ID: + case td_api::recoverAuthenticationPassword::ID: + case td_api::logOut::ID: + case td_api::close::ID: + case td_api::destroy::ID: + case td_api::checkAuthenticationBotToken::ID: + return true; + default: + return false; + } +} + +bool Td::is_synchronous_request(int32 id) { + switch (id) { + case td_api::getTextEntities::ID: + case td_api::parseTextEntities::ID: + case td_api::getFileMimeType::ID: + case td_api::getFileExtension::ID: + case td_api::cleanFileName::ID: + return true; + default: + return false; + } +} + +bool Td::is_preinitialization_request(int32 id) { + switch (id) { + case td_api::setAlarm::ID: + case td_api::testUseUpdate::ID: + case td_api::testUseError::ID: + case td_api::testCallEmpty::ID: + case td_api::testSquareInt::ID: + case td_api::testCallString::ID: + case td_api::testCallBytes::ID: + case td_api::testCallVectorInt::ID: + case td_api::testCallVectorIntObject::ID: + case td_api::testCallVectorString::ID: + case td_api::testCallVectorStringObject::ID: + return true; + default: + return false; + } +} + +bool Td::is_preauthentication_request(int32 id) { + switch (id) { + case td_api::processDcUpdate::ID: + case td_api::getOption::ID: + case td_api::setOption::ID: + case td_api::setNetworkType::ID: + case td_api::getNetworkStatistics::ID: + case td_api::addNetworkStatistics::ID: + case td_api::resetNetworkStatistics::ID: + case td_api::getCountryCode::ID: + case td_api::getTermsOfService::ID: + case td_api::getDeepLinkInfo::ID: + case td_api::addProxy::ID: + case td_api::enableProxy::ID: + case td_api::disableProxy::ID: + case td_api::removeProxy::ID: + case td_api::getProxies::ID: + case td_api::pingProxy::ID: + case td_api::testNetwork::ID: + return true; + default: + return false; + } +} + void Td::request(uint64 id, tl_object_ptr function) { request_set_.insert(id); @@ -3942,9 +4021,10 @@ void Td::request(uint64 id, tl_object_ptr function) { } VLOG(td_requests) << "Receive request " << id << ": " << to_string(function); + int32 function_id = function->get_id(); switch (state_) { case State::WaitParameters: { - switch (function->get_id()) { + switch (function_id) { case td_api::getAuthorizationState::ID: return send_closure(actor_id(this), &Td::send_result, id, td_api::make_object()); @@ -3952,13 +4032,20 @@ void Td::request(uint64 id, tl_object_ptr function) { return answer_ok_query( id, set_parameters(std::move(move_tl_object_as(function)->parameters_))); default: + if (is_synchronous_request(function_id) || is_preinitialization_request(function_id)) { + break; + } + if (is_preauthentication_request(function_id)) { + // pending_preauthentication_requests_.emplace_back(id, std::move(function)); + // return; + } return send_error_raw(id, 401, "Initialization parameters are needed"); } break; } case State::Decrypt: { string encryption_key; - switch (function->get_id()) { + switch (function_id) { case td_api::getAuthorizationState::ID: return send_closure( actor_id(this), &Td::send_result, id, @@ -3978,12 +4065,19 @@ void Td::request(uint64 id, tl_object_ptr function) { case td_api::destroy::ID: return destroy(); default: + if (is_synchronous_request(function_id) || is_preinitialization_request(function_id)) { + break; + } + if (is_preauthentication_request(function_id)) { + // pending_preauthentication_requests_.emplace_back(id, std::move(function)); + // return; + } return send_error_raw(id, 401, "Database encryption key is needed"); } return answer_ok_query(id, init(as_db_key(encryption_key))); } case State::Close: { - if (function->get_id() == td_api::getAuthorizationState::ID) { + if (function_id == td_api::getAuthorizationState::ID) { if (close_flag_ == 5) { return send_closure(actor_id(this), &Td::send_result, id, td_api::make_object()); @@ -3992,6 +4086,9 @@ void Td::request(uint64 id, tl_object_ptr function) { td_api::make_object()); } } + if (is_synchronous_request(function_id)) { + break; + } return send_error_raw(id, 401, "Unauthorized"); } case State::Run: @@ -4186,6 +4283,9 @@ void Td::start_up() { LOG_IF(FATAL, symbol != c) << "TDLib requires little-endian platform"; } + alarm_timeout_.set_callback(on_alarm_timeout_callback); + alarm_timeout_.set_callback_data(static_cast(this)); + CHECK(state_ == State::WaitParameters); send_update(td_api::make_object( td_api::make_object())); @@ -4910,10 +5010,6 @@ Status Td::set_parameters(td_api::object_ptr parameters TRY_RESULT(encryption_info, TdDb::check_encryption(parameters_)); encryption_info_ = std::move(encryption_info); - VLOG(td_init) << "Init alarm multitimeout..."; - alarm_timeout_.set_callback(on_alarm_timeout_callback); - alarm_timeout_.set_callback_data(static_cast(this)); - VLOG(td_init) << "Create Global"; set_context(std::make_shared()); inc_request_actor_refcnt(); // guard @@ -7136,27 +7232,22 @@ void Td::on_request(uint64 id, const td_api::pingProxy &request) { } void Td::on_request(uint64 id, const td_api::getTextEntities &request) { - // don't check authorization state send_closure(actor_id(this), &Td::send_result, id, do_static_request(request)); } void Td::on_request(uint64 id, td_api::parseTextEntities &request) { - // don't check authorization state send_closure(actor_id(this), &Td::send_result, id, do_static_request(request)); } void Td::on_request(uint64 id, const td_api::getFileMimeType &request) { - // don't check authorization state send_closure(actor_id(this), &Td::send_result, id, do_static_request(request)); } void Td::on_request(uint64 id, const td_api::getFileExtension &request) { - // don't check authorization state send_closure(actor_id(this), &Td::send_result, id, do_static_request(request)); } void Td::on_request(uint64 id, const td_api::cleanFileName &request) { - // don't check authorization state send_closure(actor_id(this), &Td::send_result, id, do_static_request(request)); } diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 38c8e786..27dc6012 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -245,6 +245,8 @@ class Td final : public NetQueryCallback { std::unordered_map pending_alarms_; MultiTimeout alarm_timeout_; + vector>> pending_preauthentication_requests_; + static void on_alarm_timeout_callback(void *td_ptr, int64 alarm_id); void on_alarm_timeout(int64 alarm_id); @@ -283,6 +285,14 @@ class Td final : public NetQueryCallback { Promise create_ok_request_promise(uint64 id); + static bool is_authentication_request(int32 id); + + static bool is_synchronous_request(int32 id); + + static bool is_preinitialization_request(int32 id); + + static bool is_preauthentication_request(int32 id); + template void on_request(uint64 id, const T &request) = delete; diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 08082e12..27188172 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -669,6 +669,14 @@ class CliClient final : public Actor { td_ = create_actor("ClientActor2", make_td_callback()); ready_to_stop_ = false; + for (int i = 0; i < 4; i++) { + send_closure_later(td_, &ClientActor::request, std::numeric_limits::max(), + td_api::make_object(0.001 + 1000 * (i / 2))); + } + + send_request(td_api::make_object( + "@telegram /test_command https://telegram.org telegram.me @gif @test")); + auto bad_parameters = td_api::make_object(); bad_parameters->database_directory_ = "/.."; bad_parameters->api_id_ = api_id_; @@ -687,11 +695,6 @@ class CliClient final : public Actor { parameters->application_version_ = "tg_cli"; send_request(td_api::make_object(std::move(parameters))); send_request(td_api::make_object()); - - for (int i = 0; i < 4; i++) { - send_closure_later(td_, &ClientActor::request, std::numeric_limits::max(), - td_api::make_object(0.001 + 1000 * (i / 2))); - } } void init() {