fixed restoring of trackers, comment, creation date and created-by in resume data

This commit is contained in:
arvidn 2019-11-23 21:53:30 +01:00 committed by Arvid Norberg
parent a53d090313
commit 97a79d2dba
10 changed files with 194 additions and 20 deletions

View File

@ -1,3 +1,4 @@
* fixed restoring of trackers, comment, creation date and created-by in resume data
* fix handling of torrents with too large pieces
* fixed division by zero in anti-leech choker
* fixed bug in torrent_info::swap

View File

@ -183,12 +183,22 @@ namespace torrent_flags {
// object override any trackers from the torrent file. If the flag is
// not set, the trackers from the add_torrent_params object will be
// added to the list of trackers used by the torrent.
// This flag is set by read_resume_data() if there are trackers present in
// the resume data file. This effectively makes the trackers saved in the
// resume data take presedence over the original trackers. This includes if
// there's an empty list of trackers, to support the case where they were
// explicitly removed in the previous session.
constexpr torrent_flags_t override_trackers = 11_bit;
// If this flag is set, the web seeds from the add_torrent_params
// object will override any web seeds in the torrent file. If it's not
// set, web seeds in the add_torrent_params object will be added to the
// list of web seeds used by the torrent.
// This flag is set by read_resume_data() if there are web seeds present in
// the resume data file. This effectively makes the web seeds saved in the
// resume data take presedence over the original ones. This includes if
// there's an empty list of web seeds, to support the case where they were
// explicitly removed in the previous session.
constexpr torrent_flags_t override_web_seeds = 12_bit;
// if this flag is set (which it is by default) the torrent will be

View File

@ -566,6 +566,11 @@ namespace libtorrent {
, piece_index_t piece);
std::map<int, sha1_hash> build_merkle_list(piece_index_t piece) const;
// internal
void internal_set_creator(string_view const);
void internal_set_creation_date(std::time_t);
void internal_set_comment(string_view const);
// returns whether or not this is a merkle torrent.
// see `BEP 30`__.
//

View File

@ -115,6 +115,12 @@ namespace {
{
ec = err;
}
else
{
ret.ti->internal_set_creation_date(rd.dict_find_int_value("creation date", 0));
ret.ti->internal_set_creator(rd.dict_find_string_value("created by", ""));
ret.ti->internal_set_comment(rd.dict_find_string_value("comment", ""));
}
}
}

View File

@ -6211,16 +6211,13 @@ bool is_downloading_state(int const st)
}
// save web seeds
if (!m_web_seeds.empty())
for (auto const& ws : m_web_seeds)
{
for (auto const& ws : m_web_seeds)
{
if (ws.removed || ws.ephemeral) continue;
if (ws.type == web_seed_entry::url_seed)
ret.url_seeds.push_back(ws.url);
else if (ws.type == web_seed_entry::http_seed)
ret.http_seeds.push_back(ws.url);
}
if (ws.removed || ws.ephemeral) continue;
if (ws.type == web_seed_entry::url_seed)
ret.url_seeds.push_back(ws.url);
else if (ws.type == web_seed_entry::http_seed)
ret.http_seeds.push_back(ws.url);
}
// write have bitmask

View File

@ -1347,6 +1347,15 @@ namespace {
return true;
}
void torrent_info::internal_set_creator(string_view const c)
{ m_created_by = std::string(c); }
void torrent_info::internal_set_creation_date(std::time_t const t)
{ m_creation_date = t; }
void torrent_info::internal_set_comment(string_view const s)
{ m_comment = std::string(s); }
// builds a list of nodes that are required to verify
// the given piece
std::map<int, sha1_hash>

View File

@ -92,6 +92,12 @@ namespace libtorrent {
auto const info = atp.ti->metadata();
int const size = atp.ti->metadata_size();
ret["info"].preformatted().assign(&info[0], &info[0] + size);
if (!atp.ti->comment().empty())
ret["comment"] = atp.ti->comment();
if (atp.ti->creation_date() != 0)
ret["creation date"] = atp.ti->creation_date();
if (!atp.ti->creator().empty())
ret["created by"] = atp.ti->creator();
}
if (!atp.merkle_tree.empty())
@ -123,9 +129,9 @@ namespace libtorrent {
}
// save trackers
entry::list_type& tr_list = ret["trackers"].list();
if (!atp.trackers.empty())
{
entry::list_type& tr_list = ret["trackers"].list();
tr_list.emplace_back(entry::list_type());
std::size_t tier = 0;
auto tier_it = atp.tracker_tiers.begin();
@ -142,17 +148,11 @@ namespace libtorrent {
}
// save web seeds
if (!atp.url_seeds.empty())
{
entry::list_type& url_list = ret["url-list"].list();
std::copy(atp.url_seeds.begin(), atp.url_seeds.end(), std::back_inserter(url_list));
}
entry::list_type& url_list = ret["url-list"].list();
std::copy(atp.url_seeds.begin(), atp.url_seeds.end(), std::back_inserter(url_list));
if (!atp.http_seeds.empty())
{
entry::list_type& url_list = ret["httpseeds"].list();
std::copy(atp.http_seeds.begin(), atp.http_seeds.end(), std::back_inserter(url_list));
}
entry::list_type& httpseeds_list = ret["httpseeds"].list();
std::copy(atp.http_seeds.begin(), atp.http_seeds.end(), std::back_inserter(httpseeds_list));
// write have bitmask
entry::string_type& pieces = ret["pieces"].string();

View File

@ -84,6 +84,8 @@ std::shared_ptr<torrent_info> generate_torrent(bool const with_files)
fs.add_file("test_resume/tmp3", 128 * 1024);
lt::create_torrent t(fs, 128 * 1024, 6);
t.set_comment("test comment");
t.set_creator("libtorrent test");
t.add_tracker("http://torrent_file_tracker.com/announce");
t.add_url_seed("http://torrent_file_url_seed.com/");

View File

@ -287,3 +287,10 @@ TORRENT_TEST(round_trip_unfinished)
test_roundtrip(atp);
}
TORRENT_TEST(round_trip_trackers)
{
add_torrent_params atp;
atp.flags |= torrent_flags::override_trackers;
test_roundtrip(atp);
}

View File

@ -276,6 +276,143 @@ TORRENT_TEST(piece_priorities)
test_piece_priorities();
}
TORRENT_TEST(test_non_metadata)
{
lt::session ses(settings());
// this test torrent contain a tracker:
// http://torrent_file_tracker.com/announce
// and a URL seed:
// http://torrent_file_url_seed.com
std::shared_ptr<torrent_info> ti = generate_torrent();
add_torrent_params p;
p.ti = ti;
p.save_path = ".";
torrent_handle h = ses.add_torrent(p);
h.replace_trackers(std::vector<lt::announce_entry>{announce_entry{"http://torrent_file_tracker2.com/announce"}});
h.remove_url_seed("http://torrent_file_url_seed.com/");
h.add_url_seed("http://torrent.com/");
TEST_EQUAL(ti->comment(), "test comment");
TEST_EQUAL(ti->creator(), "libtorrent test");
auto const creation_date = ti->creation_date();
h.save_resume_data(torrent_handle::save_info_dict);
alert const* a = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(a);
save_resume_data_alert const* ra = alert_cast<save_resume_data_alert>(a);
TEST_CHECK(ra);
if (ra)
{
auto const& atp = ra->params;
TEST_CHECK(atp.trackers == std::vector<std::string>{"http://torrent_file_tracker2.com/announce"});
TEST_CHECK(atp.url_seeds == std::vector<std::string>{"http://torrent.com/"});
TEST_CHECK(atp.ti);
TEST_EQUAL(atp.ti->comment(), "test comment");
TEST_EQUAL(atp.ti->creator(), "libtorrent test");
TEST_EQUAL(atp.ti->creation_date(), creation_date);
std::vector<char> resume_data = write_resume_data_buf(atp);
p = read_resume_data(resume_data);
p.ti = ti;
p.save_path = ".";
}
ses.remove_torrent(h);
// now, make sure the fields are restored correctly
h = ses.add_torrent(p);
TEST_EQUAL(h.trackers().size(), 1);
TEST_CHECK(h.trackers().at(0).url == "http://torrent_file_tracker2.com/announce");
TEST_CHECK(h.url_seeds() == std::set<std::string>{"http://torrent.com/"});
auto t = h.status().torrent_file.lock();
TEST_EQUAL(ti->comment(), "test comment");
TEST_EQUAL(ti->creator(), "libtorrent test");
TEST_EQUAL(ti->creation_date(), creation_date);
}
TORRENT_TEST(test_remove_trackers)
{
lt::session ses(settings());
// this test torrent contain a tracker:
// http://torrent_file_tracker.com/announce
std::shared_ptr<torrent_info> ti = generate_torrent();
add_torrent_params p;
p.ti = ti;
p.save_path = ".";
torrent_handle h = ses.add_torrent(p);
h.replace_trackers(std::vector<lt::announce_entry>{});
h.save_resume_data(torrent_handle::save_info_dict);
alert const* a = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(a);
save_resume_data_alert const* ra = alert_cast<save_resume_data_alert>(a);
TEST_CHECK(ra);
if (ra)
{
auto const& atp = ra->params;
TEST_EQUAL(atp.trackers.size(), 0);
std::vector<char> resume_data = write_resume_data_buf(atp);
p = read_resume_data(resume_data);
p.ti = ti;
p.save_path = ".";
}
ses.remove_torrent(h);
// now, make sure the fields are restored correctly
h = ses.add_torrent(p);
TEST_EQUAL(h.trackers().size(), 0);
}
TORRENT_TEST(test_remove_web_seed)
{
lt::session ses(settings());
// this test torrent contain a URL seed:
// http://torrent_file_url_seed.com
std::shared_ptr<torrent_info> ti = generate_torrent();
add_torrent_params p;
p.ti = ti;
p.save_path = ".";
torrent_handle h = ses.add_torrent(p);
h.remove_url_seed("http://torrent_file_url_seed.com/");
h.save_resume_data(torrent_handle::save_info_dict);
alert const* a = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(a);
save_resume_data_alert const* ra = alert_cast<save_resume_data_alert>(a);
TEST_CHECK(ra);
if (ra)
{
auto const& atp = ra->params;
TEST_CHECK(atp.url_seeds.size() == 0);
std::vector<char> resume_data = write_resume_data_buf(atp);
p = read_resume_data(resume_data);
p.ti = ti;
p.save_path = ".";
}
ses.remove_torrent(h);
// now, make sure the fields are restored correctly
h = ses.add_torrent(p);
TEST_EQUAL(h.url_seeds().size(), 0);
}
TORRENT_TEST(piece_slots)
{
// make sure the "pieces" field is correctly accepted from resume data