improve support for loading torrents out of resume files
This commit is contained in:
parent
5d21c6a1f4
commit
65e02c23e8
|
@ -6330,8 +6330,8 @@ The specific alerts are:
|
|||
torrent_added_alert
|
||||
-------------------
|
||||
|
||||
The ``torrent_added_alert`` is posted once every time a torrent is added.
|
||||
It doesn't contain any members of its own, but inherits the torrent handle
|
||||
The ``torrent_added_alert`` is posted once every time a torrent is successfully
|
||||
added. It doesn't contain any members of its own, but inherits the torrent handle
|
||||
from its base class.
|
||||
It's posted when the ``status_notification`` bit is set in the alert mask.
|
||||
|
||||
|
@ -6346,9 +6346,10 @@ It's posted when the ``status_notification`` bit is set in the alert mask.
|
|||
add_torrent_alert
|
||||
-----------------
|
||||
|
||||
This alert is always posted when a torrent was added via ``async_add_torrent()``
|
||||
This alert is always posted when a torrent was attempted to be added
|
||||
and contains the return status of the add operation. The torrent handle of the new
|
||||
torrent can be found in the base class' ``handle`` member.
|
||||
torrent can be found in the base class' ``handle`` member. If adding
|
||||
the torrent failed, ``error`` contains the error code.
|
||||
|
||||
::
|
||||
|
||||
|
@ -6362,7 +6363,7 @@ torrent can be found in the base class' ``handle`` member.
|
|||
``params`` is a copy of the parameters used when adding the torrent, it can be used
|
||||
to identify which invocation to ``async_add_torrent()`` caused this alert.
|
||||
|
||||
``error`` is set to the error, if any, adding the torrent.
|
||||
``error`` is set to the error, if one occurred while adding the torrent.
|
||||
|
||||
|
||||
torrent_removed_alert
|
||||
|
@ -6373,6 +6374,14 @@ the torrent handle in its baseclass will always be invalid (since the torrent
|
|||
is already removed) it has the info hash as a member, to identify it.
|
||||
It's posted when the ``status_notification`` bit is set in the alert mask.
|
||||
|
||||
Even though the ``handle`` member doesn't point to an existing torrent anymore,
|
||||
it is still useful for comparing to other handles, which may also no
|
||||
longer point to existing torrents, but to the same non-existing torrents.
|
||||
|
||||
The ``torrent_handle`` acts as a ``weak_ptr``, even though its object no
|
||||
longer exists, it can still compare equal to another weak pointer which
|
||||
points to the same non-existent object.
|
||||
|
||||
::
|
||||
|
||||
struct torrent_removed_alert: torrent_alert
|
||||
|
|
|
@ -348,6 +348,7 @@ namespace libtorrent
|
|||
bool is_listening() const;
|
||||
|
||||
torrent_handle add_torrent(add_torrent_params const&, error_code& ec);
|
||||
torrent_handle add_torrent_impl(add_torrent_params const&, error_code& ec);
|
||||
void async_add_torrent(add_torrent_params* params);
|
||||
|
||||
void remove_torrent(torrent_handle const& h, int options);
|
||||
|
|
|
@ -624,7 +624,12 @@ namespace libtorrent {
|
|||
}
|
||||
else
|
||||
{
|
||||
snprintf(msg, sizeof(msg), "added torrent: %s", !params.url.empty() ? params.url.c_str() : params.ti->name().c_str());
|
||||
snprintf(msg, sizeof(msg), "added torrent: %s"
|
||||
, !params.url.empty() ? params.url.c_str()
|
||||
: params.ti ? params.ti->name().c_str()
|
||||
: !params.name.empty() ? params.name.c_str()
|
||||
: !params.uuid.empty() ? params.uuid.c_str()
|
||||
: "");
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
|
|
@ -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 = ¶ms.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 = ¶ms.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();
|
||||
|
|
|
@ -446,69 +446,6 @@ namespace libtorrent
|
|||
// extension. Make sure that when we save resume data for this
|
||||
// torrent, we also save the metadata
|
||||
m_magnet_link = true;
|
||||
|
||||
// did the user provide resume data?
|
||||
// maybe the metadata is in there
|
||||
if (p.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(&(*p.resume_data)[0], &(*p.resume_data)[0]
|
||||
+ p.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
|
||||
if (resume_ih == info_hash || !p.url.empty())
|
||||
{
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
||||
debug_log("info-hash matched");
|
||||
#endif
|
||||
m_torrent_file = (p.ti ? p.ti : new torrent_info(resume_ih));
|
||||
|
||||
if (!m_torrent_file->parse_info_section(*info, ec, 0))
|
||||
{
|
||||
#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
|
||||
else
|
||||
{
|
||||
debug_log("successfully loaded metadata from resume file");
|
||||
}
|
||||
#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
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_torrent_file)
|
||||
|
|
Loading…
Reference in New Issue