Fix usage of HttpDate in ConfigRecoverer.

GitOrigin-RevId: 17007d6b0afe58a0479d3d596bc4463548a26930
This commit is contained in:
levlam 2019-07-11 23:32:45 +03:00
parent d69251faba
commit db8539d9df
4 changed files with 41 additions and 32 deletions

View File

@ -58,30 +58,32 @@
namespace td {
int VERBOSITY_NAME(config_recoverer) = VERBOSITY_NAME(INFO);
Result<int64> HttpDate::to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second) {
int64 res = 0;
Result<int32> HttpDate::to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second) {
if (year < 1970 || year > 2037) {
return td::Status::Error("invalid year");
return Status::Error("Invalid year");
}
if (month < 1 || month > 12) {
return td::Status::Error("invalid month");
return Status::Error("Invalid month");
}
if (day < 1 || day > days_in_month(year, month)) {
return td::Status::Error("invalid day");
return Status::Error("Invalid day");
}
if (hour < 0 || hour > 24) { // is hour == 24 possible?
return td::Status::Error("invalid hour");
if (hour < 0 || hour >= 24) {
return Status::Error("Invalid hour");
}
if (minute < 0 || minute > 60) {
return td::Status::Error("invalid minute");
if (minute < 0 || minute >= 60) {
return Status::Error("Invalid minute");
}
if (second < 0 || second > 60) {
return td::Status::Error("invalid second");
return Status::Error("Invalid second");
}
for (int y = 1970; y < year; y++) {
int32 res = 0;
for (int32 y = 1970; y < year; y++) {
res += (is_leap(y) + 365) * seconds_in_day();
}
for (int m = 1; m < month; m++) {
for (int32 m = 1; m < month; m++) {
res += days_in_month(year, m) * seconds_in_day();
}
res += (day - 1) * seconds_in_day();
@ -91,11 +93,12 @@ Result<int64> HttpDate::to_unix_time(int32 year, int32 month, int32 day, int32 h
return res;
}
Result<int64> HttpDate::parse_http_date(std::string slice) {
td::Parser p(slice);
Result<int32> HttpDate::parse_http_date(std::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<int32>(p.read_word()));
auto month_name = p.read_word();
to_lower_inplace(month_name);
@ -115,7 +118,7 @@ Result<int64> HttpDate::parse_http_date(std::string slice) {
return Status::Error("timezone must be GMT");
}
Slice month_names[12] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
static Slice month_names[12] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
int month = 0;
@ -134,7 +137,7 @@ Result<int64> HttpDate::parse_http_date(std::string slice) {
}
Result<SimpleConfig> decode_config(Slice input) {
static auto rsa = td::RSA::from_pem(
static auto rsa = RSA::from_pem(
"-----BEGIN RSA PUBLIC KEY-----\n"
"MIIBCgKCAQEAyr+18Rex2ohtVy8sroGP\n"
"BwXD3DOoKCSpjDqYoXgCqB7ioln4eDCFfOBUlfXUEvM/fnKCpF46VkAftlb4VuPD\n"
@ -207,7 +210,7 @@ static ActorOwn<> get_simple_config_impl(Promise<SimpleConfigResult> promise, in
promise.set_result([&]() -> Result<SimpleConfigResult> {
TRY_RESULT(http_query, std::move(r_query));
SimpleConfigResult res;
res.r_http_date = HttpDate::parse_http_date(http_query->get_arg("date").str());
res.r_http_date = HttpDate::parse_http_date(http_query->get_header("date").str());
res.r_config = decode_config(http_query->content_);
return res;
}());
@ -243,10 +246,9 @@ ActorOwn<> get_simple_config_google_dns(Promise<SimpleConfigResult> promise, con
PromiseCreator::lambda([promise = std::move(promise)](Result<unique_ptr<HttpQuery>> r_query) mutable {
promise.set_result([&]() -> Result<SimpleConfigResult> {
TRY_RESULT(http_query, std::move(r_query));
LOG(ERROR) << *http_query;
SimpleConfigResult res;
res.r_http_date = HttpDate::parse_http_date(http_query->get_arg("date").str());
res.r_http_date = HttpDate::parse_http_date(http_query->get_header("date").str());
res.r_config = [&]() -> Result<SimpleConfig> {
TRY_RESULT(json, json_decode(http_query->content_));
if (json.type() != JsonValue::Type::Object) {

View File

@ -30,7 +30,7 @@ class ConfigShared;
using SimpleConfig = tl_object_ptr<telegram_api::help_configSimple>;
struct SimpleConfigResult {
Result<SimpleConfig> r_config;
Result<int64> r_http_date;
Result<int32> r_http_date;
};
Result<SimpleConfig> decode_config(Slice input);
@ -42,19 +42,20 @@ ActorOwn<> get_simple_config_google_dns(Promise<SimpleConfigResult> promise, con
bool is_test, int32 scheduler_id);
class HttpDate {
public:
static bool is_leap(int year) {
static bool is_leap(int32 year) {
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
static int32 days_in_month(int year, int month) {
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 int64 seconds_in_day() {
static int32 seconds_in_day() {
return 24 * 60 * 60;
}
static Result<int64> to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second);
static Result<int64> parse_http_date(std::string slice);
public:
static Result<int32> to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second);
static Result<int32> parse_http_date(std::string slice);
};
using FullConfig = tl_object_ptr<telegram_api::config>;

View File

@ -753,7 +753,7 @@ void ConnectionCreator::request_raw_connection_by_ip(IPAddress ip_address, mtpro
};
auto token = next_token();
auto callback = td::make_unique<Callback>(std::move(socket_fd_promise));
LOG(INFO) << "Tls in ConfigRecoverer " << ip_address << " " << transport_type.secret.get_domain() << " "
LOG(INFO) << "TLS in ConfigRecoverer " << ip_address << " " << transport_type.secret.get_domain() << " "
<< transport_type.secret.emulate_tls() << " " << transport_type.secret.get_proxy_secret().size()
<< transport_type.secret.get_encoded_secret();
children_[token] = {false, create_actor<mtproto::TlsInit>(
@ -987,7 +987,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
bool was_connected_{false};
unique_ptr<detail::StatsCallback> stats_callback_;
};
LOG(INFO) << "Start " << (proxy.use_socks5_proxy() ? "Socks5" : (proxy.use_http_tcp_proxy() ? "HTTP" : "Tls"))
LOG(INFO) << "Start " << (proxy.use_socks5_proxy() ? "Socks5" : (proxy.use_http_tcp_proxy() ? "HTTP" : "TLS"))
<< ": " << extra.debug_str;
auto token = next_token();
auto callback = td::make_unique<Callback>(std::move(promise), std::move(stats_callback));

View File

@ -144,11 +144,17 @@ TEST(Mtproto, config) {
auto guard = sched.get_main_guard();
auto run = [&](auto &func, bool is_test) {
auto promise = PromiseCreator::lambda([&, num = cnt](Result<SimpleConfig> r_simple_config) {
if (r_simple_config.is_ok()) {
LOG(WARNING) << num << " " << to_string(r_simple_config.ok());
auto promise = PromiseCreator::lambda([&, num = cnt](Result<SimpleConfigResult> r_simple_config_result) {
if (r_simple_config_result.is_ok()) {
auto simple_config_result = r_simple_config_result.move_as_ok();
auto date = simple_config_result.r_http_date.is_ok()
? to_string(simple_config_result.r_http_date.ok())
: (PSTRING() << simple_config_result.r_http_date.error());
auto config = simple_config_result.r_config.is_ok() ? to_string(simple_config_result.r_config.ok())
: (PSTRING() << simple_config_result.r_config.error());
LOG(ERROR) << num << " " << date << " " << config;
} else {
LOG(ERROR) << num << " " << r_simple_config.error();
LOG(ERROR) << num << " " << r_simple_config_result.error();
}
if (--cnt == 0) {
Scheduler::instance()->finish();