improve support for loading torrents out of resume files

This commit is contained in:
Arvid Norberg
2012-11-08 02:07:10 +00:00
parent 5d21c6a1f4
commit 65e02c23e8
5 changed files with 99 additions and 70 deletions

View File

@@ -4916,13 +4916,20 @@ retry:
{
error_code ec;
torrent_handle handle = add_torrent(*params, ec);
m_alerts.post_alert(add_torrent_alert(handle, *params, ec));
delete params->resume_data;
delete params;
}
torrent_handle session_impl::add_torrent(add_torrent_params const& p
, error_code& ec)
{
torrent_handle h = add_torrent_impl(p, ec);
m_alerts.post_alert(add_torrent_alert(h, p, ec));
return h;
}
torrent_handle session_impl::add_torrent_impl(add_torrent_params const& p
, error_code& ec)
{
TORRENT_ASSERT(!p.save_path.empty());
@@ -4978,6 +4985,76 @@ retry:
}
else ih = &params.info_hash;
// we don't have a torrent file. If the user provided
// resume data, there may be some metadata in there
if ((!params.ti || !params.ti->is_valid())
&& params.resume_data)
{
int pos;
error_code ec;
lazy_entry tmp;
lazy_entry const* info = 0;
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
debug_log("adding magnet link with resume data");
#endif
if (lazy_bdecode(&(*params.resume_data)[0], &(*params.resume_data)[0]
+ params.resume_data->size(), tmp, ec, &pos) == 0
&& tmp.type() == lazy_entry::dict_t
&& (info = tmp.dict_find_dict("info")))
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
debug_log("found metadata in resume data");
#endif
// verify the info-hash of the metadata stored in the resume file matches
// the torrent we're loading
std::pair<char const*, int> buf = info->data_section();
sha1_hash resume_ih = hasher(buf.first, buf.second).final();
// if url is set, the info_hash is not actually the info-hash of the
// torrent, but the hash of the URL, until we have the full torrent
// only require the info-hash to match if we actually passed in one
if (resume_ih == params.info_hash
|| !params.url.empty()
|| params.info_hash.is_all_zeros())
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
debug_log("info-hash matched");
#endif
params.ti = new torrent_info(resume_ih);
if (params.ti->parse_info_section(*info, ec, 0))
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
debug_log("successfully loaded metadata from resume file");
#endif
// make the info-hash be the one in the resume file
params.info_hash = resume_ih;
ih = &params.info_hash;
}
else
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
debug_log("failed to load metadata from resume file: %s"
, ec.message().c_str());
#endif
}
}
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
else
{
debug_log("metadata info-hash failed");
}
#endif
}
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
else
{
debug_log("no metadata found");
}
#endif
}
// is the torrent already active?
boost::shared_ptr<torrent> torrent_ptr = find_torrent(*ih).lock();
if (!torrent_ptr && !params.uuid.empty()) torrent_ptr = find_torrent(params.uuid).lock();