diff --git a/td b/td index 7eba198..e531ae2 160000 --- a/td +++ b/td @@ -1 +1 @@ -Subproject commit 7eba19887ad834fd731b6b07b53c2426fe4beb59 +Subproject commit e531ae2eb01d5c0ba2a195c8d860a4e53689a729 diff --git a/telegram-bot-api/Client.cpp b/telegram-bot-api/Client.cpp index 1392038..be31e0e 100644 --- a/telegram-bot-api/Client.cpp +++ b/telegram-bot-api/Client.cpp @@ -2024,6 +2024,12 @@ void Client::JsonMessage::store(JsonValueScope *scope) const { } break; } + case td_api::messageForumTopicIsHiddenToggled::ID: { + // auto content = static_cast(message_->content.get()); + // temporary; the topic is closed when it is hidden or unhidden + object("forum_topic_closed", JsonForumTopicIsClosedToggled()); + break; + } case td_api::messagePinMessage::ID: { auto content = static_cast(message_->content.get()); auto message_id = content->message_id_; @@ -8259,11 +8265,14 @@ td::Status Client::process_edit_forum_topic_query(PromisedQueryPtr &query) { auto chat_id = query->arg("chat_id"); auto message_thread_id = get_message_id(query.get(), "message_thread_id"); auto name = query->arg("name"); + auto edit_icon_custom_emoji_id = query->has_arg("icon_custom_emoji_id"); auto icon_custom_emoji_id = td::to_integer(query->arg("icon_custom_emoji_id")); check_chat(chat_id, AccessRights::Write, std::move(query), - [this, message_thread_id, name = name.str(), icon_custom_emoji_id](int64 chat_id, PromisedQueryPtr query) { - send_request(make_object(chat_id, message_thread_id, name, icon_custom_emoji_id), + [this, message_thread_id, name = name.str(), edit_icon_custom_emoji_id, icon_custom_emoji_id]( + int64 chat_id, PromisedQueryPtr query) { + send_request(make_object(chat_id, message_thread_id, name, + edit_icon_custom_emoji_id, icon_custom_emoji_id), td::make_unique(std::move(query))); }); return Status::OK(); @@ -8863,7 +8872,7 @@ td::Status Client::process_set_webhook_query(PromisedQueryPtr &query) { if (now > next_set_webhook_logging_time_ || webhook_url_ != new_url) { next_set_webhook_logging_time_ = now + 300; LOG(WARNING) << "Set webhook to " << new_url << ", max_connections = " << new_max_connections - << ", IP address = " << new_ip_address; + << ", IP address = " << new_ip_address << ", drop_pending_updates = " << drop_pending_updates; } if (!new_url.empty()) { @@ -10125,7 +10134,9 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr(td::Time::now()); - td::uint32 wakeup_at = flood_control.get_wakeup_at(); + auto now = td::Time::now(); + auto wakeup_at = flood_control.get_wakeup_at(); if (wakeup_at > now) { LOG(INFO) << "Failed to create Client from IP address " << ip_address; return query->set_retry_after_error(static_cast(wakeup_at - now) + 1); } - flood_control.add_event(static_cast(now)); + flood_control.add_event(now); } auto tqueue_id = get_tqueue_id(user_id, query->is_test_dc()); if (active_client_count_.count(tqueue_id) != 0) { diff --git a/telegram-bot-api/HttpServer.h b/telegram-bot-api/HttpServer.h index f7d0009..9699835 100644 --- a/telegram-bot-api/HttpServer.h +++ b/telegram-bot-api/HttpServer.h @@ -46,7 +46,7 @@ class HttpServer final : public td::TcpListener::Callback { set_timeout_at(wakeup_at); return; } - flood_control_.add_event(static_cast(now)); + flood_control_.add_event(now); LOG(INFO) << "Create tcp listener " << td::tag("address", ip_address_) << td::tag("port", port_); listener_ = td::create_actor( PSLICE() << "TcpListener" << td::tag("address", ip_address_) << td::tag("port", port_), port_, diff --git a/telegram-bot-api/WebhookActor.cpp b/telegram-bot-api/WebhookActor.cpp index f63cd55..4fd95d8 100644 --- a/telegram-bot-api/WebhookActor.cpp +++ b/telegram-bot-api/WebhookActor.cpp @@ -11,7 +11,6 @@ #include "td/net/GetHostByNameActor.h" #include "td/net/HttpHeaderCreator.h" #include "td/net/HttpProxy.h" -#include "td/net/SslStream.h" #include "td/net/TransparentProxy.h" #include "td/actor/actor.h" @@ -136,12 +135,7 @@ td::Status WebhookActor::create_connection() { if (parameters_->webhook_proxy_ip_address_.is_valid()) { auto r_proxy_socket_fd = td::SocketFd::open(parameters_->webhook_proxy_ip_address_); if (r_proxy_socket_fd.is_error()) { - td::Slice error_message = "Can't connect to the webhook proxy"; - auto error = td::Status::Error(PSLICE() << error_message << ": " << r_proxy_socket_fd.error()); - VLOG(webhook) << error; - on_webhook_error(error_message); - on_error(td::Status::Error(error_message)); - return error; + return create_webhook_error("Can't connect to the webhook proxy", r_proxy_socket_fd.move_as_error(), false); } if (!was_checked_) { TRY_STATUS(create_ssl_stream()); // check certificate @@ -188,29 +182,40 @@ td::Status WebhookActor::create_connection() { auto r_fd = td::SocketFd::open(ip_address_); if (r_fd.is_error()) { - td::Slice error_message = "Can't connect to the webhook"; - auto error = td::Status::Error(PSLICE() << error_message << ": " << r_fd.error()); - VLOG(webhook) << error; - on_webhook_error(error_message); - on_error(r_fd.move_as_error()); - return error; + return create_webhook_error("Can't connect to the webhook", r_fd.move_as_error(), false); } return create_connection(td::BufferedFd(r_fd.move_as_ok())); } +td::Status WebhookActor::create_webhook_error(td::Slice error_message, td::Status &&result, bool is_public) { + CHECK(result.is_error()); + auto error = td::Status::Error(PSLICE() << error_message << ": " << result); + VLOG(webhook) << error; + if (is_public) { + on_webhook_error(PSLICE() << error_message << ": " << result.public_message()); + } else { + on_webhook_error(error_message); + } + on_error(std::move(result)); + return std::move(error); +} + td::Result WebhookActor::create_ssl_stream() { if (url_.protocol_ == td::HttpUrl::Protocol::Http) { return td::SslStream(); } - auto r_ssl_stream = td::SslStream::create(url_.host_, cert_path_, td::SslStream::VerifyPeer::On, !cert_path_.empty()); + if (!ssl_ctx_) { + auto r_ssl_ctx = td::SslCtx::create(cert_path_, td::SslCtx::VerifyPeer::On); + if (r_ssl_ctx.is_error()) { + return create_webhook_error("Can't create an SSL context", r_ssl_ctx.move_as_error(), true); + } + ssl_ctx_ = r_ssl_ctx.move_as_ok(); + } + + auto r_ssl_stream = td::SslStream::create(url_.host_, ssl_ctx_, !cert_path_.empty()); if (r_ssl_stream.is_error()) { - td::Slice error_message = "Can't create an SSL connection"; - auto error = td::Status::Error(PSLICE() << error_message << ": " << r_ssl_stream.error()); - VLOG(webhook) << error; - on_webhook_error(PSLICE() << error_message << ": " << r_ssl_stream.error().public_message()); - on_error(r_ssl_stream.move_as_error()); - return std::move(error); + return create_webhook_error("Can't create an SSL connection", r_ssl_stream.move_as_error(), true); } return r_ssl_stream.move_as_ok(); } @@ -287,7 +292,7 @@ void WebhookActor::create_new_connections() { << td::tag("after", td::format::as_time(wakeup_at - now)); break; } - flood->add_event(static_cast(now)); + flood->add_event(now); if (create_connection().is_error()) { relax_wakeup_at(now + 1.0, "create_new_connections error"); return; diff --git a/telegram-bot-api/WebhookActor.h b/telegram-bot-api/WebhookActor.h index 28f5989..2538cc0 100644 --- a/telegram-bot-api/WebhookActor.h +++ b/telegram-bot-api/WebhookActor.h @@ -12,6 +12,7 @@ #include "td/net/HttpOutboundConnection.h" #include "td/net/HttpQuery.h" +#include "td/net/SslCtx.h" #include "td/net/SslStream.h" #include "td/actor/actor.h" @@ -76,7 +77,7 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback { bool tqueue_empty_ = false; std::size_t last_pending_update_count_ = MIN_PENDING_UPDATES_WARNING; td::HttpUrl url_; - td::string cert_path_; + const td::string cert_path_; std::shared_ptr parameters_; double last_error_time_ = 0; @@ -133,6 +134,7 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback { double first_error_410_time_ = 0; + td::SslCtx ssl_ctx_; td::IPAddress ip_address_; td::int32 ip_generation_ = 0; double next_ip_address_resolve_time_ = 0; @@ -176,6 +178,8 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback { void resolve_ip_address(); void on_resolved_ip_address(td::Result r_ip_address); + td::Status create_webhook_error(td::Slice error_message, td::Status &&result, bool is_public); + td::Result create_ssl_stream(); td::Status create_connection() TD_WARN_UNUSED_RESULT; td::Status create_connection(td::BufferedFd fd) TD_WARN_UNUSED_RESULT;