From a00e5aa6c76498114ecc7124eb112a876b3db07c Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 29 Sep 2015 01:51:01 -0400 Subject: [PATCH] forward port patch to have resume data web seeds override .torrent file web seeds, and a flag to merge them --- ChangeLog | 2 ++ bindings/python/src/session.cpp | 1 + include/libtorrent/add_torrent_params.hpp | 16 ++++++++- include/libtorrent/torrent.hpp | 5 +++ src/torrent.cpp | 18 +++++++--- test/test_resume.cpp | 42 +++++++++++++++++++++++ 6 files changed, 79 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 203c640bf..1aa6a4ac3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -75,6 +75,8 @@ * almost completely changed the storage interface (for custom storage) * added support for hashing pieces in multiple threads + * introduce add_torrent_params flags to merge web seeds with resume data + (similar to trackers) * fix bug where dont_count_slow_torrents could not be disabled * fix fallocate hack on linux (fixes corruption on some architectures) * fix auto-manage bug with announce to tracker/lsd/dht limits diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index 8864e4011..2fd126f52 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -615,6 +615,7 @@ void bind_session() .value("flag_super_seeding", add_torrent_params::flag_super_seeding) .value("flag_sequential_download", add_torrent_params::flag_sequential_download) .value("flag_use_resume_save_path", add_torrent_params::flag_use_resume_save_path) + .value("flag_merge_resume_http_seeds", add_torrent_params::flag_merge_resume_http_seeds) ; class_("cache_status") #ifndef TORRENT_NO_DEPRECATE diff --git a/include/libtorrent/add_torrent_params.hpp b/include/libtorrent/add_torrent_params.hpp index 27cd0467b..ee2f885de 100644 --- a/include/libtorrent/add_torrent_params.hpp +++ b/include/libtorrent/add_torrent_params.hpp @@ -225,7 +225,11 @@ namespace libtorrent // defaults to off and specifies whether tracker URLs loaded from // resume data should be added to the trackers in the torrent or - // replace the trackers. + // replace the trackers. When replacing trackers (i.e. this flag is not + // set), any trackers passed in via add_torrent_params are also + // replaced by any trackers in the resume data. The default behavior is + // to have the resume data override the .torrent file _and_ the + // trackers added in add_torrent_params. flag_merge_resume_trackers = 0x100, // on by default and means that this torrent will be part of state @@ -253,6 +257,16 @@ namespace libtorrent // the torrent exempt from loading/unloading management. flag_pinned = 0x2000, + // defaults to off and specifies whether web seed URLs loaded from + // resume data should be added to the ones in the torrent file or + // replace them. No distinction is made between the two different kinds + // of web seeds (`BEP 17`_ and `BEP 19`_). When replacing web seeds + // (i.e. when this flag is not set), any web seeds passed in via + // add_torrent_params are also replaced. The default behavior is to + // have any web seeds in the resume data take presedence over whatever + // is passed in here as well as the .torrent file. + flag_merge_resume_http_seeds = 0x2000, + // internal default_flags = flag_pinned | flag_update_subscribe | flag_auto_managed | flag_paused | flag_apply_ip_filter diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 281e43e38..fe7eb753f 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -1695,6 +1695,11 @@ namespace libtorrent // present bool m_use_resume_save_path:1; + // if set to true, add web seed URLs loaded from resume + // data into this torrent instead of replacing the ones from the .torrent + // file + bool m_merge_resume_http_seeds:1; + #if TORRENT_USE_ASSERTS public: // set to false until we've loaded resume data diff --git a/src/torrent.cpp b/src/torrent.cpp index ff426b9eb..e05e512b9 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -253,6 +253,7 @@ namespace libtorrent , m_magnet_link(false) , m_apply_ip_filter(p.flags & add_torrent_params::flag_apply_ip_filter) , m_merge_resume_trackers(p.flags & add_torrent_params::flag_merge_resume_trackers) + , m_merge_resume_http_seeds(p.flags & add_torrent_params::flag_merge_resume_http_seeds) , m_padding(0) , m_priority(0) , m_incomplete(0xffffff) @@ -316,6 +317,9 @@ namespace libtorrent if (!m_torrent_file) m_torrent_file = (p.ti ? p.ti : boost::make_shared(info_hash)); + std::vector const& web_seeds = m_torrent_file->web_seeds(); + m_web_seeds.insert(m_web_seeds.end(), web_seeds.begin(), web_seeds.end()); + // add web seeds from add_torrent_params for (std::vector::const_iterator i = p.url_seeds.begin() , end(p.url_seeds.end()); i != end; ++i) @@ -1945,9 +1949,6 @@ namespace libtorrent update_piece_priorities(); } - std::vector const& web_seeds = m_torrent_file->web_seeds(); - m_web_seeds.insert(m_web_seeds.end(), web_seeds.begin(), web_seeds.end()); - #if TORRENT_USE_ASSERTS m_resume_data_loaded = true; #endif @@ -6914,7 +6915,17 @@ namespace libtorrent prioritize_udp_trackers(); } + // if merge resume http seeds is not set, we need to clear whatever web + // seeds we loaded from the .torrent file, because we want whatever's in + // the resume file to take precedence. If there aren't even any fields in + // the resume data though, keep the ones from the torrent bdecode_node url_list = rd.dict_find_list("url-list"); + bdecode_node httpseeds = rd.dict_find_list("httpseeds"); + if ((url_list || httpseeds) && !m_merge_resume_http_seeds) + { + m_web_seeds.clear(); + } + if (url_list) { for (int i = 0; i < url_list.list_size(); ++i) @@ -6926,7 +6937,6 @@ namespace libtorrent } } - bdecode_node httpseeds = rd.dict_find_list("httpseeds"); if (httpseeds) { for (int i = 0; i < httpseeds.list_size(); ++i) diff --git a/test/test_resume.cpp b/test/test_resume.cpp index 7a1e5f5e3..b81fbe7c6 100644 --- a/test/test_resume.cpp +++ b/test/test_resume.cpp @@ -56,6 +56,7 @@ boost::shared_ptr generate_torrent() lt::create_torrent t(fs, 128 * 1024, 6); t.add_tracker("http://torrent_file_tracker.com/announce"); + t.add_url_seed("http://torrent_file_url_seed.com/"); int num = t.num_pieces(); TEST_CHECK(num > 0); @@ -696,4 +697,45 @@ TORRENT_TEST(paused) // and trackers for instance } +TORRENT_TEST(url_seed_resume_data) +{ + // merge url seeds with resume data + fprintf(stderr, "flags: merge_resume_http_seeds\n"); + lt::session ses; + torrent_handle h = test_resume_flags(ses, + add_torrent_params::flag_merge_resume_http_seeds); + std::set us = h.url_seeds(); + std::set ws = h.http_seeds(); + + TEST_EQUAL(us.size(), 3); + TEST_EQUAL(std::count(us.begin(), us.end() + , "http://add_torrent_params_url_seed.com"), 1); + TEST_EQUAL(std::count(us.begin(), us.end() + , "http://torrent_file_url_seed.com/"), 1); + TEST_EQUAL(std::count(us.begin(), us.end() + , "http://resume_data_url_seed.com/"), 1); + + TEST_EQUAL(ws.size(), 1); + TEST_EQUAL(std::count(ws.begin(), ws.end() + , "http://resume_data_http_seed.com"), 1); +} + +TORRENT_TEST(resume_override_torrent) +{ + // resume data overrides the .torrent_file + fprintf(stderr, "flags: no merge_resume_http_seed\n"); + lt::session ses; + torrent_handle h = test_resume_flags(ses, + add_torrent_params::flag_merge_resume_trackers); + std::set us = h.url_seeds(); + std::set ws = h.http_seeds(); + + TEST_EQUAL(ws.size(), 1); + TEST_EQUAL(std::count(ws.begin(), ws.end() + , "http://resume_data_http_seed.com"), 1); + + TEST_EQUAL(us.size(), 1); + TEST_EQUAL(std::count(us.begin(), us.end() + , "http://resume_data_url_seed.com/"), 1); +}