diff --git a/ChangeLog b/ChangeLog index 9aeedd717..c74768fb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,8 @@ release 0.14.2 * improved error message for python setup script * fixed bug when torrent file included announce-list, but no valid tracker urls + * fixed bug where the files requested from web seeds would be the + renamed file names instead of the original file names in the torrent. release 0.14.1 diff --git a/docs/manual.rst b/docs/manual.rst index f5497bf11..f251d1181 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -1245,7 +1245,10 @@ The ``torrent_info`` has the following synopsis:: std::vector const& trackers() const; file_storage const& files() const; - file_storage& files(); + file_storage const& orig_files() const; + + void rename_file(int index, std::string const& new_filename); + void rename_file(int index, std::wstring const& new_filename); typedef file_storage::iterator file_iterator; typedef file_storage::reverse_iterator reverse_file_iterator; @@ -1328,12 +1331,13 @@ add_tracker() ``add_tracker()`` adds a tracker to the announce-list. The ``tier`` determines the order in which the trackers are to be tried. For more information see `trackers()`_. -files() -------- +files() orig_files() +-------------------- :: file_storage const& file() const; + file_storage const& orig_files() const; The ``file_storage`` object contains the information on how to map the pieces to files. It is separated from the ``torrent_info`` object because when creating torrents @@ -1341,6 +1345,10 @@ a storage object needs to be created without having a torrent file. When renamin in a storage, the storage needs to make its own copy of the ``file_storage`` in order to make its mapping differ from the one in the torrent file. +``orig_files()`` returns the original (unmodified) file storage for this torrent. This +is used by the web server connection, which needs to request files with the original +names. + For more information on the ``file_storage`` object, see the separate document on how to create torrents. diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index a02ddec82..dccbf6814 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -175,7 +175,19 @@ namespace libtorrent ~torrent_info(); file_storage const& files() const { return m_files; } - file_storage& files() { return m_files; } + file_storage const& orig_files() const { return m_orig_files ? *m_orig_files : m_files; } + + void rename_file(int index, std::string const& new_filename) + { + copy_on_write(); + m_files.rename_file(index, new_filename); + } + + void rename_file(int index, std::wstring const& new_filename) + { + copy_on_write(); + m_files.rename_file(index, new_filename); + } void add_tracker(std::string const& url, int tier = 0); std::vector const& trackers() const { return m_urls; } @@ -213,6 +225,7 @@ namespace libtorrent // these functions will be removed in a future version torrent_info(entry const& torrent_file) TORRENT_DEPRECATED; void print(std::ostream& os) const TORRENT_DEPRECATED; + file_storage& files() TORRENT_DEPRECATED { return m_files; } // ------- end deprecation ------- #endif @@ -270,10 +283,16 @@ namespace libtorrent private: + void copy_on_write(); bool parse_torrent_file(lazy_entry const& libtorrent, std::string& error); file_storage m_files; + // if m_files is modified, it is first copied into + // m_orig_files so that the original name and + // filenames are preserved. + boost::shared_ptr m_orig_files; + // the urls to the trackers std::vector m_urls; std::vector m_url_seeds; diff --git a/src/torrent.cpp b/src/torrent.cpp index f99dd2d54..dfe75ff71 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1935,7 +1935,7 @@ namespace libtorrent { if (alerts().should_post()) alerts().post_alert(file_renamed_alert(get_handle(), j.str, j.piece)); - m_torrent_file->files().rename_file(j.piece, j.str); + m_torrent_file->rename_file(j.piece, j.str); } else { @@ -2910,7 +2910,7 @@ namespace libtorrent { std::string new_filename = mapped_files->list_string_value_at(i); if (new_filename.empty()) continue; - m_torrent_file->files().rename_file(i, new_filename); + m_torrent_file->rename_file(i, new_filename); } } diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 9aeb6e1b9..d03893825 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -392,12 +392,19 @@ namespace libtorrent torrent_info::~torrent_info() {} + void torrent_info::copy_on_write() + { + if (m_orig_files) return; + m_orig_files.reset(new file_storage(m_files)); + } + void torrent_info::swap(torrent_info& ti) { using std::swap; m_urls.swap(ti.m_urls); m_url_seeds.swap(ti.m_url_seeds); m_files.swap(ti.m_files); + m_orig_files.swap(ti.m_orig_files); m_nodes.swap(ti.m_nodes); swap(m_info_hash, ti.m_info_hash); swap(m_creation_date, ti.m_creation_date); diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index fd8a30346..b856d0ec4 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -243,7 +243,7 @@ namespace libtorrent } else { - std::vector files = info.files().map_block(r.piece, r.start + std::vector files = info.orig_files().map_block(r.piece, r.start , r.length); for (std::vector::iterator i = files.begin(); @@ -255,13 +255,13 @@ namespace libtorrent if (using_proxy) { request += m_url; - std::string path = info.files().at(f.file_index).path.string(); + std::string path = info.orig_files().at(f.file_index).path.string(); request += escape_path(path.c_str(), path.length()); } else { std::string path = m_path; - path += info.files().at(f.file_index).path.string(); + path += info.orig_files().at(f.file_index).path.string(); request += escape_path(path.c_str(), path.length()); } request += " HTTP/1.1\r\n"; @@ -434,7 +434,7 @@ namespace libtorrent int file_index = m_file_requests.front(); torrent_info const& info = t->torrent_file(); - std::string path = info.files().at(file_index).path.string(); + std::string path = info.orig_files().at(file_index).path.string(); path = escape_path(path.c_str(), path.length()); size_t i = location.rfind(path); if (i == std::string::npos) @@ -528,7 +528,7 @@ namespace libtorrent } int file_index = m_file_requests.front(); - peer_request in_range = info.files().map_file(file_index, range_start + peer_request in_range = info.orig_files().map_file(file_index, range_start , int(range_end - range_start)); peer_request front_request = m_requests.front(); diff --git a/test/test_storage.cpp b/test/test_storage.cpp index 873869478..326cc4d84 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -503,11 +503,6 @@ void test_rename_file_in_fastresume() print_alerts(ses, "ses"); test_sleep(1000); torrent_status s = h.status(); - if (s.progress == 1.0f) - { - std::cout << "progress: 1.0f" << std::endl; - break; - } } resume = h.write_resume_data(); ses.remove_torrent(h); diff --git a/test/test_web_seed.cpp b/test/test_web_seed.cpp index d2435064e..3c230aaba 100644 --- a/test/test_web_seed.cpp +++ b/test/test_web_seed.cpp @@ -56,7 +56,7 @@ void test_transfer(boost::intrusive_ptr torrent_file, int proxy) session_settings settings; settings.ignore_limits_on_local_network = false; ses.set_settings(settings); - ses.set_severity_level(alert::debug); + ses.set_alert_mask(~alert::progress_notification); ses.listen_on(std::make_pair(51000, 52000)); ses.set_download_rate_limit(torrent_file->total_size() / 10); remove_all("./tmp1"); @@ -124,6 +124,7 @@ void test_transfer(boost::intrusive_ptr torrent_file, int proxy) if (proxy) stop_proxy(8002); + TEST_CHECK(exists("./tmp1" / torrent_file->file_at(0).path)); remove_all("./tmp1"); } @@ -175,6 +176,9 @@ int test_main() for (int i = 0; i < 6; ++i) test_transfer(torrent_file, i); + torrent_file->rename_file(0, "./test_torrent_dir/renamed_test1"); + test_transfer(torrent_file, 0); + stop_web_server(8000); remove_all("./test_torrent_dir"); return 0;