diff --git a/libtransmission/announcer-http.cc b/libtransmission/announcer-http.cc index ddfb373f8..e0741b2be 100644 --- a/libtransmission/announcer-http.cc +++ b/libtransmission/announcer-http.cc @@ -56,14 +56,10 @@ static tr_urlbuf announce_url_new(tr_session const* session, tr_announce_request auto url = tr_urlbuf{}; auto out = std::back_inserter(url); - auto escaped_info_hash = std::array{}; - tr_http_escape_sha1(std::data(escaped_info_hash), req->info_hash); - fmt::format_to( out, "{url}" - "{sep}info_hash={info_hash}" - "&peer_id={peer_id}" + "{sep}peer_id={peer_id}" "&port={port}" "&uploaded={uploaded}" "&downloaded={downloaded}" @@ -74,7 +70,6 @@ static tr_urlbuf announce_url_new(tr_session const* session, tr_announce_request "&supportcrypto=1", fmt::arg("url", req->announce_url), fmt::arg("sep", tr_strvContains(req->announce_url.sv(), '?') ? '&' : '?'), - fmt::arg("info_hash", std::data(escaped_info_hash)), fmt::arg("peer_id", std::string_view{ std::data(req->peer_id), std::size(req->peer_id) }), fmt::arg("port", req->port.host()), fmt::arg("uploaded", req->up), @@ -83,6 +78,9 @@ static tr_urlbuf announce_url_new(tr_session const* session, tr_announce_request fmt::arg("numwant", req->numwant), fmt::arg("key", req->key)); + fmt::format_to(out, "&info_hash="); + tr_http_escape(out, req->info_hash); + if (session->encryptionMode() == TR_ENCRYPTION_REQUIRED) { fmt::format_to(out, "&requirecrypto=1"); @@ -652,12 +650,12 @@ static auto scrape_url_new(tr_scrape_request const* req) char delimiter = tr_strvContains(sv, '?') ? '&' : '?'; auto scrape_url = tr_pathbuf{ sv }; + auto out = std::back_inserter(scrape_url); for (int i = 0; i < req->info_hash_count; ++i) { - char str[SHA_DIGEST_LENGTH * 3 + 1]; - tr_http_escape_sha1(str, req->info_hash[i]); - scrape_url.append(delimiter, "info_hash=", str); + fmt::format_to(out, "{}info_hash=", delimiter); + tr_http_escape(out, req->info_hash[i]); delimiter = '&'; } diff --git a/libtransmission/web-utils.cc b/libtransmission/web-utils.cc index 02dda8b4f..7165046e0 100644 --- a/libtransmission/web-utils.cc +++ b/libtransmission/web-utils.cc @@ -172,29 +172,6 @@ char const* tr_webGetResponseStr(long code) } } -static bool is_rfc2396_alnum(uint8_t ch) -{ - return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ch == '.' || ch == '-' || - ch == '_' || ch == '~'; -} - -void tr_http_escape_sha1(char* out, tr_sha1_digest_t const& digest) -{ - for (auto const b : digest) - { - if (is_rfc2396_alnum(uint8_t(b))) - { - *out++ = (char)b; - } - else - { - out = fmt::format_to(out, FMT_STRING("%{:02x}"), unsigned(b)); - } - } - - *out = '\0'; -} - //// URLs namespace diff --git a/libtransmission/web-utils.h b/libtransmission/web-utils.h index 829f9e256..53c77af42 100644 --- a/libtransmission/web-utils.h +++ b/libtransmission/web-utils.h @@ -111,7 +111,11 @@ void tr_http_escape(OutputIt out, std::string_view in, bool escape_reserved) } } -void tr_http_escape_sha1(char* out, tr_sha1_digest_t const& digest); +template +void tr_http_escape(OutputIt out, tr_sha1_digest_t const& digest) +{ + tr_http_escape(out, std::string_view{ reinterpret_cast(digest.data()), std::size(digest) }, false); +} char const* tr_webGetResponseStr(long response_code); diff --git a/utils/show.cc b/utils/show.cc index 99ba64bcd..d2145556c 100644 --- a/utils/show.cc +++ b/utils/show.cc @@ -8,6 +8,7 @@ #include // PRIu64 #include #include +#include #include #include @@ -339,14 +340,9 @@ void doScrape(tr_torrent_metainfo const& metainfo) } // build the full scrape URL - auto escaped = std::array{}; - tr_http_escape_sha1(std::data(escaped), metainfo.infoHash()); auto const scrape = tracker.scrape.sv(); - auto const url = tr_urlbuf{ scrape, - tr_strvContains(scrape, '?') ? '&' : '?', - "info_hash="sv, - std::string_view{ std::data(escaped) } }; - + auto url = tr_urlbuf{ scrape, tr_strvContains(scrape, '?') ? '&' : '?', "info_hash="sv }; + tr_http_escape(std::back_inserter(url), metainfo.infoHash()); printf("%" TR_PRIsv " ... ", TR_PRIsv_ARG(url)); fflush(stdout);