support adding torrents by url to a .torrent file
This commit is contained in:
parent
ae41b2598b
commit
26053e4b76
|
@ -1,4 +1,5 @@
|
||||||
* supporr CDATA tags in xml parser
|
* support adding torrents by url to the .torrent file
|
||||||
|
* support CDATA tags in xml parser
|
||||||
* use a python python dictionary for settings instead of session_settings object (in python bindings)
|
* use a python python dictionary for settings instead of session_settings object (in python bindings)
|
||||||
* optimized metadata transfer (magnet link) startup time (shaved off about 1 second)
|
* optimized metadata transfer (magnet link) startup time (shaved off about 1 second)
|
||||||
* optimized swarm startup time (shaved off about 1 second)
|
* optimized swarm startup time (shaved off about 1 second)
|
||||||
|
|
|
@ -187,6 +187,10 @@ namespace
|
||||||
p.upload_mode = params["share_mode"];
|
p.upload_mode = params["share_mode"];
|
||||||
if (params.has_key("override_resume_data"))
|
if (params.has_key("override_resume_data"))
|
||||||
p.override_resume_data = params["override_resume_data"];
|
p.override_resume_data = params["override_resume_data"];
|
||||||
|
if (params.has_key("trackerid"))
|
||||||
|
p.trackerid = extract<std::string>(params["trackerid"]);
|
||||||
|
if (params.has_key("url"))
|
||||||
|
p.url = extract<std::string>(params["url"]);
|
||||||
|
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
return s.add_torrent(p);
|
return s.add_torrent(p);
|
||||||
|
|
|
@ -384,6 +384,7 @@ add_torrent()
|
||||||
std::vector<boost::uint8_t> const* file_priorities;
|
std::vector<boost::uint8_t> const* file_priorities;
|
||||||
bool share_mode;
|
bool share_mode;
|
||||||
std::string trackerid;
|
std::string trackerid;
|
||||||
|
std::string url;
|
||||||
};
|
};
|
||||||
|
|
||||||
torrent_handle add_torrent(add_torrent_params const& params);
|
torrent_handle add_torrent(add_torrent_params const& params);
|
||||||
|
@ -396,9 +397,10 @@ object with all the parameters.
|
||||||
The overload that does not take an ``error_code`` throws an exception on
|
The overload that does not take an ``error_code`` throws an exception on
|
||||||
error and is not available when building without exception support.
|
error and is not available when building without exception support.
|
||||||
|
|
||||||
The only mandatory parameter is ``save_path`` which is the directory where you
|
The only mandatory parameters are ``save_path`` which is the directory where you
|
||||||
want the files to be saved. You also need to specify either the ``ti`` (the
|
want the files to be saved. You also need to specify either the ``ti`` (the
|
||||||
torrent file) or ``info_hash`` (the info hash of the torrent). If you specify the
|
torrent file), the ``info_hash`` (the info hash of the torrent) or the ``url``
|
||||||
|
(the URL to where to download the .torrent file from). If you specify the
|
||||||
info-hash, the torrent file will be downloaded from peers, which requires them to
|
info-hash, the torrent file will be downloaded from peers, which requires them to
|
||||||
support the metadata extension. For the metadata extension to work, libtorrent must
|
support the metadata extension. For the metadata extension to work, libtorrent must
|
||||||
be built with extensions enabled (``TORRENT_DISABLE_EXTENSIONS`` must not be
|
be built with extensions enabled (``TORRENT_DISABLE_EXTENSIONS`` must not be
|
||||||
|
@ -410,6 +412,11 @@ If the torrent doesn't have a tracker, but relies on the DHT to find peers, the
|
||||||
``tracker_url`` can be 0, otherwise you might specify a tracker url that tracks this
|
``tracker_url`` can be 0, otherwise you might specify a tracker url that tracks this
|
||||||
torrent.
|
torrent.
|
||||||
|
|
||||||
|
If you specify a ``url``, the torrent will be set in ``downloading_metadata`` state
|
||||||
|
until the .torrent file has been downloaded. If there's any error while downloading,
|
||||||
|
the torrent will be stopped and the torrent error state (``torrent_status::error``)
|
||||||
|
will indicate what went wrong. The ``url`` may also refer to a magnet link.
|
||||||
|
|
||||||
If the torrent you are trying to add already exists in the session (is either queued
|
If the torrent you are trying to add already exists in the session (is either queued
|
||||||
for checking, being checked or downloading) ``add_torrent()`` will throw
|
for checking, being checked or downloading) ``add_torrent()`` will throw
|
||||||
libtorrent_exception_ which derives from ``std::exception`` unless ``duplicate_is_error``
|
libtorrent_exception_ which derives from ``std::exception`` unless ``duplicate_is_error``
|
||||||
|
@ -5448,6 +5455,9 @@ the ``add_torrent_params``, ``p``. See `add_torrent()`_.
|
||||||
The overload that does not take an ``error_code`` throws an exception on
|
The overload that does not take an ``error_code`` throws an exception on
|
||||||
error and is not available when building without exception support.
|
error and is not available when building without exception support.
|
||||||
|
|
||||||
|
A simpler way to add a magnet link to a session is to pass in the
|
||||||
|
link through ``add_torrent_params::url`` argument to ``session::add_torrent()``.
|
||||||
|
|
||||||
For more information about magnet links, see `magnet links`_.
|
For more information about magnet links, see `magnet links`_.
|
||||||
|
|
||||||
make_magnet_uri()
|
make_magnet_uri()
|
||||||
|
|
|
@ -797,7 +797,7 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: client_test [OPTIONS] [TORRENT|MAGNETURL]\n\n"
|
fprintf(stderr, "usage: client_test [OPTIONS] [TORRENT|MAGNETURL|URL]\n\n"
|
||||||
"OPTIONS:\n"
|
"OPTIONS:\n"
|
||||||
" -f <log file> logs all events to the given file\n"
|
" -f <log file> logs all events to the given file\n"
|
||||||
" -o <limit> limits the number of simultaneous\n"
|
" -o <limit> limits the number of simultaneous\n"
|
||||||
|
@ -848,7 +848,8 @@ int main(int argc, char* argv[])
|
||||||
" "
|
" "
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"TORRENT is a path to a .torrent file\n"
|
"TORRENT is a path to a .torrent file\n"
|
||||||
"MAGNETURL is a magnet: url\n")
|
"MAGNETURL is a magnet link\n"
|
||||||
|
"URL is a url to a torrent file\n")
|
||||||
;
|
;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1108,16 +1109,19 @@ int main(int argc, char* argv[])
|
||||||
for (std::vector<std::string>::iterator i = torrents.begin()
|
for (std::vector<std::string>::iterator i = torrents.begin()
|
||||||
, end(torrents.end()); i != end; ++i)
|
, end(torrents.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
// first see if this is a torrentless download
|
if (std::strstr(i->c_str(), "http://") == i->c_str()
|
||||||
if (std::strstr(i->c_str(), "magnet:") == i->c_str())
|
|| std::strstr(i->c_str(), "https://") == i->c_str()
|
||||||
|
|| std::strstr(i->c_str(), "magnet:") == i->c_str())
|
||||||
{
|
{
|
||||||
add_torrent_params p;
|
add_torrent_params p;
|
||||||
p.share_mode = share_mode;
|
p.share_mode = share_mode;
|
||||||
p.save_path = save_path;
|
p.save_path = save_path;
|
||||||
p.storage_mode = (storage_mode_t)allocation_mode;
|
p.storage_mode = (storage_mode_t)allocation_mode;
|
||||||
printf("adding MANGET link: %s\n", i->c_str());
|
p.url = *i;
|
||||||
|
|
||||||
|
printf("adding URL: %s\n", i->c_str());
|
||||||
error_code ec;
|
error_code ec;
|
||||||
torrent_handle h = add_magnet_uri(ses, i->c_str(), p, ec);
|
torrent_handle h = ses.add_torrent(p, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s\n", ec.message().c_str());
|
fprintf(stderr, "%s\n", ec.message().c_str());
|
||||||
|
|
|
@ -85,6 +85,7 @@ namespace libtorrent
|
||||||
std::vector<boost::uint8_t> const* file_priorities;
|
std::vector<boost::uint8_t> const* file_priorities;
|
||||||
bool share_mode;
|
bool share_mode;
|
||||||
std::string trackerid;
|
std::string trackerid;
|
||||||
|
std::string url;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
struct http_parser;
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||||
struct logger;
|
struct logger;
|
||||||
#endif
|
#endif
|
||||||
|
@ -108,7 +110,8 @@ namespace libtorrent
|
||||||
public:
|
public:
|
||||||
|
|
||||||
torrent(aux::session_impl& ses, tcp::endpoint const& net_interface
|
torrent(aux::session_impl& ses, tcp::endpoint const& net_interface
|
||||||
, int block_size, int seq, add_torrent_params const& p);
|
, int block_size, int seq, add_torrent_params const& p
|
||||||
|
, sha1_hash const& info_hash);
|
||||||
~torrent();
|
~torrent();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
@ -122,6 +125,8 @@ namespace libtorrent
|
||||||
// starts the announce timer
|
// starts the announce timer
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
void start_download_url();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
void add_extension(boost::shared_ptr<torrent_plugin>);
|
void add_extension(boost::shared_ptr<torrent_plugin>);
|
||||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> const& ext
|
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> const& ext
|
||||||
|
@ -176,6 +181,7 @@ namespace libtorrent
|
||||||
, peer_request p);
|
, peer_request p);
|
||||||
void on_disk_cache_complete(int ret, disk_io_job const& j);
|
void on_disk_cache_complete(int ret, disk_io_job const& j);
|
||||||
|
|
||||||
|
void set_progress_ppm(int p) { m_progress_ppm = p; }
|
||||||
struct read_piece_struct
|
struct read_piece_struct
|
||||||
{
|
{
|
||||||
boost::shared_array<char> piece_data;
|
boost::shared_array<char> piece_data;
|
||||||
|
@ -761,6 +767,9 @@ namespace libtorrent
|
||||||
// a return value of false indicates an error
|
// a return value of false indicates an error
|
||||||
bool set_metadata(char const* metadata_buf, int metadata_size);
|
bool set_metadata(char const* metadata_buf, int metadata_size);
|
||||||
|
|
||||||
|
void on_torrent_download(error_code const& ec, http_parser const& parser
|
||||||
|
, char const* data, int size);
|
||||||
|
|
||||||
int sequence_number() const { return m_sequence_number; }
|
int sequence_number() const { return m_sequence_number; }
|
||||||
|
|
||||||
bool seed_mode() const { return m_seed_mode; }
|
bool seed_mode() const { return m_seed_mode; }
|
||||||
|
@ -964,6 +973,14 @@ namespace libtorrent
|
||||||
|
|
||||||
std::string m_save_path;
|
std::string m_save_path;
|
||||||
|
|
||||||
|
// if we don't have the metadata, this is a url to
|
||||||
|
// the torrent file
|
||||||
|
std::string m_url;
|
||||||
|
|
||||||
|
// this is used as temporary storage while downloading
|
||||||
|
// the .torrent file from m_url
|
||||||
|
std::vector<char> m_torrent_file_buf;
|
||||||
|
|
||||||
// each bit represents a piece. a set bit means
|
// each bit represents a piece. a set bit means
|
||||||
// the piece has had its hash verified. This
|
// the piece has had its hash verified. This
|
||||||
// is only used in seed mode (when m_seed_mode
|
// is only used in seed mode (when m_seed_mode
|
||||||
|
|
|
@ -198,6 +198,7 @@ namespace libtorrent { namespace
|
||||||
{
|
{
|
||||||
m_metadata_progress += received;
|
m_metadata_progress += received;
|
||||||
m_metadata_size = total_size;
|
m_metadata_size = total_size;
|
||||||
|
m_torrent.set_progress_ppm(boost::int64_t(m_metadata_progress) * 1000000 / m_metadata_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_piece_pass(int)
|
void on_piece_pass(int)
|
||||||
|
|
|
@ -72,6 +72,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/kademlia/dht_tracker.hpp"
|
#include "libtorrent/kademlia/dht_tracker.hpp"
|
||||||
#include "libtorrent/natpmp.hpp"
|
#include "libtorrent/natpmp.hpp"
|
||||||
#include "libtorrent/upnp.hpp"
|
#include "libtorrent/upnp.hpp"
|
||||||
|
#include "libtorrent/magnet_uri.hpp"
|
||||||
|
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
using boost::weak_ptr;
|
using boost::weak_ptr;
|
||||||
|
@ -481,6 +482,13 @@ namespace libtorrent
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
torrent_handle session::add_torrent(add_torrent_params const& params)
|
torrent_handle session::add_torrent(add_torrent_params const& params)
|
||||||
{
|
{
|
||||||
|
if (string_begins_no_case("magnet:", params.url.c_str()))
|
||||||
|
{
|
||||||
|
add_torrent_params p(params);
|
||||||
|
p.url.clear();
|
||||||
|
return add_magnet_uri(*this, params.url, p);
|
||||||
|
}
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, ec);
|
TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, ec);
|
||||||
if (ec) throw libtorrent_exception(ec);
|
if (ec) throw libtorrent_exception(ec);
|
||||||
|
@ -490,6 +498,13 @@ namespace libtorrent
|
||||||
|
|
||||||
torrent_handle session::add_torrent(add_torrent_params const& params, error_code& ec)
|
torrent_handle session::add_torrent(add_torrent_params const& params, error_code& ec)
|
||||||
{
|
{
|
||||||
|
if (string_begins_no_case("magnet:", params.url.c_str()))
|
||||||
|
{
|
||||||
|
add_torrent_params p(params);
|
||||||
|
p.url.clear();
|
||||||
|
return add_magnet_uri(*this, params.url, p, ec);
|
||||||
|
}
|
||||||
|
|
||||||
TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, ec);
|
TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, ec);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3453,7 +3453,18 @@ namespace aux {
|
||||||
|
|
||||||
// figure out the info hash of the torrent
|
// figure out the info hash of the torrent
|
||||||
sha1_hash const* ih = 0;
|
sha1_hash const* ih = 0;
|
||||||
|
sha1_hash tmp;
|
||||||
if (params.ti) ih = ¶ms.ti->info_hash();
|
if (params.ti) ih = ¶ms.ti->info_hash();
|
||||||
|
else if (!params.url.empty())
|
||||||
|
{
|
||||||
|
// in order to avoid info-hash collisions, for
|
||||||
|
// torrents where we don't have an info-hash, but
|
||||||
|
// just a URL, set the temporary info-hash to the
|
||||||
|
// hash of the URL. This will be changed once we
|
||||||
|
// have the actual .torrent file
|
||||||
|
tmp = hasher(¶ms.url[0], params.url.size()).final();
|
||||||
|
ih = &tmp;
|
||||||
|
}
|
||||||
else ih = ¶ms.info_hash;
|
else ih = ¶ms.info_hash;
|
||||||
|
|
||||||
// is the torrent already active?
|
// is the torrent already active?
|
||||||
|
@ -3476,7 +3487,7 @@ namespace aux {
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent_ptr.reset(new torrent(*this, m_listen_interface
|
torrent_ptr.reset(new torrent(*this, m_listen_interface
|
||||||
, 16 * 1024, queue_pos, params));
|
, 16 * 1024, queue_pos, params, *ih));
|
||||||
torrent_ptr->start();
|
torrent_ptr->start();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
|
|
130
src/torrent.cpp
130
src/torrent.cpp
|
@ -78,6 +78,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/kademlia/dht_tracker.hpp"
|
#include "libtorrent/kademlia/dht_tracker.hpp"
|
||||||
#include "libtorrent/peer_info.hpp"
|
#include "libtorrent/peer_info.hpp"
|
||||||
#include "libtorrent/enum_net.hpp"
|
#include "libtorrent/enum_net.hpp"
|
||||||
|
#include "libtorrent/http_connection.hpp"
|
||||||
|
#include "libtorrent/gzip.hpp" // for inflate_gzip
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
#include "libtorrent/ssl_stream.hpp"
|
#include "libtorrent/ssl_stream.hpp"
|
||||||
|
@ -321,18 +323,20 @@ namespace libtorrent
|
||||||
, tcp::endpoint const& net_interface
|
, tcp::endpoint const& net_interface
|
||||||
, int block_size
|
, int block_size
|
||||||
, int seq
|
, int seq
|
||||||
, add_torrent_params const& p)
|
, add_torrent_params const& p
|
||||||
|
, sha1_hash const& info_hash)
|
||||||
: m_policy(this)
|
: m_policy(this)
|
||||||
, m_total_uploaded(0)
|
, m_total_uploaded(0)
|
||||||
, m_total_downloaded(0)
|
, m_total_downloaded(0)
|
||||||
, m_started(time_now())
|
, m_started(time_now())
|
||||||
, m_torrent_file(p.ti ? p.ti : new torrent_info(p.info_hash))
|
, m_torrent_file(p.ti ? p.ti : new torrent_info(info_hash))
|
||||||
, m_storage(0)
|
, m_storage(0)
|
||||||
, m_tracker_timer(ses.m_io_service)
|
, m_tracker_timer(ses.m_io_service)
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_trackers(m_torrent_file->trackers())
|
, m_trackers(m_torrent_file->trackers())
|
||||||
, m_save_path(complete(p.save_path))
|
|
||||||
, m_trackerid(p.trackerid)
|
, m_trackerid(p.trackerid)
|
||||||
|
, m_save_path(complete(p.save_path))
|
||||||
|
, m_url(p.url)
|
||||||
, m_storage_constructor(p.storage)
|
, m_storage_constructor(p.storage)
|
||||||
, m_ratio(0.f)
|
, m_ratio(0.f)
|
||||||
, m_available_free_upload(0)
|
, m_available_free_upload(0)
|
||||||
|
@ -427,6 +431,7 @@ namespace libtorrent
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (p.name && !p.ti) m_name.reset(new std::string(p.name));
|
if (p.name && !p.ti) m_name.reset(new std::string(p.name));
|
||||||
|
if (!m_name && !m_url.empty()) m_name.reset(new std::string(m_url));
|
||||||
|
|
||||||
if (p.tracker_url && std::strlen(p.tracker_url) > 0)
|
if (p.tracker_url && std::strlen(p.tracker_url) > 0)
|
||||||
{
|
{
|
||||||
|
@ -437,6 +442,95 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// since this download is not bottled, this callback will
|
||||||
|
// be called every time we receive another piece of the
|
||||||
|
// .torrent file
|
||||||
|
void torrent::on_torrent_download(error_code const& ec
|
||||||
|
, http_parser const& parser
|
||||||
|
, char const* data, int size)
|
||||||
|
{
|
||||||
|
if (ec && ec != asio::error::eof)
|
||||||
|
{
|
||||||
|
set_error(ec, m_url);
|
||||||
|
pause();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (size > 0)
|
||||||
|
{
|
||||||
|
m_torrent_file_buf.insert(m_torrent_file_buf.end(), data, data + size);
|
||||||
|
if (parser.content_length() > 0)
|
||||||
|
set_progress_ppm(boost::int64_t(m_torrent_file_buf.size())
|
||||||
|
* 1000000 / parser.content_length());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ec) return;
|
||||||
|
|
||||||
|
std::string const& encoding = parser.header("content-encoding");
|
||||||
|
if ((encoding == "gzip" || encoding == "x-gzip") && m_torrent_file_buf.size())
|
||||||
|
{
|
||||||
|
std::vector<char> buf;
|
||||||
|
std::string error;
|
||||||
|
if (inflate_gzip(&m_torrent_file_buf[0], m_torrent_file_buf.size()
|
||||||
|
, buf, 4 * 1024 * 1024, error))
|
||||||
|
{
|
||||||
|
set_error(errors::http_failed_decompress, m_url);
|
||||||
|
pause();
|
||||||
|
std::vector<char>().swap(m_torrent_file_buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_torrent_file_buf.swap(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're done!
|
||||||
|
error_code e;
|
||||||
|
intrusive_ptr<torrent_info> tf(new torrent_info(
|
||||||
|
&m_torrent_file_buf[0], m_torrent_file_buf.size(), e));
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
set_error(e, m_url);
|
||||||
|
pause();
|
||||||
|
std::vector<char>().swap(m_torrent_file_buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<char>().swap(m_torrent_file_buf);
|
||||||
|
|
||||||
|
// update our torrent_info object and move the
|
||||||
|
// torrent from the old info-hash to the new one
|
||||||
|
// as we replace the torrent_info object
|
||||||
|
#ifdef TORRENT_DEBUG
|
||||||
|
int num_torrents = m_ses.m_torrents.size();
|
||||||
|
#endif
|
||||||
|
m_ses.m_torrents.erase(m_torrent_file->info_hash());
|
||||||
|
m_torrent_file = tf;
|
||||||
|
m_ses.m_torrents.insert(std::make_pair(m_torrent_file->info_hash(), shared_from_this()));
|
||||||
|
|
||||||
|
TORRENT_ASSERT(num_torrents == m_ses.m_torrents.size());
|
||||||
|
|
||||||
|
// TODO: if the user added any trackers while downloading the
|
||||||
|
// .torrent file, they are overwritten. Merge them into the
|
||||||
|
// new tracker list
|
||||||
|
m_trackers = m_torrent_file->trackers();
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
hasher h;
|
||||||
|
h.update("req2", 4);
|
||||||
|
h.update((char*)&m_torrent_file->info_hash()[0], 20);
|
||||||
|
m_obfuscated_hash = h.final();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m_ses.m_alerts.should_post<metadata_received_alert>())
|
||||||
|
{
|
||||||
|
m_ses.m_alerts.post_alert(metadata_received_alert(
|
||||||
|
get_handle()));
|
||||||
|
}
|
||||||
|
|
||||||
|
set_state(torrent_status::downloading);
|
||||||
|
|
||||||
|
m_override_resume_data = true;
|
||||||
|
init();
|
||||||
|
announce_with_tracker();
|
||||||
|
}
|
||||||
|
|
||||||
void torrent::start()
|
void torrent::start()
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_ses.is_network_thread());
|
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||||
|
@ -472,10 +566,15 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_torrent_file->is_valid() && !m_url.empty())
|
||||||
|
{
|
||||||
|
// we need to download the .torrent file from m_url
|
||||||
|
start_download_url();
|
||||||
|
}
|
||||||
|
else if (m_torrent_file->is_valid())
|
||||||
|
{
|
||||||
// we need to start announcing since we don't have any
|
// we need to start announcing since we don't have any
|
||||||
// metadata. To receive peers to ask for it.
|
// metadata. To receive peers to ask for it.
|
||||||
if (m_torrent_file->is_valid())
|
|
||||||
{
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -485,6 +584,18 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent::start_download_url()
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(!m_url.empty());
|
||||||
|
TORRENT_ASSERT(!m_torrent_file->is_valid());
|
||||||
|
boost::shared_ptr<http_connection> conn(
|
||||||
|
new http_connection(m_ses.m_io_service, m_ses.m_half_open
|
||||||
|
, boost::bind(&torrent::on_torrent_download, shared_from_this()
|
||||||
|
, _1, _2, _3, _4), false));
|
||||||
|
conn->get(m_url);
|
||||||
|
set_state(torrent_status::downloading_metadata);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
bool torrent::should_announce_dht() const
|
bool torrent::should_announce_dht() const
|
||||||
{
|
{
|
||||||
|
@ -920,7 +1031,6 @@ namespace libtorrent
|
||||||
// ans also in the case of share mode, we need to update the priorities
|
// ans also in the case of share mode, we need to update the priorities
|
||||||
update_piece_priorities();
|
update_piece_priorities();
|
||||||
|
|
||||||
|
|
||||||
std::vector<web_seed_entry> const& web_seeds = m_torrent_file->web_seeds();
|
std::vector<web_seed_entry> const& web_seeds = m_torrent_file->web_seeds();
|
||||||
m_web_seeds.insert(m_web_seeds.end(), web_seeds.begin(), web_seeds.end());
|
m_web_seeds.insert(m_web_seeds.end(), web_seeds.begin(), web_seeds.end());
|
||||||
|
|
||||||
|
@ -5518,10 +5628,18 @@ namespace libtorrent
|
||||||
m_ses.m_auto_manage_time_scaler = 2;
|
m_ses.m_auto_manage_time_scaler = 2;
|
||||||
m_error = error_code();
|
m_error = error_code();
|
||||||
m_error_file.clear();
|
m_error_file.clear();
|
||||||
|
|
||||||
|
// if we haven't downloaded the metadata from m_url, try again
|
||||||
|
if (!m_url.empty() && !m_torrent_file->is_valid())
|
||||||
|
{
|
||||||
|
start_download_url();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// if the error happened during initialization, try again now
|
// if the error happened during initialization, try again now
|
||||||
if (!m_storage) init();
|
if (!m_storage) init();
|
||||||
if (!checking_files && should_check_files())
|
if (!checking_files && should_check_files())
|
||||||
queue_torrent_check();
|
queue_torrent_check();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::set_error(error_code const& ec, std::string const& error_file)
|
void torrent::set_error(error_code const& ec, std::string const& error_file)
|
||||||
|
|
|
@ -162,6 +162,7 @@ namespace libtorrent { namespace
|
||||||
{
|
{
|
||||||
m_metadata_progress += received;
|
m_metadata_progress += received;
|
||||||
m_metadata_size = total_size;
|
m_metadata_size = total_size;
|
||||||
|
m_torrent.set_progress_ppm(boost::int64_t(m_metadata_progress) * 1000000 / m_metadata_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_piece_pass(int)
|
void on_piece_pass(int)
|
||||||
|
|
Loading…
Reference in New Issue