From 4d250ff8294beafa8f74d331efb779d5ea1ad317 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 31 Jul 2024 17:26:17 +0300 Subject: [PATCH] Move synchronous request implementations to a separate file. --- CMakeLists.txt | 2 + SplitSource.php | 1 + td/telegram/SynchronousRequests.cpp | 398 ++++++++++++++++++++++++++++ td/telegram/SynchronousRequests.h | 89 +++++++ td/telegram/Td.cpp | 367 +------------------------ td/telegram/Td.h | 35 --- 6 files changed, 493 insertions(+), 399 deletions(-) create mode 100644 td/telegram/SynchronousRequests.cpp create mode 100644 td/telegram/SynchronousRequests.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2675882e2..3b29af4a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -570,6 +570,7 @@ set(TDLIB_SOURCE_PART2 td/telegram/StoryViewer.cpp td/telegram/SuggestedAction.cpp td/telegram/Support.cpp + td/telegram/SynchronousRequests.cpp td/telegram/Td.cpp td/telegram/TdDb.cpp td/telegram/TermsOfService.cpp @@ -912,6 +913,7 @@ set(TDLIB_SOURCE_PART2 td/telegram/StoryViewer.h td/telegram/SuggestedAction.h td/telegram/Support.h + td/telegram/SynchronousRequests.h td/telegram/Td.h td/telegram/TdCallback.h td/telegram/TdDb.h diff --git a/SplitSource.php b/SplitSource.php index 90ecf98df..f12ce35f0 100644 --- a/SplitSource.php +++ b/SplitSource.php @@ -418,6 +418,7 @@ function split_file($file, $chunks, $undo) { 'StoryListId' => 'StoryListId', 'story_manager[_(-](?![.]get[(][)])|StoryManager' => 'StoryManager', 'SuggestedAction|[a-z_]*_suggested_action' => 'SuggestedAction', + 'SynchronousRequests' => 'SynchronousRequests', 'td_api' => 'td_api', 'td_db[(][)]|TdDb[^A-Za-z]' => 'TdDb', 'telegram_api' => 'telegram_api', diff --git a/td/telegram/SynchronousRequests.cpp b/td/telegram/SynchronousRequests.cpp new file mode 100644 index 000000000..d43389420 --- /dev/null +++ b/td/telegram/SynchronousRequests.cpp @@ -0,0 +1,398 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// 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) +// +#include "td/telegram/SynchronousRequests.h" + +#include "td/telegram/CountryInfoManager.h" +#include "td/telegram/DialogFilter.h" +#include "td/telegram/JsonValue.h" +#include "td/telegram/LanguagePackManager.h" +#include "td/telegram/Logging.h" +#include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageQuote.h" +#include "td/telegram/misc.h" +#include "td/telegram/NotificationManager.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/QuickReplyManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/td_api.hpp" +#include "td/telegram/ThemeManager.h" + +#include "td/utils/filesystem.h" +#include "td/utils/MimeType.h" +#include "td/utils/PathView.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/Status.h" +#include "td/utils/utf8.h" + +#include + +namespace td { + +td_api::object_ptr SynchronousRequests::run_request(td_api::object_ptr function) { + if (function == nullptr) { + return td_api::make_object(400, "Request is empty"); + } + + auto function_id = function->get_id(); + bool need_logging = [function_id] { + switch (function_id) { + case td_api::parseTextEntities::ID: + case td_api::parseMarkdown::ID: + case td_api::getMarkdownText::ID: + case td_api::searchStringsByPrefix::ID: + case td_api::checkQuickReplyShortcutName::ID: + case td_api::getCountryFlagEmoji::ID: + case td_api::getFileMimeType::ID: + case td_api::getFileExtension::ID: + case td_api::cleanFileName::ID: + case td_api::getChatFolderDefaultIconName::ID: + case td_api::getJsonValue::ID: + case td_api::getJsonString::ID: + case td_api::getThemeParametersJsonString::ID: + case td_api::testReturnError::ID: + return true; + default: + return false; + } + }(); + + if (need_logging) { + VLOG(td_requests) << "Receive static request: " << to_string(function); + } + + td_api::object_ptr response; + downcast_call(*function, [&response](auto &request) { response = SynchronousRequests::do_request(request); }); + LOG_CHECK(response != nullptr) << function_id; + + if (need_logging) { + VLOG(td_requests) << "Sending result for static request: " << to_string(response); + } + return response; +} + +bool SynchronousRequests::is_synchronous_request(const td_api::Function *function) { + switch (function->get_id()) { + case td_api::searchQuote::ID: + case td_api::getTextEntities::ID: + case td_api::parseTextEntities::ID: + case td_api::parseMarkdown::ID: + case td_api::getMarkdownText::ID: + case td_api::searchStringsByPrefix::ID: + case td_api::checkQuickReplyShortcutName::ID: + case td_api::getCountryFlagEmoji::ID: + case td_api::getFileMimeType::ID: + case td_api::getFileExtension::ID: + case td_api::cleanFileName::ID: + case td_api::getLanguagePackString::ID: + case td_api::getPhoneNumberInfoSync::ID: + case td_api::getChatFolderDefaultIconName::ID: + case td_api::getJsonValue::ID: + case td_api::getJsonString::ID: + case td_api::getThemeParametersJsonString::ID: + case td_api::getPushReceiverId::ID: + case td_api::setLogStream::ID: + case td_api::getLogStream::ID: + case td_api::setLogVerbosityLevel::ID: + case td_api::getLogVerbosityLevel::ID: + case td_api::getLogTags::ID: + case td_api::setLogTagVerbosityLevel::ID: + case td_api::getLogTagVerbosityLevel::ID: + case td_api::addLogMessage::ID: + case td_api::testReturnError::ID: + return true; + case td_api::getOption::ID: + return OptionManager::is_synchronous_option(static_cast(function)->name_); + default: + return false; + } +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::searchQuote &request) { + if (request.text_ == nullptr || request.quote_ == nullptr) { + return make_error(400, "Text and quote must be non-empty"); + } + if (!check_utf8(request.text_->text_) || !check_utf8(request.quote_->text_)) { + return make_error(400, "Strings must be encoded in UTF-8"); + } + auto r_text_entities = get_message_entities(nullptr, std::move(request.text_->entities_), false); + if (r_text_entities.is_error()) { + return make_error(400, r_text_entities.error().message()); + } + auto r_quote_entities = get_message_entities(nullptr, std::move(request.quote_->entities_), false); + if (r_quote_entities.is_error()) { + return make_error(400, r_quote_entities.error().message()); + } + auto position = MessageQuote::search_quote({std::move(request.text_->text_), r_text_entities.move_as_ok()}, + {std::move(request.quote_->text_), r_quote_entities.move_as_ok()}, + request.quote_position_); + if (position == -1) { + return make_error(404, "Not Found"); + } + return td_api::make_object(position); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getTextEntities &request) { + if (!check_utf8(request.text_)) { + return make_error(400, "Text must be encoded in UTF-8"); + } + auto text_entities = find_entities(request.text_, false, false); + return td_api::make_object( + get_text_entities_object(nullptr, text_entities, false, std::numeric_limits::max())); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::parseTextEntities &request) { + if (!check_utf8(request.text_)) { // must not use clean_input_string, because \r may be used as a separator + return make_error(400, "Text must be encoded in UTF-8"); + } + if (request.parse_mode_ == nullptr) { + return make_error(400, "Parse mode must be non-empty"); + } + + auto r_entities = [&]() -> Result> { + if (utf8_length(request.text_) > 65536) { + return Status::Error("Text is too long"); + } + switch (request.parse_mode_->get_id()) { + case td_api::textParseModeHTML::ID: + return parse_html(request.text_); + case td_api::textParseModeMarkdown::ID: { + auto version = static_cast(request.parse_mode_.get())->version_; + if (version == 0 || version == 1) { + return parse_markdown(request.text_); + } + if (version == 2) { + return parse_markdown_v2(request.text_); + } + return Status::Error("Wrong Markdown version specified"); + } + default: + UNREACHABLE(); + return Status::Error(500, "Unknown parse mode"); + } + }(); + if (r_entities.is_error()) { + return make_error(400, PSLICE() << "Can't parse entities: " << r_entities.error().message()); + } + + return td_api::make_object(std::move(request.text_), + get_text_entities_object(nullptr, r_entities.ok(), false, -1)); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::parseMarkdown &request) { + if (request.text_ == nullptr) { + return make_error(400, "Text must be non-empty"); + } + + auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_), true); + if (r_entities.is_error()) { + return make_error(400, r_entities.error().message()); + } + auto entities = r_entities.move_as_ok(); + auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); + if (status.is_error()) { + return make_error(400, status.message()); + } + + auto parsed_text = parse_markdown_v3({std::move(request.text_->text_), std::move(entities)}); + fix_formatted_text(parsed_text.text, parsed_text.entities, true, true, true, true, true).ensure(); + return get_formatted_text_object(nullptr, parsed_text, false, std::numeric_limits::max()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getOption &request) { + if (!is_synchronous_request(&request)) { + return make_error(400, "The option can't be get synchronously"); + } + return OptionManager::get_option_synchronously(request.name_); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::getMarkdownText &request) { + if (request.text_ == nullptr) { + return make_error(400, "Text must be non-empty"); + } + + auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_)); + if (r_entities.is_error()) { + return make_error(400, r_entities.error().message()); + } + auto entities = r_entities.move_as_ok(); + auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); + if (status.is_error()) { + return make_error(400, status.message()); + } + + return get_formatted_text_object(nullptr, get_markdown_v3({std::move(request.text_->text_), std::move(entities)}), + false, std::numeric_limits::max()); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::searchStringsByPrefix &request) { + if (!clean_input_string(request.query_)) { + return make_error(400, "Strings must be encoded in UTF-8"); + } + for (auto &str : request.strings_) { + if (!clean_input_string(str)) { + return make_error(400, "Strings must be encoded in UTF-8"); + } + } + int32 total_count = 0; + auto result = search_strings_by_prefix(std::move(request.strings_), std::move(request.query_), request.limit_, + !request.return_none_for_empty_query_, total_count); + return td_api::make_object(total_count, std::move(result)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::checkQuickReplyShortcutName &request) { + // don't check name UTF-8 correctness + auto status = QuickReplyManager::check_shortcut_name(request.name_); + if (status.is_ok()) { + return td_api::make_object(); + } + return make_error(200, status.message()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getCountryFlagEmoji &request) { + // don't check country code UTF-8 correctness + return td_api::make_object(CountryInfoManager::get_country_flag_emoji(request.country_code_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getFileMimeType &request) { + // don't check file name UTF-8 correctness + return td_api::make_object(MimeType::from_extension(PathView(request.file_name_).extension())); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getFileExtension &request) { + // don't check MIME type UTF-8 correctness + return td_api::make_object(MimeType::to_extension(request.mime_type_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::cleanFileName &request) { + // don't check file name UTF-8 correctness + return td_api::make_object(clean_filename(request.file_name_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLanguagePackString &request) { + return LanguagePackManager::get_language_pack_string( + request.language_pack_database_path_, request.localization_target_, request.language_pack_id_, request.key_); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::getPhoneNumberInfoSync &request) { + // don't check language_code/phone number UTF-8 correctness + return CountryInfoManager::get_phone_number_info_sync(request.language_code_, + std::move(request.phone_number_prefix_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getPushReceiverId &request) { + // don't check push payload UTF-8 correctness + auto r_push_receiver_id = NotificationManager::get_push_receiver_id(request.payload_); + if (r_push_receiver_id.is_error()) { + VLOG(notifications) << "Failed to get push notification receiver from \"" << format::escaped(request.payload_) + << '"'; + return make_error(r_push_receiver_id.error().code(), r_push_receiver_id.error().message()); + } + return td_api::make_object(r_push_receiver_id.ok()); +} + +td_api::object_ptr SynchronousRequests::do_request( + const td_api::getChatFolderDefaultIconName &request) { + if (request.folder_ == nullptr) { + return make_error(400, "Chat folder must be non-empty"); + } + if (!check_utf8(request.folder_->title_)) { + return make_error(400, "Chat folder title must be encoded in UTF-8"); + } + if (request.folder_->icon_ != nullptr && !check_utf8(request.folder_->icon_->name_)) { + return make_error(400, "Chat folder icon name must be encoded in UTF-8"); + } + return td_api::make_object(DialogFilter::get_default_icon_name(request.folder_.get())); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::getJsonValue &request) { + if (!check_utf8(request.json_)) { + return make_error(400, "JSON has invalid encoding"); + } + auto result = get_json_value(request.json_); + if (result.is_error()) { + return make_error(400, result.error().message()); + } else { + return result.move_as_ok(); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getJsonString &request) { + return td_api::make_object(get_json_string(request.json_value_.get())); +} + +td_api::object_ptr SynchronousRequests::do_request( + const td_api::getThemeParametersJsonString &request) { + return td_api::make_object(ThemeManager::get_theme_parameters_json_string(request.theme_)); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::setLogStream &request) { + auto result = Logging::set_current_stream(std::move(request.log_stream_)); + if (result.is_ok()) { + return td_api::make_object(); + } else { + return make_error(400, result.message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogStream &request) { + auto result = Logging::get_current_stream(); + if (result.is_ok()) { + return result.move_as_ok(); + } else { + return make_error(400, result.error().message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::setLogVerbosityLevel &request) { + auto result = Logging::set_verbosity_level(static_cast(request.new_verbosity_level_)); + if (result.is_ok()) { + return td_api::make_object(); + } else { + return make_error(400, result.message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogVerbosityLevel &request) { + return td_api::make_object(Logging::get_verbosity_level()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogTags &request) { + return td_api::make_object(Logging::get_tags()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::setLogTagVerbosityLevel &request) { + auto result = Logging::set_tag_verbosity_level(request.tag_, static_cast(request.new_verbosity_level_)); + if (result.is_ok()) { + return td_api::make_object(); + } else { + return make_error(400, result.message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogTagVerbosityLevel &request) { + auto result = Logging::get_tag_verbosity_level(request.tag_); + if (result.is_ok()) { + return td_api::make_object(result.ok()); + } else { + return make_error(400, result.error().message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::addLogMessage &request) { + Logging::add_message(request.verbosity_level_, request.text_); + return td_api::make_object(); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::testReturnError &request) { + if (request.error_ == nullptr) { + return td_api::make_object(404, "Not Found"); + } + + return std::move(request.error_); +} + +} // namespace td diff --git a/td/telegram/SynchronousRequests.h b/td/telegram/SynchronousRequests.h new file mode 100644 index 000000000..d5349eca7 --- /dev/null +++ b/td/telegram/SynchronousRequests.h @@ -0,0 +1,89 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// 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/telegram/td_api.h" + +#include "td/utils/common.h" +#include "td/utils/Slice.h" + +namespace td { + +class SynchronousRequests { + public: + static td_api::object_ptr run_request(td_api::object_ptr function); + + static bool is_synchronous_request(const td_api::Function *function); + + private: + static td_api::object_ptr make_error(int32 code, Slice error) { + return td_api::make_object(code, error.str()); + } + + template + static td_api::object_ptr do_request(const T &request) { + return td_api::make_object(400, "The method can't be executed synchronously"); + } + + static td_api::object_ptr do_request(const td_api::getOption &request); + + static td_api::object_ptr do_request(td_api::searchQuote &request); + + static td_api::object_ptr do_request(const td_api::getTextEntities &request); + + static td_api::object_ptr do_request(td_api::parseTextEntities &request); + + static td_api::object_ptr do_request(td_api::parseMarkdown &request); + + static td_api::object_ptr do_request(td_api::getMarkdownText &request); + + static td_api::object_ptr do_request(td_api::searchStringsByPrefix &request); + + static td_api::object_ptr do_request(const td_api::checkQuickReplyShortcutName &request); + + static td_api::object_ptr do_request(const td_api::getCountryFlagEmoji &request); + + static td_api::object_ptr do_request(const td_api::getFileMimeType &request); + + static td_api::object_ptr do_request(const td_api::getFileExtension &request); + + static td_api::object_ptr do_request(const td_api::cleanFileName &request); + + static td_api::object_ptr do_request(const td_api::getLanguagePackString &request); + + static td_api::object_ptr do_request(td_api::getPhoneNumberInfoSync &request); + + static td_api::object_ptr do_request(const td_api::getPushReceiverId &request); + + static td_api::object_ptr do_request(const td_api::getChatFolderDefaultIconName &request); + + static td_api::object_ptr do_request(td_api::getJsonValue &request); + + static td_api::object_ptr do_request(const td_api::getJsonString &request); + + static td_api::object_ptr do_request(const td_api::getThemeParametersJsonString &request); + + static td_api::object_ptr do_request(td_api::setLogStream &request); + + static td_api::object_ptr do_request(const td_api::getLogStream &request); + + static td_api::object_ptr do_request(const td_api::setLogVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::getLogVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::getLogTags &request); + + static td_api::object_ptr do_request(const td_api::setLogTagVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::getLogTagVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::addLogMessage &request); + + static td_api::object_ptr do_request(td_api::testReturnError &request); +}; + +} // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 7ba2337b9..97e7a0513 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -47,7 +47,6 @@ #include "td/telegram/DialogActionManager.h" #include "td/telegram/DialogBoostLinkInfo.h" #include "td/telegram/DialogEventLog.h" -#include "td/telegram/DialogFilter.h" #include "td/telegram/DialogFilterId.h" #include "td/telegram/DialogFilterManager.h" #include "td/telegram/DialogId.h" @@ -85,7 +84,6 @@ #include "td/telegram/LanguagePackManager.h" #include "td/telegram/LinkManager.h" #include "td/telegram/Location.h" -#include "td/telegram/Logging.h" #include "td/telegram/MessageCopyOptions.h" #include "td/telegram/MessageEffectId.h" #include "td/telegram/MessageEntity.h" @@ -156,6 +154,7 @@ #include "td/telegram/StoryManager.h" #include "td/telegram/SuggestedAction.h" #include "td/telegram/Support.h" +#include "td/telegram/SynchronousRequests.h" #include "td/telegram/td_api.hpp" #include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" @@ -181,11 +180,8 @@ #include "td/utils/algorithm.h" #include "td/utils/buffer.h" -#include "td/utils/filesystem.h" #include "td/utils/format.h" -#include "td/utils/MimeType.h" #include "td/utils/misc.h" -#include "td/utils/PathView.h" #include "td/utils/port/uname.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" @@ -2483,43 +2479,6 @@ bool Td::is_authentication_request(int32 id) { } } -bool Td::is_synchronous_request(const td_api::Function *function) { - switch (function->get_id()) { - case td_api::searchQuote::ID: - case td_api::getTextEntities::ID: - case td_api::parseTextEntities::ID: - case td_api::parseMarkdown::ID: - case td_api::getMarkdownText::ID: - case td_api::searchStringsByPrefix::ID: - case td_api::checkQuickReplyShortcutName::ID: - case td_api::getCountryFlagEmoji::ID: - case td_api::getFileMimeType::ID: - case td_api::getFileExtension::ID: - case td_api::cleanFileName::ID: - case td_api::getLanguagePackString::ID: - case td_api::getPhoneNumberInfoSync::ID: - case td_api::getChatFolderDefaultIconName::ID: - case td_api::getJsonValue::ID: - case td_api::getJsonString::ID: - case td_api::getThemeParametersJsonString::ID: - case td_api::getPushReceiverId::ID: - case td_api::setLogStream::ID: - case td_api::getLogStream::ID: - case td_api::setLogVerbosityLevel::ID: - case td_api::getLogVerbosityLevel::ID: - case td_api::getLogTags::ID: - case td_api::setLogTagVerbosityLevel::ID: - case td_api::getLogTagVerbosityLevel::ID: - case td_api::addLogMessage::ID: - case td_api::testReturnError::ID: - return true; - case td_api::getOption::ID: - return OptionManager::is_synchronous_option(static_cast(function)->name_); - default: - return false; - } -} - bool Td::is_preinitialization_request(int32 id) { switch (id) { case td_api::getCurrentState::ID: @@ -2635,7 +2594,7 @@ void Td::request(uint64 id, tl_object_ptr function) { VLOG(td_requests) << "Receive request " << id << ": " << to_string(function); request_set_.emplace(id, function->get_id()); - if (is_synchronous_request(function.get())) { + if (SynchronousRequests::is_synchronous_request(function.get())) { // send response synchronously return send_result(id, static_request(std::move(function))); } @@ -2724,45 +2683,7 @@ void Td::run_request(uint64 id, tl_object_ptr function) { } td_api::object_ptr Td::static_request(td_api::object_ptr function) { - if (function == nullptr) { - return td_api::make_object(400, "Request is empty"); - } - - auto function_id = function->get_id(); - bool need_logging = [function_id] { - switch (function_id) { - case td_api::parseTextEntities::ID: - case td_api::parseMarkdown::ID: - case td_api::getMarkdownText::ID: - case td_api::searchStringsByPrefix::ID: - case td_api::checkQuickReplyShortcutName::ID: - case td_api::getCountryFlagEmoji::ID: - case td_api::getFileMimeType::ID: - case td_api::getFileExtension::ID: - case td_api::cleanFileName::ID: - case td_api::getChatFolderDefaultIconName::ID: - case td_api::getJsonValue::ID: - case td_api::getJsonString::ID: - case td_api::getThemeParametersJsonString::ID: - case td_api::testReturnError::ID: - return true; - default: - return false; - } - }(); - - if (need_logging) { - VLOG(td_requests) << "Receive static request: " << to_string(function); - } - - td_api::object_ptr response; - downcast_call(*function, [&response](auto &request) { response = Td::do_static_request(request); }); - LOG_CHECK(response != nullptr) << function_id; - - if (need_logging) { - VLOG(td_requests) << "Sending result for static request: " << to_string(response); - } - return response; + return SynchronousRequests::run_request(std::move(function)); } void Td::add_handler(uint64 id, std::shared_ptr handler) { @@ -9763,288 +9684,6 @@ void Td::on_request(uint64 id, const td_api::addLogMessage &request) { UNREACHABLE(); } -td_api::object_ptr Td::do_static_request(td_api::searchQuote &request) { - if (request.text_ == nullptr || request.quote_ == nullptr) { - return make_error(400, "Text and quote must be non-empty"); - } - if (!check_utf8(request.text_->text_) || !check_utf8(request.quote_->text_)) { - return make_error(400, "Strings must be encoded in UTF-8"); - } - auto r_text_entities = get_message_entities(nullptr, std::move(request.text_->entities_), false); - if (r_text_entities.is_error()) { - return make_error(400, r_text_entities.error().message()); - } - auto r_quote_entities = get_message_entities(nullptr, std::move(request.quote_->entities_), false); - if (r_quote_entities.is_error()) { - return make_error(400, r_quote_entities.error().message()); - } - auto position = MessageQuote::search_quote({std::move(request.text_->text_), r_text_entities.move_as_ok()}, - {std::move(request.quote_->text_), r_quote_entities.move_as_ok()}, - request.quote_position_); - if (position == -1) { - return make_error(404, "Not Found"); - } - return td_api::make_object(position); -} - -td_api::object_ptr Td::do_static_request(const td_api::getTextEntities &request) { - if (!check_utf8(request.text_)) { - return make_error(400, "Text must be encoded in UTF-8"); - } - auto text_entities = find_entities(request.text_, false, false); - return make_tl_object( - get_text_entities_object(nullptr, text_entities, false, std::numeric_limits::max())); -} - -td_api::object_ptr Td::do_static_request(td_api::parseTextEntities &request) { - if (!check_utf8(request.text_)) { // must not use clean_input_string, because \r may be used as a separator - return make_error(400, "Text must be encoded in UTF-8"); - } - if (request.parse_mode_ == nullptr) { - return make_error(400, "Parse mode must be non-empty"); - } - - auto r_entities = [&]() -> Result> { - if (utf8_length(request.text_) > 65536) { - return Status::Error("Text is too long"); - } - switch (request.parse_mode_->get_id()) { - case td_api::textParseModeHTML::ID: - return parse_html(request.text_); - case td_api::textParseModeMarkdown::ID: { - auto version = static_cast(request.parse_mode_.get())->version_; - if (version == 0 || version == 1) { - return parse_markdown(request.text_); - } - if (version == 2) { - return parse_markdown_v2(request.text_); - } - return Status::Error("Wrong Markdown version specified"); - } - default: - UNREACHABLE(); - return Status::Error(500, "Unknown parse mode"); - } - }(); - if (r_entities.is_error()) { - return make_error(400, PSLICE() << "Can't parse entities: " << r_entities.error().message()); - } - - return make_tl_object(std::move(request.text_), - get_text_entities_object(nullptr, r_entities.ok(), false, -1)); -} - -td_api::object_ptr Td::do_static_request(td_api::parseMarkdown &request) { - if (request.text_ == nullptr) { - return make_error(400, "Text must be non-empty"); - } - - auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_), true); - if (r_entities.is_error()) { - return make_error(400, r_entities.error().message()); - } - auto entities = r_entities.move_as_ok(); - auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); - if (status.is_error()) { - return make_error(400, status.message()); - } - - auto parsed_text = parse_markdown_v3({std::move(request.text_->text_), std::move(entities)}); - fix_formatted_text(parsed_text.text, parsed_text.entities, true, true, true, true, true).ensure(); - return get_formatted_text_object(nullptr, parsed_text, false, std::numeric_limits::max()); -} - -td_api::object_ptr Td::do_static_request(const td_api::getOption &request) { - if (!is_synchronous_request(&request)) { - return make_error(400, "The option can't be get synchronously"); - } - return OptionManager::get_option_synchronously(request.name_); -} - -td_api::object_ptr Td::do_static_request(td_api::getMarkdownText &request) { - if (request.text_ == nullptr) { - return make_error(400, "Text must be non-empty"); - } - - auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_)); - if (r_entities.is_error()) { - return make_error(400, r_entities.error().message()); - } - auto entities = r_entities.move_as_ok(); - auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); - if (status.is_error()) { - return make_error(400, status.message()); - } - - return get_formatted_text_object(nullptr, get_markdown_v3({std::move(request.text_->text_), std::move(entities)}), - false, std::numeric_limits::max()); -} - -td_api::object_ptr Td::do_static_request(td_api::searchStringsByPrefix &request) { - if (!clean_input_string(request.query_)) { - return make_error(400, "Strings must be encoded in UTF-8"); - } - for (auto &str : request.strings_) { - if (!clean_input_string(str)) { - return make_error(400, "Strings must be encoded in UTF-8"); - } - } - int32 total_count = 0; - auto result = search_strings_by_prefix(std::move(request.strings_), std::move(request.query_), request.limit_, - !request.return_none_for_empty_query_, total_count); - return td_api::make_object(total_count, std::move(result)); -} - -td_api::object_ptr Td::do_static_request(const td_api::checkQuickReplyShortcutName &request) { - // don't check name UTF-8 correctness - auto status = QuickReplyManager::check_shortcut_name(request.name_); - if (status.is_ok()) { - return td_api::make_object(); - } - return make_error(200, status.message()); -} - -td_api::object_ptr Td::do_static_request(const td_api::getCountryFlagEmoji &request) { - // don't check country code UTF-8 correctness - return td_api::make_object(CountryInfoManager::get_country_flag_emoji(request.country_code_)); -} - -td_api::object_ptr Td::do_static_request(const td_api::getFileMimeType &request) { - // don't check file name UTF-8 correctness - return make_tl_object(MimeType::from_extension(PathView(request.file_name_).extension())); -} - -td_api::object_ptr Td::do_static_request(const td_api::getFileExtension &request) { - // don't check MIME type UTF-8 correctness - return make_tl_object(MimeType::to_extension(request.mime_type_)); -} - -td_api::object_ptr Td::do_static_request(const td_api::cleanFileName &request) { - // don't check file name UTF-8 correctness - return make_tl_object(clean_filename(request.file_name_)); -} - -td_api::object_ptr Td::do_static_request(const td_api::getLanguagePackString &request) { - return LanguagePackManager::get_language_pack_string( - request.language_pack_database_path_, request.localization_target_, request.language_pack_id_, request.key_); -} - -td_api::object_ptr Td::do_static_request(td_api::getPhoneNumberInfoSync &request) { - // don't check language_code/phone number UTF-8 correctness - return CountryInfoManager::get_phone_number_info_sync(request.language_code_, - std::move(request.phone_number_prefix_)); -} - -td_api::object_ptr Td::do_static_request(const td_api::getPushReceiverId &request) { - // don't check push payload UTF-8 correctness - auto r_push_receiver_id = NotificationManager::get_push_receiver_id(request.payload_); - if (r_push_receiver_id.is_error()) { - VLOG(notifications) << "Failed to get push notification receiver from \"" << format::escaped(request.payload_) - << '"'; - return make_error(r_push_receiver_id.error().code(), r_push_receiver_id.error().message()); - } - return td_api::make_object(r_push_receiver_id.ok()); -} - -td_api::object_ptr Td::do_static_request(const td_api::getChatFolderDefaultIconName &request) { - if (request.folder_ == nullptr) { - return make_error(400, "Chat folder must be non-empty"); - } - if (!check_utf8(request.folder_->title_)) { - return make_error(400, "Chat folder title must be encoded in UTF-8"); - } - if (request.folder_->icon_ != nullptr && !check_utf8(request.folder_->icon_->name_)) { - return make_error(400, "Chat folder icon name must be encoded in UTF-8"); - } - return td_api::make_object(DialogFilter::get_default_icon_name(request.folder_.get())); -} - -td_api::object_ptr Td::do_static_request(td_api::getJsonValue &request) { - if (!check_utf8(request.json_)) { - return make_error(400, "JSON has invalid encoding"); - } - auto result = get_json_value(request.json_); - if (result.is_error()) { - return make_error(400, result.error().message()); - } else { - return result.move_as_ok(); - } -} - -td_api::object_ptr Td::do_static_request(const td_api::getJsonString &request) { - return td_api::make_object(get_json_string(request.json_value_.get())); -} - -td_api::object_ptr Td::do_static_request(const td_api::getThemeParametersJsonString &request) { - return td_api::make_object(ThemeManager::get_theme_parameters_json_string(request.theme_)); -} - -td_api::object_ptr Td::do_static_request(td_api::setLogStream &request) { - auto result = Logging::set_current_stream(std::move(request.log_stream_)); - if (result.is_ok()) { - return td_api::make_object(); - } else { - return make_error(400, result.message()); - } -} - -td_api::object_ptr Td::do_static_request(const td_api::getLogStream &request) { - auto result = Logging::get_current_stream(); - if (result.is_ok()) { - return result.move_as_ok(); - } else { - return make_error(400, result.error().message()); - } -} - -td_api::object_ptr Td::do_static_request(const td_api::setLogVerbosityLevel &request) { - auto result = Logging::set_verbosity_level(static_cast(request.new_verbosity_level_)); - if (result.is_ok()) { - return td_api::make_object(); - } else { - return make_error(400, result.message()); - } -} - -td_api::object_ptr Td::do_static_request(const td_api::getLogVerbosityLevel &request) { - return td_api::make_object(Logging::get_verbosity_level()); -} - -td_api::object_ptr Td::do_static_request(const td_api::getLogTags &request) { - return td_api::make_object(Logging::get_tags()); -} - -td_api::object_ptr Td::do_static_request(const td_api::setLogTagVerbosityLevel &request) { - auto result = Logging::set_tag_verbosity_level(request.tag_, static_cast(request.new_verbosity_level_)); - if (result.is_ok()) { - return td_api::make_object(); - } else { - return make_error(400, result.message()); - } -} - -td_api::object_ptr Td::do_static_request(const td_api::getLogTagVerbosityLevel &request) { - auto result = Logging::get_tag_verbosity_level(request.tag_); - if (result.is_ok()) { - return td_api::make_object(result.ok()); - } else { - return make_error(400, result.error().message()); - } -} - -td_api::object_ptr Td::do_static_request(const td_api::addLogMessage &request) { - Logging::add_message(request.verbosity_level_, request.text_); - return td_api::make_object(); -} - -td_api::object_ptr Td::do_static_request(td_api::testReturnError &request) { - if (request.error_ == nullptr) { - return td_api::make_object(404, "Not Found"); - } - - return std::move(request.error_); -} - // test void Td::on_request(uint64 id, const td_api::testNetwork &request) { CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 2d3f9f2a6..aaeefa432 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -470,8 +470,6 @@ class Td final : public Actor { static bool is_authentication_request(int32 id); - static bool is_synchronous_request(const td_api::Function *function); - static bool is_preinitialization_request(int32 id); static bool is_preauthentication_request(int32 id); @@ -2020,39 +2018,6 @@ class Td final : public Actor { void on_request(uint64 id, td_api::testCallVectorString &request); void on_request(uint64 id, td_api::testCallVectorStringObject &request); - template - static td_api::object_ptr do_static_request(const T &request) { - return td_api::make_object(400, "The method can't be executed synchronously"); - } - static td_api::object_ptr do_static_request(const td_api::getOption &request); - static td_api::object_ptr do_static_request(td_api::searchQuote &request); - static td_api::object_ptr do_static_request(const td_api::getTextEntities &request); - static td_api::object_ptr do_static_request(td_api::parseTextEntities &request); - static td_api::object_ptr do_static_request(td_api::parseMarkdown &request); - static td_api::object_ptr do_static_request(td_api::getMarkdownText &request); - static td_api::object_ptr do_static_request(td_api::searchStringsByPrefix &request); - static td_api::object_ptr do_static_request(const td_api::checkQuickReplyShortcutName &request); - static td_api::object_ptr do_static_request(const td_api::getCountryFlagEmoji &request); - static td_api::object_ptr do_static_request(const td_api::getFileMimeType &request); - static td_api::object_ptr do_static_request(const td_api::getFileExtension &request); - static td_api::object_ptr do_static_request(const td_api::cleanFileName &request); - static td_api::object_ptr do_static_request(const td_api::getLanguagePackString &request); - static td_api::object_ptr do_static_request(td_api::getPhoneNumberInfoSync &request); - static td_api::object_ptr do_static_request(const td_api::getPushReceiverId &request); - static td_api::object_ptr do_static_request(const td_api::getChatFolderDefaultIconName &request); - static td_api::object_ptr do_static_request(td_api::getJsonValue &request); - static td_api::object_ptr do_static_request(const td_api::getJsonString &request); - static td_api::object_ptr do_static_request(const td_api::getThemeParametersJsonString &request); - static td_api::object_ptr do_static_request(td_api::setLogStream &request); - static td_api::object_ptr do_static_request(const td_api::getLogStream &request); - static td_api::object_ptr do_static_request(const td_api::setLogVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::getLogVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::getLogTags &request); - static td_api::object_ptr do_static_request(const td_api::setLogTagVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::getLogTagVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::addLogMessage &request); - static td_api::object_ptr do_static_request(td_api::testReturnError &request); - static DbKey as_db_key(string key); struct Parameters {