refactor: do not mix torrent, default trackers

This commit is contained in:
Charles Kerr 2022-02-20 13:00:52 -06:00
parent 7b377511a9
commit 581c3f9854
9 changed files with 134 additions and 84 deletions

View File

@ -531,6 +531,7 @@ Response arguments: `path`, `name`, and `id`, holding the torrent ID integer
| `blocklist-url` | string | location of the blocklist to use for `blocklist-update`
| `cache-size-mb` | number | maximum size of the disk cache (MB)
| `config-dir` | string | location of transmission's configuration directory
| `default-trackers` | list of default trackers to use on public torrents
| `dht-enabled` | boolean | true means allow dht in public torrents
| `download-dir` | string | default path to download torrents
| `download-dir-free-space` | number | **DEPRECATED** Use the `free-space` method instead.
@ -940,6 +941,7 @@ Transmission 4.0.0 (`rpc-version-semver` 5.3.0, `rpc-version`: 17)
| `/upload` | :warning: undocumented `/upload` endpoint removed
| `session-get` | **DEPRECATED** `download-dir-free-space`. Use `free-space` instead.
| `free-space` | new return arg `total-capacity`
| `session-get` | new arg `default-trackers`
| `session-get` | new arg `rpc-version-semver`
| `session-get` | new arg `script-torrent-added-enabled`
| `session-get` | new arg `script-torrent-added-filename`

View File

@ -98,6 +98,29 @@ bool tr_announce_list::add(std::string_view announce_url_sv, tr_tracker_tier_t t
return true;
}
void tr_announce_list::add(tr_announce_list const& src)
{
if (std::empty(src))
{
return;
}
auto src_tier = src.at(0).tier;
auto& tgt = *this;
auto tgt_tier = tgt.nextTier();
for (auto const& tracker : src)
{
if (src_tier != tracker.tier)
{
src_tier = tracker.tier;
++tgt_tier;
}
tgt.add(tracker.announce.full, tgt_tier);
}
}
std::optional<std::string> tr_announce_list::announceToScrape(std::string_view announce)
{
// To derive the scrape URL use the following steps:

View File

@ -98,6 +98,7 @@ public:
}
bool add(std::string_view announce_url_sv, tr_tracker_tier_t tier);
void add(tr_announce_list const& that);
bool remove(std::string_view announce_url);
bool remove(tr_tracker_id_t id);
bool replace(tr_tracker_id_t id, std::string_view announce_url_sv);

View File

@ -505,7 +505,7 @@ struct tr_torrent_announcer
{
// build the trackers
auto tier_to_infos = std::map<tr_tracker_tier_t, std::vector<tr_announce_list::tracker_info const*>>{};
auto const& announce_list = tor->announceList();
auto const announce_list = getAnnounceList(tor);
for (auto const& info : announce_list)
{
tier_to_infos[info.tier].emplace_back(&info);
@ -575,6 +575,20 @@ struct tr_torrent_announcer
tr_tracker_callback callback = nullptr;
void* callback_data = nullptr;
private:
[[nodiscard]] static tr_announce_list getAnnounceList(tr_torrent const* tor)
{
auto announce_list = tor->announceList();
// if it's a public torrent, inject the default trackers
if (!tor->isPrivate())
{
announce_list.add(tor->session->defaultTrackers());
}
return announce_list;
}
};
static tr_tier* getTier(tr_announcer* announcer, tr_sha1_digest_t const& info_hash, int tier_id)

View File

@ -2077,7 +2077,7 @@ static void addSessionField(tr_session* s, tr_variant* d, tr_quark key)
break;
case TR_KEY_default_trackers:
tr_variantDictAddStr(d, key, s->defaultTrackers());
tr_variantDictAddStr(d, key, s->defaultTrackersStr());
break;
case TR_KEY_download_dir:

View File

@ -412,7 +412,7 @@ void tr_sessionGetSettings(tr_session const* s, tr_variant* d)
tr_variantDictAddBool(d, TR_KEY_utp_enabled, s->isUTPEnabled);
tr_variantDictAddBool(d, TR_KEY_lpd_enabled, s->isLPDEnabled);
tr_variantDictAddStr(d, TR_KEY_download_dir, tr_sessionGetDownloadDir(s));
tr_variantDictAddStr(d, TR_KEY_default_trackers, s->defaultTrackers());
tr_variantDictAddStr(d, TR_KEY_default_trackers, s->defaultTrackersStr());
tr_variantDictAddInt(d, TR_KEY_download_queue_size, tr_sessionGetQueueSize(s, TR_DOWN));
tr_variantDictAddBool(d, TR_KEY_download_queue_enabled, tr_sessionGetQueueEnabled(s, TR_DOWN));
tr_variantDictAddInt(d, TR_KEY_speed_limit_down, tr_sessionGetSpeedLimit_KBps(s, TR_DOWN));
@ -2253,45 +2253,15 @@ int tr_sessionGetCacheLimit_MB(tr_session const* session)
void tr_session::setDefaultTrackers(std::string_view trackers)
{
/* keep the string */
this->default_trackers_str_ = trackers;
/* clear out the old list entries */
this->defaultTrackersList.clear();
/* build the new list entries */
auto urlStart = std::string::npos;
auto constexpr Delimiters = " ,;\r\n\t"sv;
auto fragment = default_trackers_str_;
while ((urlStart = fragment.find_first_not_of(Delimiters)) != std::string::npos)
{
auto urlEnd = fragment.find_first_of(Delimiters, urlStart);
if (urlEnd == std::string::npos)
{
urlEnd = fragment.size() - 1;
}
else
{
urlEnd -= 1;
}
this->defaultTrackersList.push_back(fragment.substr(urlStart, urlEnd));
if (fragment.size() > (urlEnd + 1))
{
fragment = fragment.substr(urlEnd + 1, fragment.size());
}
else
{
break;
}
}
this->default_trackers_.parse(trackers);
}
void tr_sessionSetDefaultTrackers(tr_session* session, char const* trackers)
{
TR_ASSERT(tr_isSession(session));
session->setDefaultTrackers(trackers ? trackers : "");
session->setDefaultTrackers(trackers != nullptr ? trackers : "");
}
/***

View File

@ -27,6 +27,7 @@
#include "transmission.h"
#include "announce-list.h"
#include "net.h" // tr_socket_t
#include "quark.h"
#include "web.h"
@ -151,12 +152,18 @@ public:
}
// default trackers
// (trackers to apply automatically to public torrents)
std::string const& defaultTrackers() const
auto const& defaultTrackersStr() const
{
return default_trackers_str_;
}
auto const& defaultTrackers() const
{
return default_trackers_;
}
void setDefaultTrackers(std::string_view trackers);
// incomplete dir
@ -396,7 +403,7 @@ public:
std::unique_ptr<tr_rpc_server> rpc_server_;
std::list<std::string> defaultTrackersList;
tr_announce_list default_trackers_;
// One of <netinet/ip.h>'s IPTOS_ values.
// See tr_netTos*() in libtransmission/net.h for more info

View File

@ -817,52 +817,6 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
}
}
static void tr_torrentAddDefaultTrackers(tr_torrent* tor)
{
std::list<std::string> trackerURLs = {};
int numExistingTrackers = tr_torrentTrackerCount(tor);
int numNewTrackers = tor->session->defaultTrackersList.size();
if (!numNewTrackers || tor->isPrivate())
{
return;
}
// copy existing tracker URLs
for (int i = 0; i < numExistingTrackers; ++i)
{
auto tracker = tr_torrentTracker(tor, i);
trackerURLs.push_back(tracker.announce);
}
// add the new ones
for (std::string_view url : tor->session->defaultTrackersList)
{
if (tr_urlIsValidTracker(url))
{
// check for duplicates
bool duplicate = false;
for (auto trackerURL : trackerURLs)
{
if (trackerURL == url)
{
duplicate = true;
break;
}
}
if (duplicate)
{
continue;
}
tor->announceList().add(url);
}
}
/* tell the announcer to reload this torrent's tracker list */
tr_announcerResetTorrent(tor->session->announcer, tor);
}
tr_torrent* tr_torrentNew(tr_ctor* ctor, tr_torrent** setme_duplicate_of)
{
TR_ASSERT(ctor != nullptr);
@ -889,7 +843,6 @@ tr_torrent* tr_torrentNew(tr_ctor* ctor, tr_torrent** setme_duplicate_of)
auto* const tor = new tr_torrent{ std::move(metainfo) };
torrentInit(tor, ctor);
tr_torrentAddDefaultTrackers(tor);
return tor;
}

View File

@ -611,3 +611,83 @@ TEST_F(AnnounceListTest, parseDuplicateUrl)
EXPECT_FALSE(announce_list.parse(Text));
}
TEST_F(AnnounceListTest, addAnnounceListWithSingleTracker)
{
auto constexpr Trackers =
"https://www.foo.com/announce\n"
"\n"
"https://www.bar.com/announce\n"sv;
auto announce_list = tr_announce_list{};
announce_list.parse(Trackers);
auto constexpr AddStr = "https://www.baz.com/announce"sv;
auto tmp = tr_announce_list{};
tmp.parse(AddStr);
announce_list.add(tmp);
auto constexpr Expected =
"https://www.foo.com/announce\n"
"\n"
"https://www.bar.com/announce\n"
"\n"
"https://www.baz.com/announce\n"sv;
EXPECT_EQ(Expected, announce_list.toString());
}
TEST_F(AnnounceListTest, addAnnounceWithSingleTier)
{
auto constexpr Trackers =
"https://www.foo.com/announce\n"
"\n"
"https://www.bar.com/announce\n"sv;
auto announce_list = tr_announce_list{};
announce_list.parse(Trackers);
auto constexpr AddStr =
"https://www.baz.com/announce\n"
"https://www.qux.com/announce\n"sv;
auto tmp = tr_announce_list{};
tmp.parse(AddStr);
announce_list.add(tmp);
auto constexpr Expected =
"https://www.foo.com/announce\n"
"\n"
"https://www.bar.com/announce\n"
"\n"
"https://www.baz.com/announce\n"
"https://www.qux.com/announce\n"sv;
EXPECT_EQ(Expected, announce_list.toString());
}
TEST_F(AnnounceListTest, addAnnounceListWithMultiTier)
{
auto constexpr Trackers =
"https://www.foo.com/announce\n"
"\n"
"https://www.bar.com/announce\n"sv;
auto announce_list = tr_announce_list{};
announce_list.parse(Trackers);
auto constexpr AddStr =
"https://www.baz.com/announce\n"
"\n"
"https://www.qux.com/announce\n"sv;
auto tmp = tr_announce_list{};
tmp.parse(AddStr);
announce_list.add(tmp);
auto constexpr Expected =
"https://www.foo.com/announce\n"
"\n"
"https://www.bar.com/announce\n"
"\n"
"https://www.baz.com/announce\n"
"\n"
"https://www.qux.com/announce\n"sv;
EXPECT_EQ(Expected, announce_list.toString());
}