1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Add TON Storage to Proxy via storage gateway (#577)

* Access ton storage from proxy, resolve "dns_storage_address" in tonlib

* Set storage gateway address in proxy args

Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
EmelyanenkoK 2022-12-29 17:28:50 +03:00 committed by GitHub
parent ad736c6bc3
commit 7347ec0b3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 171 additions and 73 deletions

View file

@ -425,7 +425,8 @@ class TcpToRldpRequestSender : public td::actor::Actor {
td::Promise<std::pair<std::unique_ptr<ton::http::HttpResponse>, std::shared_ptr<ton::http::HttpPayload>>> promise,
td::actor::ActorId<ton::adnl::Adnl> adnl, td::actor::ActorId<ton::dht::Dht> dht,
td::actor::ActorId<ton::rldp::Rldp> rldp, td::actor::ActorId<RldpHttpProxy> proxy,
td::actor::ActorId<DNSResolver> dns_resolver)
td::actor::ActorId<DNSResolver> dns_resolver,
ton::adnl::AdnlNodeIdShort storage_gateway)
: local_id_(local_id)
, host_(std::move(host))
, request_(std::move(request))
@ -435,17 +436,20 @@ class TcpToRldpRequestSender : public td::actor::Actor {
, dht_(dht)
, rldp_(rldp)
, proxy_(proxy)
, dns_resolver_(dns_resolver) {
}
void start_up() override {
resolve();
, dns_resolver_(dns_resolver)
, storage_gateway_(storage_gateway) {
}
void resolve();
void start_up() override {
td::Random::secure_bytes(id_.as_slice());
request_tl_ = request_->store_tl(id_);
resolve(host_);
}
void resolve(std::string host);
void resolved(ton::adnl::AdnlNodeIdShort id) {
dst_ = id;
td::Random::secure_bytes(id_.as_slice());
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
@ -459,7 +463,7 @@ class TcpToRldpRequestSender : public td::actor::Actor {
proxy_, is_tunnel())
.release();
auto f = ton::serialize_tl_object(request_->store_tl(id_), true);
auto f = ton::serialize_tl_object(request_tl_, true);
td::actor::send_closure(rldp_, &ton::rldp::Rldp::send_query_ex, local_id_, dst_, "http request over rldp",
std::move(P), td::Timestamp::in(30.0), std::move(f), 16 << 10);
}
@ -538,6 +542,7 @@ class TcpToRldpRequestSender : public td::actor::Actor {
std::unique_ptr<ton::http::HttpRequest> request_;
std::shared_ptr<ton::http::HttpPayload> request_payload_;
ton::tl_object_ptr<ton::ton_api::http_request> request_tl_;
td::Promise<std::pair<std::unique_ptr<ton::http::HttpResponse>, std::shared_ptr<ton::http::HttpPayload>>> promise_;
@ -546,6 +551,9 @@ class TcpToRldpRequestSender : public td::actor::Actor {
td::actor::ActorId<ton::rldp::Rldp> rldp_;
td::actor::ActorId<RldpHttpProxy> proxy_;
td::actor::ActorId<DNSResolver> dns_resolver_;
ton::adnl::AdnlNodeIdShort storage_gateway_ = ton::adnl::AdnlNodeIdShort::zero();
bool dns_resolve_sent_ = false;
std::unique_ptr<ton::http::HttpResponse> response_;
std::shared_ptr<ton::http::HttpPayload> response_payload_;
@ -983,15 +991,9 @@ class RldpHttpProxy : public td::actor::Actor {
}
}
{
if (is_client_) {
auto D = ton::dht::Dht::create_client(dht_id_, "", dht_config_, keyring_.get(), adnl_.get());
D.ensure();
dht_ = D.move_as_ok();
} else {
auto D = ton::dht::Dht::create(dht_id_, db_root_, dht_config_, keyring_.get(), adnl_.get());
D.ensure();
dht_ = D.move_as_ok();
}
auto D = ton::dht::Dht::create_client(dht_id_, "", dht_config_, keyring_.get(), adnl_.get());
D.ensure();
dht_ = D.move_as_ok();
td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_dht_node, dht_.get());
}
if (port_) {
@ -1104,15 +1106,20 @@ class RldpHttpProxy : public td::actor::Actor {
}
}
std::transform(host.begin(), host.end(), host.begin(), [](unsigned char c) { return std::tolower(c); });
if (!proxy_all_ &&
(host.size() < 5 || (host.substr(host.size() - 4) != ".ton" && host.substr(host.size() - 5) != ".adnl"))) {
bool allow = proxy_all_;
for (const char* suffix : {".adnl", ".ton", ".bag"}) {
if (td::ends_with(host, td::Slice(suffix))) {
allow = true;
}
}
if (!allow) {
promise.set_error(td::Status::Error(ton::ErrorCode::error, "bad server name"));
return;
}
td::actor::create_actor<TcpToRldpRequestSender>("outboundreq", local_id_, host, std::move(request),
std::move(payload), std::move(promise), adnl_.get(), dht_.get(),
rldp_.get(), actor_id(this), dns_resolver_.get())
rldp_.get(), actor_id(this), dns_resolver_.get(), storage_gateway_)
.release();
}
@ -1280,6 +1287,10 @@ class RldpHttpProxy : public td::actor::Actor {
proxy_all_ = value;
}
void set_storage_gateway(ton::adnl::AdnlNodeIdShort id) {
storage_gateway_ = id;
}
private:
struct Host {
struct Server {
@ -1317,15 +1328,43 @@ class RldpHttpProxy : public td::actor::Actor {
td::actor::ActorOwn<tonlib::TonlibClientWrapper> tonlib_client_;
td::actor::ActorOwn<DNSResolver> dns_resolver_;
ton::adnl::AdnlNodeIdShort storage_gateway_ = ton::adnl::AdnlNodeIdShort::zero();
std::map<td::Bits256,
std::function<void(ton::tl_object_ptr<ton::ton_api::http_getNextPayloadPart>, td::Promise<td::BufferSlice>)>>
payload_senders_;
};
void TcpToRldpRequestSender::resolve() {
auto S = td::Slice(host_);
if (S.size() >= 5 && S.substr(S.size() - 5) == ".adnl") {
void TcpToRldpRequestSender::resolve(std::string host) {
auto S = td::Slice(host);
if (td::ends_with(S, ".bag")) {
if (storage_gateway_.is_zero()) {
abort_query(td::Status::Error("storage gateway is not set"));
return;
}
td::Slice bag_id = S.substr(0, S.size() - 4);
td::Slice url = request_tl_->url_;
if (td::begins_with(url, "http://")) {
url.remove_prefix(7);
}
size_t pos = url.find('/');
if (pos == td::Slice::npos) {
url = "/";
} else {
url = url.substr(pos);
}
request_tl_->url_ = (PSTRING() << "/gateway/" << bag_id << url);
host = storage_gateway_.serialize() + ".adnl";
for (auto& header : request_tl_->headers_) {
if (td::to_lower(header->name_) == "host") {
header->value_ = host;
break;
}
}
resolved(storage_gateway_);
return;
}
if (td::ends_with(S, ".adnl")) {
S.truncate(S.size() - 5);
auto R = ton::adnl::AdnlNodeIdShort::parse(S);
if (R.is_error()) {
@ -1335,15 +1374,20 @@ void TcpToRldpRequestSender::resolve() {
resolved(R.move_as_ok());
return;
}
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<ton::adnl::AdnlNodeIdShort> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &TcpToRldpRequestSender::abort_query,
R.move_as_error_prefix("failed to resolve: "));
} else {
td::actor::send_closure(SelfId, &TcpToRldpRequestSender::resolved, R.move_as_ok());
}
});
td::actor::send_closure(dns_resolver_, &DNSResolver::resolve, host_, std::move(P));
if (dns_resolve_sent_) {
abort_query(td::Status::Error(PSTRING() << "unexpected dns result: " << host));
return;
}
dns_resolve_sent_ = true;
td::actor::send_closure(dns_resolver_, &DNSResolver::resolve, host,
[SelfId = actor_id(this)](td::Result<std::string> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &TcpToRldpRequestSender::abort_query,
R.move_as_error_prefix("failed to resolve: "));
} else {
td::actor::send_closure(SelfId, &TcpToRldpRequestSender::resolve, R.move_as_ok());
}
});
}
void HttpRldpPayloadSender::start_up() {
@ -1532,6 +1576,11 @@ int main(int argc, char *argv[]) {
logger_ = td::FileLog::create(fname.str()).move_as_ok();
td::log_interface = logger_.get();
});
p.add_checked_option('S', "storage-gateway", "adnl address of ton storage gateway", [&](td::Slice arg) -> td::Status {
TRY_RESULT(adnl, ton::adnl::AdnlNodeIdShort::parse(arg));
td::actor::send_closure(x, &RldpHttpProxy::set_storage_gateway, adnl);
return td::Status::OK();
});
p.add_checked_option('P', "proxy-all", "value=[YES|NO]. proxy all HTTP requests (default only *.ton and *.adnl)",
[&](td::Slice value) {
if (value == "YES" || value == "yes") {