mirror of
https://github.com/transmission/transmission
synced 2024-12-24 16:52:39 +00:00
refactor: do not mix torrent, default trackers
This commit is contained in:
parent
7b377511a9
commit
581c3f9854
9 changed files with 134 additions and 84 deletions
|
@ -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`
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 : "");
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue