feat: do separate IPv4 and IPv6 port checks in Qt and GTK Client (#6525)

* fix: specify `port-test` ip protocol in response when possible

* feat: IPv4 and IPv6 port test in Qt Client

* feat: shorten timeout of `port-test`

* feat: IPv4 and IPv6 port test in Gtk Client

* chore: housekeeping

* refactor: remove IP protocol error message

* code review: mikedld gtk

* feat: return tag in qt rpc response

* code review: mikedld qt

* feat: move port test button up alongside spin button

* fixup! code review: mikedld gtk

* fixup! code review: mikedld qt

* code review: port status initial text

* feat: decouple ipv4 and ipv6 status updates (GTK)

* feat: decouple ipv4 and ipv6 status updates (Qt)

* code review: unknown protocols are non-pending

Co-authored-by: Mike Gelfand <mikedld@users.noreply.github.com>

* code review: simplify status text when the statuses are the same

* Revert "feat: return tag in qt rpc response"

This reverts commit 2a022c2bb0ee7ddad81f8176839cf0d043422368.

* code review: add translation context for status text (GTK)

* code review: move `port_test_pending_` to `Impl` (GTK)

* fixup! code review: move `port_test_pending_` to `Impl` (GTK)

---------

Co-authored-by: Mike Gelfand <mikedld@users.noreply.github.com>
This commit is contained in:
Yat Ho
2024-01-22 06:50:26 +08:00
committed by GitHub
parent 29a566664a
commit 32ef92e7a7
12 changed files with 337 additions and 116 deletions

View File

@@ -1144,6 +1144,12 @@ void onPortTested(tr_web::FetchResponse const& web_response)
auto const& [status, body, primary_ip, did_connect, did_timeout, user_data] = web_response;
auto* data = static_cast<tr_rpc_idle_data*>(user_data);
if (auto const addr = tr_address::from_string(primary_ip);
data->args_out.find_if<std::string_view>(TR_KEY_ipProtocol) == nullptr && addr && addr->is_valid())
{
data->args_out.try_emplace(TR_KEY_ipProtocol, addr->is_ipv4() ? "ipv4"sv : "ipv6"sv);
}
if (status != 200)
{
tr_idle_function_done(
@@ -1155,30 +1161,30 @@ void onPortTested(tr_web::FetchResponse const& web_response)
return;
}
auto const addr = tr_address::from_string(primary_ip);
if (!addr || !addr->is_valid())
{
tr_idle_function_done(data, "Unknown error, please file a bug report to us");
return;
}
data->args_out.try_emplace(TR_KEY_port_is_open, tr_strv_starts_with(body, '1'));
data->args_out.try_emplace(TR_KEY_ipProtocol, addr->is_ipv4() ? "ipv4"sv : "ipv6"sv);
tr_idle_function_done(data, SuccessResult);
}
char const* portTest(tr_session* session, tr_variant::Map const& args_in, struct tr_rpc_idle_data* idle_data)
{
auto ip_proto = tr_web::FetchOptions::IPProtocol::ANY;
static auto constexpr TimeoutSecs = 20s;
auto const port = session->advertisedPeerPort();
auto const url = fmt::format("https://portcheck.transmissionbt.com/{:d}", port.host());
auto options = tr_web::FetchOptions{ url, onPortTested, idle_data };
options.timeout_secs = TimeoutSecs;
if (auto const* val = args_in.find_if<std::string_view>(TR_KEY_ipProtocol); val != nullptr)
{
if (*val == "ipv4"sv)
{
ip_proto = tr_web::FetchOptions::IPProtocol::V4;
options.ip_proto = tr_web::FetchOptions::IPProtocol::V4;
idle_data->args_out.try_emplace(TR_KEY_ipProtocol, "ipv4"sv);
}
else if (*val == "ipv6"sv)
{
ip_proto = tr_web::FetchOptions::IPProtocol::V6;
options.ip_proto = tr_web::FetchOptions::IPProtocol::V6;
idle_data->args_out.try_emplace(TR_KEY_ipProtocol, "ipv6"sv);
}
else
{
@@ -1186,10 +1192,6 @@ char const* portTest(tr_session* session, tr_variant::Map const& args_in, struct
}
}
auto const port = session->advertisedPeerPort();
auto const url = fmt::format("https://portcheck.transmissionbt.com/{:d}", port.host());
auto options = tr_web::FetchOptions{ url, onPortTested, idle_data };
options.ip_proto = ip_proto;
session->fetch(std::move(options));
return nullptr;
}