DnsOverHttps class with a test
GitOrigin-RevId: 4f8785377ddbe47a59fe6e03628685902503e1f6
This commit is contained in:
parent
fc3717109d
commit
dd190c7d79
@ -8,8 +8,57 @@
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/net/Wget.h"
|
||||
|
||||
namespace td {
|
||||
namespace detail {
|
||||
class GoogleDnsResolver : public Actor {
|
||||
public:
|
||||
GoogleDnsResolver(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise) {
|
||||
const int timeout = 10;
|
||||
const int ttl = 3;
|
||||
wget_ = create_actor<Wget>(
|
||||
"Wget", create_result_handler(std::move(promise), port),
|
||||
PSTRING() << "https://www.google.com/resolve?name=" << url_encode(host) << "&type=" << (prefer_ipv6 ? 28 : 1),
|
||||
std::vector<std::pair<string, string>>({{"Host", "dns.google.com"}}), timeout, ttl, prefer_ipv6,
|
||||
SslStream::VerifyPeer::Off);
|
||||
}
|
||||
|
||||
private:
|
||||
ActorOwn<Wget> wget_;
|
||||
|
||||
Promise<HttpQueryPtr> create_result_handler(Promise<IPAddress> promise, int port) {
|
||||
return PromiseCreator::lambda([promise = std::move(promise), port](Result<HttpQueryPtr> r_http_query) mutable {
|
||||
promise.set_result([&]() -> Result<IPAddress> {
|
||||
TRY_RESULT(http_query, std::move(r_http_query));
|
||||
LOG(ERROR) << *http_query;
|
||||
TRY_RESULT(json_value, json_decode(http_query->content_));
|
||||
if (json_value.type() != JsonValue::Type::Object) {
|
||||
return Status::Error("Failed to parse dns result: not an object");
|
||||
}
|
||||
TRY_RESULT(answer, get_json_object_field(json_value.get_object(), "Answer", JsonValue::Type::Array, false));
|
||||
if (answer.get_array().size() == 0) {
|
||||
return Status::Error("Failed to parse dns result: Answer is an empty array");
|
||||
}
|
||||
if (answer.get_array()[0].type() != JsonValue::Type::Object) {
|
||||
return Status::Error("Failed to parse dns result: Answer[0] is not an object");
|
||||
}
|
||||
auto &answer_0 = answer.get_array()[0].get_object();
|
||||
TRY_RESULT(ip_str, get_json_object_string_field(answer_0, "data", false));
|
||||
IPAddress ip;
|
||||
TRY_STATUS(ip.init_host_port(ip_str, port));
|
||||
return ip;
|
||||
}());
|
||||
});
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
ActorOwn<> DnsOverHttps::resolve(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise) {
|
||||
return ActorOwn<>(create_actor<detail::GoogleDnsResolver>("GoogleDnsResolver", std::move(host), port, prefer_ipv6,
|
||||
std::move(promise)));
|
||||
}
|
||||
|
||||
GetHostByNameActor::GetHostByNameActor(int32 ok_timeout, int32 error_timeout)
|
||||
: ok_timeout_(ok_timeout), error_timeout_(error_timeout) {
|
||||
|
@ -16,6 +16,12 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
class DnsOverHttps {
|
||||
public:
|
||||
static TD_WARN_UNUSED_RESULT ActorOwn<> resolve(std::string host, int port, bool prefer_ipv6,
|
||||
td::Promise<td::IPAddress> promise);
|
||||
};
|
||||
|
||||
class GetHostByNameActor final : public td::Actor {
|
||||
public:
|
||||
explicit GetHostByNameActor(int32 ok_timeout = CACHE_TIME, int32 error_timeout = ERROR_CACHE_TIME);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "td/net/Socks5.h"
|
||||
#include "td/net/TransparentProxy.h"
|
||||
#include "td/net/GetHostByNameActor.h"
|
||||
|
||||
#include "td/telegram/ConfigManager.h"
|
||||
#include "td/telegram/net/DcId.h"
|
||||
@ -32,6 +33,42 @@ REGISTER_TESTS(mtproto);
|
||||
|
||||
using namespace td;
|
||||
|
||||
TEST(Mtproto, DnsOverHttps) {
|
||||
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(WARNING));
|
||||
ConcurrentScheduler sched;
|
||||
int threads_n = 0;
|
||||
sched.init(threads_n);
|
||||
|
||||
int cnt = 1;
|
||||
{
|
||||
auto guard = sched.get_main_guard();
|
||||
|
||||
auto run = [&](bool prefer_ipv6) {
|
||||
auto promise = PromiseCreator::lambda([&, num = cnt](Result<IPAddress> r_ip_address) {
|
||||
if (r_ip_address.is_ok()) {
|
||||
LOG(WARNING) << num << " " << r_ip_address.ok();
|
||||
} else {
|
||||
LOG(ERROR) << num << " " << r_ip_address.error();
|
||||
}
|
||||
if (--cnt == 0) {
|
||||
Scheduler::instance()->finish();
|
||||
}
|
||||
});
|
||||
cnt++;
|
||||
DnsOverHttps::resolve("web.telegram.org", 443, prefer_ipv6, std::move(promise)).release();
|
||||
};
|
||||
|
||||
run(false);
|
||||
run(true);
|
||||
}
|
||||
cnt--;
|
||||
sched.start();
|
||||
while (sched.run_main(10)) {
|
||||
// empty;
|
||||
}
|
||||
sched.finish();
|
||||
}
|
||||
|
||||
TEST(Mtproto, config) {
|
||||
ConcurrentScheduler sched;
|
||||
int threads_n = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user