From 103b1176c1f37bde7806d7554157c261d33243cd Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 26 Mar 2017 09:16:42 -0400 Subject: [PATCH] remove torrent_file_path asynchronous loading of .torrent files. (#1848) remove torrent_file_path asynchronous loading of .torrent files. This is not the responsibility of the client, to simplify and unify the path of adding torrents --- ChangeLog | 2 +- examples/client_test.cpp | 188 +++++++++------------- include/libtorrent/add_torrent_params.hpp | 6 - include/libtorrent/aux_/session_impl.hpp | 5 + src/magnet_uri.cpp | 2 +- src/session_impl.cpp | 30 ++-- test/test_torrent.cpp | 25 --- 7 files changed, 97 insertions(+), 161 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0244991cc..50865add9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,5 @@ * optimize download queue management - * deprecated (undocumented) file:// urls, added torrent_file_path alternative + * deprecated (undocumented) file:// urls * add limit for number of web seed connections * added support for retrieval of DHT live nodes * complete UNC path support diff --git a/examples/client_test.cpp b/examples/client_test.cpp index c6ff89633..7aec25287 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -325,6 +325,22 @@ std::string path_append(std::string const& lhs, std::string const& rhs) return lhs + (need_sep?TORRENT_SEPARATOR:"") + rhs; } +std::string make_absolute_path(std::string const& p) +{ + if (is_absolute_path(p)) return p; + std::string ret; +#if defined TORRENT_WINDOWS + char* cwd = ::_getcwd(nullptr, 0); + ret = path_append(cwd, p); + std::free(cwd); +#else + char* cwd = ::getcwd(nullptr, 0); + ret = path_append(cwd, p); + std::free(cwd); +#endif + return ret; +} + bool is_hex(char const *in, int len) { for (char const* end = in + len; in < end; ++in) @@ -587,9 +603,46 @@ void print_settings(int const start, int const num } } -void add_torrent(libtorrent::session& ses - , handles_t& files - , std::string torrent) +std::string resume_file(lt::sha1_hash const& info_hash) +{ + return path_append(save_path, path_append(".resume" + , to_hex(info_hash) + ".resume")); +} + +void add_magnet(lt::session& ses, lt::string_view uri) +{ + lt::add_torrent_params p; + lt::error_code ec; + lt::parse_magnet_uri(uri.to_string(), p, ec); + + if (ec) + { + std::printf("invalid magnet link \"%s\": %s\n" + , uri.to_string().c_str(), ec.message().c_str()); + return; + } + + std::vector resume_data; + load_file(resume_file(p.info_hash), resume_data, ec); + if (!ec) + { + p = lt::read_resume_data(&resume_data[0], int(resume_data.size()), ec); + if (ec) std::printf(" failed to load resume data: %s\n", ec.message().c_str()); + parse_magnet_uri(uri.to_string(), p, ec); + } + ec.clear(); + + if (seed_mode) p.flags |= lt::add_torrent_params::flag_seed_mode; + if (disable_storage) p.storage = lt::disabled_storage_constructor; + if (share_mode) p.flags |= lt::add_torrent_params::flag_share_mode; + p.save_path = save_path; + p.storage_mode = static_cast(allocation_mode); + + std::printf("adding magnet: %s\n", uri.to_string().c_str()); + ses.async_add_torrent(p); +} + +void add_torrent(libtorrent::session& ses, handles_t& files, std::string torrent) { using namespace libtorrent; static int counter = 0; @@ -597,15 +650,21 @@ void add_torrent(libtorrent::session& ses std::printf("[%d] %s\n", counter++, torrent.c_str()); error_code ec; + auto ti = std::make_shared(torrent, ec); + if (ec) + { + std::printf("failed to load torrent \"%s\": %s\n" + , torrent.c_str(), ec.message().c_str()); + return; + } + add_torrent_params p; std::vector resume_data; - std::string filename = path_append(save_path, path_append(".resume" - , leaf_path(torrent) + ".resume")); - load_file(filename, resume_data, ec); + load_file(resume_file(ti->info_hash()), resume_data, ec); if (!ec) { - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); + p = lt::read_resume_data(&resume_data[0], int(resume_data.size()), ec); if (ec) std::printf(" failed to load resume data: %s\n", ec.message().c_str()); } ec.clear(); @@ -614,7 +673,7 @@ void add_torrent(libtorrent::session& ses if (disable_storage) p.storage = disabled_storage_constructor; if (share_mode) p.flags |= add_torrent_params::flag_share_mode; - p.torrent_file_path = torrent; + p.ti = ti; p.save_path = save_path; p.storage_mode = (storage_mode_t)allocation_mode; p.flags &= ~add_torrent_params::flag_duplicate_is_error; @@ -623,29 +682,6 @@ void add_torrent(libtorrent::session& ses files.insert(std::pair(torrent, torrent_handle())); } -std::string make_absolute_path(char const* p) -{ - std::string ret; -#if defined TORRENT_WINDOWS - if (p[0] != '\0' && !(p[1] == ':' && p[2] == '\\')) - { - char* cwd = ::_getcwd(nullptr, 0); - ret = path_append(cwd, p); - std::free(cwd); - } - else ret = p; -#else - if (p[0] != '/') - { - char* cwd = ::getcwd(nullptr, 0); - ret = path_append(cwd, p); - std::free(cwd); - } - else ret = p; -#endif - return ret; -} - std::vector list_dir(std::string path , bool (*filter_fun)(lt::string_view) , libtorrent::error_code& ec) @@ -1000,8 +1036,7 @@ bool handle_alert(torrent_view& view, session_view& ses_view torrent_handle h = p->handle; auto const buf = write_resume_data_buf(p->params); torrent_status st = h.status(torrent_handle::query_save_path); - save_file(path_append(st.save_path, path_append(".resume", leaf_path( - hash_to_filename[st.info_hash]) + ".resume")), buf); + save_file(resume_file(st.info_hash), buf); if (h.is_valid() && non_files.find(h) == non_files.end() && std::none_of(files.begin(), files.end() @@ -1186,9 +1221,7 @@ int main(int argc, char* argv[]) std::set non_files; // load the torrents given on the commandline - - std::vector magnet_links; - std::vector torrents; + std::vector torrents; ip_filter loaded_ip_filter; for (int i = 1; i < argc; ++i) @@ -1362,52 +1395,16 @@ int main(int argc, char* argv[]) } #endif - for (auto const& magnet : magnet_links) - ses.async_add_torrent(magnet); - for (auto const& i : torrents) { - if (std::strstr(i.c_str(), "http://") == i.c_str() - || std::strstr(i.c_str(), "https://") == i.c_str() - || std::strstr(i.c_str(), "magnet:") == i.c_str()) + if (i.substr(0, 7) == "magnet:") { - add_torrent_params p; - - if (std::strstr(i.c_str(), "magnet:") == i.c_str()) - { - add_torrent_params tmp; - ec.clear(); - parse_magnet_uri(i, tmp, ec); - - if (ec) continue; - - std::string filename = path_append(save_path, path_append(".resume" - , to_hex(tmp.info_hash) + ".resume")); - - std::vector resume_data; - load_file(filename, resume_data, ec); - if (!ec) - { - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); - if (ec) std::printf(" failed to load resume data: %s\n", ec.message().c_str()); - } - ec.clear(); - } - - if (seed_mode) p.flags |= add_torrent_params::flag_seed_mode; - if (disable_storage) p.storage = disabled_storage_constructor; - if (share_mode) p.flags |= add_torrent_params::flag_share_mode; - p.save_path = save_path; - p.storage_mode = (storage_mode_t)allocation_mode; - p.url = i; - - std::printf("adding URL: %s\n", i.c_str()); - ses.async_add_torrent(p); - continue; + add_magnet(ses, i); + } + else + { + add_torrent(ses, files, i.to_string()); } - - // if it's a torrent file, open it as usual - add_torrent(ses, files, i.c_str()); } // main loop @@ -1515,39 +1512,10 @@ int main(int argc, char* argv[]) if (c == 'm') { char url[4096]; + url[0] = '\0'; puts("Enter magnet link:\n"); - int ret = std::scanf("%4095s", url); - - add_torrent_params p; - if (ret == 1 && std::strstr(url, "magnet:") == url) - { - add_torrent_params tmp; - parse_magnet_uri(url, tmp, ec); - - if (ec) continue; - - std::string filename = path_append(save_path, path_append(".resume" - , to_hex(tmp.info_hash) + ".resume")); - - std::vector resume_data; - load_file(filename, resume_data, ec); - if (!ec) - { - p = read_resume_data(&resume_data[0], int(resume_data.size()), ec); - if (ec) std::printf(" failed to load resume data: %s\n", ec.message().c_str()); - } - ec.clear(); - } - - if (seed_mode) p.flags |= add_torrent_params::flag_seed_mode; - if (disable_storage) p.storage = disabled_storage_constructor; - if (share_mode) p.flags |= add_torrent_params::flag_share_mode; - p.save_path = save_path; - p.storage_mode = (storage_mode_t)allocation_mode; - p.url = url; - - std::printf("adding URL: %s\n", url); - ses.async_add_torrent(p); + if (std::scanf("%4095s", url) == 1) add_magnet(ses, url); + else std::printf("failed to read magnet link\n"); } if (c == 'q') break; diff --git a/include/libtorrent/add_torrent_params.hpp b/include/libtorrent/add_torrent_params.hpp index f06116d08..7a9d881c3 100644 --- a/include/libtorrent/add_torrent_params.hpp +++ b/include/libtorrent/add_torrent_params.hpp @@ -60,8 +60,6 @@ namespace libtorrent // * url - when you have a magnet link // * info_hash - when all you have is an info-hash (this is similar to a // magnet link) - // * torrent_file_path - when you have the path to a .torrent file and want - // libtorrent to load it. (This is especially useful with async_add_torrent) // // one of those fields must be set. Another mandatory field is // ``save_path``. The add_torrent_params object is passed into one of the @@ -360,10 +358,6 @@ namespace libtorrent // state (``torrent_status::error``) will indicate what went wrong. std::string url; - // if you specify a ``torrent_file_path``, libtorrent will attempt to load - // a .torrent file from the file at the given path. - std::string torrent_file_path; - // flags controlling aspects of this torrent and how it's added. See // flags_t for details. // diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 3f2e7d21c..439902008 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -480,7 +480,10 @@ namespace libtorrent std::pair, bool> add_torrent_impl(add_torrent_params& p, error_code& ec); void async_add_torrent(add_torrent_params* params); + +#ifndef TORRENT_NO_DEPRECATE void on_async_load_torrent(add_torrent_params* params, error_code ec); +#endif void remove_torrent(torrent_handle const& h, int options) override; void remove_torrent_impl(std::shared_ptr tptr, int options) override; @@ -1091,6 +1094,7 @@ namespace libtorrent std::shared_ptr m_upnp; std::shared_ptr m_lsd; +#ifndef TORRENT_NO_DEPRECATE struct work_thread_t { work_thread_t() @@ -1110,6 +1114,7 @@ namespace libtorrent std::thread thread; }; std::unique_ptr m_torrent_load_thread; +#endif // mask is a bitmask of which protocols to remap on: // 1: NAT-PMP diff --git a/src/magnet_uri.cpp b/src/magnet_uri.cpp index 16b06859c..e34c9a428 100644 --- a/src/magnet_uri.cpp +++ b/src/magnet_uri.cpp @@ -167,7 +167,7 @@ namespace libtorrent #endif // BOOST_NO_EXCEPTIONS #endif // TORRENT_NO_DEPRECATE - // TODO: 3 take string_ref here instead + // TODO: 3 take string_view here instead void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec) { ec.clear(); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index dbdad3d58..e98a602a1 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -4597,22 +4597,18 @@ namespace aux { #ifndef TORRENT_NO_DEPRECATE if (!params->ti && string_begins_no_case("file://", params->url.c_str())) - { - params->torrent_file_path = resolve_file_url(params->url); - params->url.clear(); - } -#endif - - if (!params->ti && !params->torrent_file_path.empty()) { if (!m_torrent_load_thread) m_torrent_load_thread.reset(new work_thread_t()); m_torrent_load_thread->ios.post([params, this] { + std::string const torrent_file_path = resolve_file_url(params->url); + params->url.clear(); + std::unique_ptr holder2(params); error_code ec; - params->ti = std::make_shared(params->torrent_file_path, ec); + params->ti = std::make_shared(torrent_file_path, ec); this->m_io_service.post(std::bind(&session_impl::on_async_load_torrent , this, params, ec)); holder2.release(); @@ -4620,11 +4616,13 @@ namespace aux { holder.release(); return; } +#endif error_code ec; add_torrent(*params, ec); } +#ifndef TORRENT_NO_DEPRECATE void session_impl::on_async_load_torrent(add_torrent_params* params, error_code ec) { std::unique_ptr holder(params); @@ -4640,6 +4638,7 @@ namespace aux { params->url.clear(); add_torrent(*params, ec); } +#endif #ifndef TORRENT_DISABLE_EXTENSIONS void session_impl::add_extensions_to_torrent( @@ -4792,25 +4791,20 @@ namespace aux { parse_magnet_uri(params.url, params, ec); if (ec) return std::make_pair(ptr_t(), false); params.url.clear(); - params.torrent_file_path.clear(); } #ifndef TORRENT_NO_DEPRECATE if (!params.ti && string_begins_no_case("file://", params.url.c_str())) { - params.torrent_file_path = resolve_file_url(params.url); + std::string const torrent_file_path = resolve_file_url(params.url); params.url.clear(); + auto t = std::make_shared(torrent_file_path, std::ref(ec), 0); + if (ec) return std::make_pair(ptr_t(), false); + params.url.clear(); + params.ti = t; } #endif - if (!params.ti && !params.torrent_file_path.empty()) - { - auto t = std::make_shared(params.torrent_file_path, std::ref(ec), 0); - if (ec) return std::make_pair(ptr_t(), false); - params.url.clear(); - params.torrent_file_path.clear(); - params.ti = t; - } if (params.ti && !params.ti->is_valid()) { diff --git a/test/test_torrent.cpp b/test/test_torrent.cpp index ca3812b92..6ea77591a 100644 --- a/test/test_torrent.cpp +++ b/test/test_torrent.cpp @@ -440,31 +440,6 @@ TORRENT_TEST(async_load_deprecated) } #endif -TORRENT_TEST(async_load) -{ - settings_pack pack = settings(); - lt::session ses(pack); - - add_torrent_params p; - p.flags &= ~add_torrent_params::flag_paused; - p.flags &= ~add_torrent_params::flag_auto_managed; - std::string dir = parent_path(current_working_directory()); - - p.torrent_file_path = combine_path(combine_path(dir, "test_torrents"), "base.torrent"); - p.save_path = "."; - ses.async_add_torrent(p); - - alert const* a = wait_for_alert(ses, add_torrent_alert::alert_type); - TEST_CHECK(a); - if (a == nullptr) return; - auto const* ta = alert_cast(a); - TEST_CHECK(ta); - if (ta == nullptr) return; - TEST_CHECK(!ta->error); - TEST_CHECK(ta->params.ti->name() == "temp"); -} - - TORRENT_TEST(torrent_status) { TEST_EQUAL(static_cast(torrent_status::error_file_none), -1);