From 53c3e791976c20fdc835c4c196ee78fc812f321a Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 20 May 2024 13:46:32 +0300 Subject: [PATCH] Move class HttpDate to tdutils. --- td/telegram/Birthdate.cpp | 2 +- td/telegram/ConfigManager.cpp | 79 +----------------------------- td/telegram/ConfigManager.h | 18 ------- tdutils/CMakeLists.txt | 2 + tdutils/td/utils/HttpDate.cpp | 92 +++++++++++++++++++++++++++++++++++ tdutils/td/utils/HttpDate.h | 34 +++++++++++++ test/mtproto.cpp | 1 + 7 files changed, 131 insertions(+), 97 deletions(-) create mode 100644 tdutils/td/utils/HttpDate.cpp create mode 100644 tdutils/td/utils/HttpDate.h diff --git a/td/telegram/Birthdate.cpp b/td/telegram/Birthdate.cpp index 48918aea1e22..18c5dd12db9e 100644 --- a/td/telegram/Birthdate.cpp +++ b/td/telegram/Birthdate.cpp @@ -6,7 +6,7 @@ // #include "td/telegram/Birthdate.h" -#include "td/telegram/ConfigManager.h" +#include "td/utils/HttpDate.h" namespace td { diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 534e904ec426..d61d3bfbf1d1 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -56,10 +56,10 @@ #include "td/utils/emoji.h" #include "td/utils/FlatHashMap.h" #include "td/utils/format.h" +#include "td/utils/HttpDate.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" #include "td/utils/misc.h" -#include "td/utils/Parser.h" #include "td/utils/port/Clocks.h" #include "td/utils/Random.h" #include "td/utils/SliceBuilder.h" @@ -77,83 +77,6 @@ namespace td { int VERBOSITY_NAME(config_recoverer) = VERBOSITY_NAME(INFO); -Result HttpDate::to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second) { - if (year < 1970 || year > 2037) { - return Status::Error("Invalid year"); - } - if (month < 1 || month > 12) { - return Status::Error("Invalid month"); - } - if (day < 1 || day > days_in_month(year, month)) { - return Status::Error("Invalid day"); - } - if (hour < 0 || hour >= 24) { - return Status::Error("Invalid hour"); - } - if (minute < 0 || minute >= 60) { - return Status::Error("Invalid minute"); - } - if (second < 0 || second > 60) { - return Status::Error("Invalid second"); - } - - int32 res = 0; - for (int32 y = 1970; y < year; y++) { - res += (is_leap(y) + 365) * seconds_in_day(); - } - for (int32 m = 1; m < month; m++) { - res += days_in_month(year, m) * seconds_in_day(); - } - res += (day - 1) * seconds_in_day(); - res += hour * 60 * 60; - res += minute * 60; - res += second; - return res; -} - -Result HttpDate::parse_http_date(string slice) { - Parser p(slice); - p.read_till(','); // ignore week day - p.skip(','); - p.skip_whitespaces(); - p.skip_nofail('0'); - TRY_RESULT(day, to_integer_safe(p.read_word())); - auto month_name = p.read_word(); - to_lower_inplace(month_name); - TRY_RESULT(year, to_integer_safe(p.read_word())); - p.skip_whitespaces(); - p.skip_nofail('0'); - TRY_RESULT(hour, to_integer_safe(p.read_till(':'))); - p.skip(':'); - p.skip_nofail('0'); - TRY_RESULT(minute, to_integer_safe(p.read_till(':'))); - p.skip(':'); - p.skip_nofail('0'); - TRY_RESULT(second, to_integer_safe(p.read_word())); - auto gmt = p.read_word(); - TRY_STATUS(std::move(p.status())); - if (gmt != "GMT") { - return Status::Error("Timezone must be GMT"); - } - - static Slice month_names[12] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}; - - int month = 0; - - for (int m = 1; m <= 12; m++) { - if (month_names[m - 1] == month_name) { - month = m; - break; - } - } - - if (month == 0) { - return Status::Error("Unknown month name"); - } - - return HttpDate::to_unix_time(year, month, day, hour, minute, second); -} - Result decode_config(Slice input) { static auto rsa = mtproto::RSA::from_pem_public_key( "-----BEGIN RSA PUBLIC KEY-----\n" diff --git a/td/telegram/ConfigManager.h b/td/telegram/ConfigManager.h index b3207a0a6d6d..d8a0ac6f7e37 100644 --- a/td/telegram/ConfigManager.h +++ b/td/telegram/ConfigManager.h @@ -56,24 +56,6 @@ ActorOwn<> get_simple_config_firebase_realtime(Promise promi ActorOwn<> get_simple_config_firebase_firestore(Promise promise, bool prefer_ipv6, Slice domain_name, bool is_test, int32 scheduler_id); -class HttpDate { - static bool is_leap(int32 year) { - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); - } - static int32 seconds_in_day() { - return 24 * 60 * 60; - } - - public: - static int32 days_in_month(int32 year, int32 month) { - static int cnt[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - return cnt[month - 1] + (month == 2 && is_leap(year)); - } - - static Result to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second); - static Result parse_http_date(std::string slice); -}; - class ConfigRecoverer; class ConfigManager final : public NetQueryCallback { public: diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index 1240682fca09..f63bd90e5cf0 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -107,6 +107,7 @@ set(TDUTILS_SOURCE td/utils/Gzip.cpp td/utils/GzipByteFlow.cpp td/utils/Hints.cpp + td/utils/HttpDate.cpp td/utils/HttpUrl.cpp td/utils/JsonBuilder.cpp td/utils/logging.cpp @@ -231,6 +232,7 @@ set(TDUTILS_SOURCE td/utils/HazardPointers.h td/utils/Heap.h td/utils/Hints.h + td/utils/HttpDate.h td/utils/HttpUrl.h td/utils/int_types.h td/utils/invoke.h diff --git a/tdutils/td/utils/HttpDate.cpp b/tdutils/td/utils/HttpDate.cpp new file mode 100644 index 000000000000..da290ae3a74d --- /dev/null +++ b/tdutils/td/utils/HttpDate.cpp @@ -0,0 +1,92 @@ +// +// 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/utils/HttpDate.h" + +#include "td/utils/misc.h" +#include "td/utils/Parser.h" +#include "td/utils/Slice.h" + +namespace td { + +Result HttpDate::to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second) { + if (year < 1970 || year > 2037) { + return Status::Error("Invalid year"); + } + if (month < 1 || month > 12) { + return Status::Error("Invalid month"); + } + if (day < 1 || day > days_in_month(year, month)) { + return Status::Error("Invalid day"); + } + if (hour < 0 || hour >= 24) { + return Status::Error("Invalid hour"); + } + if (minute < 0 || minute >= 60) { + return Status::Error("Invalid minute"); + } + if (second < 0 || second > 60) { + return Status::Error("Invalid second"); + } + + int32 res = 0; + for (int32 y = 1970; y < year; y++) { + res += (is_leap(y) + 365) * seconds_in_day(); + } + for (int32 m = 1; m < month; m++) { + res += days_in_month(year, m) * seconds_in_day(); + } + res += (day - 1) * seconds_in_day(); + res += hour * 60 * 60; + res += minute * 60; + res += second; + return res; +} + +Result HttpDate::parse_http_date(string slice) { + Parser p(slice); + p.read_till(','); // ignore week day + p.skip(','); + p.skip_whitespaces(); + p.skip_nofail('0'); + TRY_RESULT(day, to_integer_safe(p.read_word())); + auto month_name = p.read_word(); + to_lower_inplace(month_name); + TRY_RESULT(year, to_integer_safe(p.read_word())); + p.skip_whitespaces(); + p.skip_nofail('0'); + TRY_RESULT(hour, to_integer_safe(p.read_till(':'))); + p.skip(':'); + p.skip_nofail('0'); + TRY_RESULT(minute, to_integer_safe(p.read_till(':'))); + p.skip(':'); + p.skip_nofail('0'); + TRY_RESULT(second, to_integer_safe(p.read_word())); + auto gmt = p.read_word(); + TRY_STATUS(std::move(p.status())); + if (gmt != "GMT") { + return Status::Error("Timezone must be GMT"); + } + + static Slice month_names[12] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}; + + int month = 0; + + for (int m = 1; m <= 12; m++) { + if (month_names[m - 1] == month_name) { + month = m; + break; + } + } + + if (month == 0) { + return Status::Error("Unknown month name"); + } + + return to_unix_time(year, month, day, hour, minute, second); +} + +} // namespace td diff --git a/tdutils/td/utils/HttpDate.h b/tdutils/td/utils/HttpDate.h new file mode 100644 index 000000000000..a2daf0784fd9 --- /dev/null +++ b/tdutils/td/utils/HttpDate.h @@ -0,0 +1,34 @@ +// +// 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/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +class HttpDate { + static bool is_leap(int32 year) { + return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); + } + + static int32 seconds_in_day() { + return 24 * 60 * 60; + } + + public: + static int32 days_in_month(int32 year, int32 month) { + static int cnt[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + return cnt[month - 1] + (month == 2 && is_leap(year)); + } + + static Result to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second); + + static Result parse_http_date(string slice); +}; + +} // namespace td diff --git a/test/mtproto.cpp b/test/mtproto.cpp index 293050189015..39087599b3e0 100644 --- a/test/mtproto.cpp +++ b/test/mtproto.cpp @@ -34,6 +34,7 @@ #include "td/utils/BufferedFd.h" #include "td/utils/common.h" #include "td/utils/crypto.h" +#include "td/utils/HttpDate.h" #include "td/utils/logging.h" #include "td/utils/port/Clocks.h" #include "td/utils/port/IPAddress.h"