forked from premiere/premiere-libtorrent
improve magnet link support. in RSS feeds for instance. Parsing of magnet links was factored out and moved to the proper place, in session_impl::add_torrent
This commit is contained in:
parent
9bd40e950b
commit
341967dab7
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "Python.h"
|
||||
#include <cctype>
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/settings.hpp> // for bencode_map_entry
|
||||
|
@ -154,12 +156,6 @@ namespace
|
|||
if (params.has_key("ti"))
|
||||
p.ti = extract<intrusive_ptr<torrent_info> >(params["ti"]);
|
||||
|
||||
std::string url;
|
||||
if (params.has_key("tracker_url"))
|
||||
{
|
||||
string_storage.push_back(extract<std::string>(params["tracker_url"]));
|
||||
p.tracker_url = string_storage.back().c_str();
|
||||
}
|
||||
if (params.has_key("info_hash"))
|
||||
p.info_hash = extract<sha1_hash>(params["info_hash"]);
|
||||
if (params.has_key("name"))
|
||||
|
@ -179,7 +175,28 @@ namespace
|
|||
if (params.has_key("storage_mode"))
|
||||
p.storage_mode = extract<storage_mode_t>(params["storage_mode"]);
|
||||
|
||||
if (params.has_key("tracker_url"))
|
||||
{
|
||||
list l = extract<list>(params["trackers"]);
|
||||
int n = boost::python::len(l);
|
||||
for(int i = 0; i < n; i++)
|
||||
p.trackers.push_back(extract<std::string>(l[i]));
|
||||
}
|
||||
|
||||
if (params.has_key("dht_nodes"))
|
||||
{
|
||||
list l = extract<list>(params["dht_nodes"]);
|
||||
int n = boost::python::len(l);
|
||||
for(int i = 0; i < n; i++)
|
||||
p.dht_nodes.push_back(extract<std::pair<std::string, int> >(l[i]));
|
||||
}
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
std::string url;
|
||||
if (params.has_key("tracker_url"))
|
||||
{
|
||||
string_storage.push_back(extract<std::string>(params["tracker_url"]));
|
||||
p.tracker_url = string_storage.back().c_str();
|
||||
}
|
||||
if (params.has_key("seed_mode"))
|
||||
p.seed_mode = params["seed_mode"];
|
||||
if (params.has_key("upload_mode"))
|
||||
|
|
|
@ -399,10 +399,14 @@ async_add_torrent() add_torrent()
|
|||
|
||||
int version;
|
||||
boost::intrusive_ptr<torrent_info> ti;
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
char const* tracker_url;
|
||||
#endif
|
||||
std::vector<std::string> trackers;
|
||||
std::vector<std::pair<std::string, int> > dht_nodes;
|
||||
sha1_hash info_hash;
|
||||
char const* name;
|
||||
fs::path save_path;
|
||||
std::string name;
|
||||
std::string save_path;
|
||||
std::vector<char>* resume_data;
|
||||
storage_mode_t storage_mode;
|
||||
storage_constructor_type storage;
|
||||
|
@ -438,18 +442,22 @@ torrent file), the ``info_hash`` (the info hash of the torrent) or the ``url``
|
|||
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
|
||||
be built with extensions enabled (``TORRENT_DISABLE_EXTENSIONS`` must not be
|
||||
defined). It also takes an optional ``name`` argument. This may be 0 in case no
|
||||
name should be assigned to the torrent. In case it's not 0, the name is used for
|
||||
defined). It also takes an optional ``name`` argument. This may be left empty in case no
|
||||
name should be assigned to the torrent. In case it's not, the name is used for
|
||||
the torrent as long as it doesn't have metadata. See ``torrent_handle::name``.
|
||||
|
||||
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
|
||||
torrent.
|
||||
``trackers`` (or the deprecated ``tracker_url``) can specify tracker urls that
|
||||
for the 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.
|
||||
will indicate what went wrong. The ``url`` may refer to a magnet link or a regular
|
||||
http URL.
|
||||
|
||||
``dht_nodes`` is a list of hostname and port pairs, representing DHT nodes to be
|
||||
added to the session (if DHT is enabled). The hostname may be an IP address.
|
||||
|
||||
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
|
||||
|
@ -6031,6 +6039,8 @@ it will throw libtorrent_exception_.
|
|||
add_magnet_uri()
|
||||
----------------
|
||||
|
||||
*deprecated*
|
||||
|
||||
::
|
||||
|
||||
torrent_handle add_magnet_uri(session& ses, std::string const& uri
|
||||
|
@ -6052,6 +6062,16 @@ link through ``add_torrent_params::url`` argument to ``session::add_torrent()``.
|
|||
|
||||
For more information about magnet links, see `magnet links`_.
|
||||
|
||||
parse_magnet_uri()
|
||||
------------------
|
||||
|
||||
::
|
||||
|
||||
void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec);
|
||||
|
||||
This function parses out information from the magnet link and populates the
|
||||
``add_torrent_params`` object.
|
||||
|
||||
make_magnet_uri()
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -49,8 +49,9 @@ namespace libtorrent
|
|||
{
|
||||
add_torrent_params(storage_constructor_type sc = default_storage_constructor)
|
||||
: version(LIBTORRENT_VERSION_NUM)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
, tracker_url(0)
|
||||
, name(0)
|
||||
#endif
|
||||
, resume_data(0)
|
||||
, storage_mode(storage_mode_sparse)
|
||||
, storage(sc)
|
||||
|
@ -114,9 +115,13 @@ namespace libtorrent
|
|||
// libtorrent version. Used for forward binary compatibility
|
||||
int version;
|
||||
boost::intrusive_ptr<torrent_info> ti;
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
char const* tracker_url;
|
||||
#endif
|
||||
std::vector<std::string> trackers;
|
||||
std::vector<std::pair<std::string, int> > dht_nodes;
|
||||
sha1_hash info_hash;
|
||||
char const* name;
|
||||
std::string name;
|
||||
std::string save_path;
|
||||
std::vector<char>* resume_data;
|
||||
storage_mode_t storage_mode;
|
||||
|
|
|
@ -46,23 +46,31 @@ namespace libtorrent
|
|||
std::string TORRENT_EXPORT make_magnet_uri(torrent_handle const& handle);
|
||||
std::string TORRENT_EXPORT make_magnet_uri(torrent_info const& info);
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
// deprecated in 0.14
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri
|
||||
, std::string const& save_path
|
||||
, storage_mode_t storage_mode = storage_mode_sparse
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor
|
||||
, void* userdata = 0) TORRENT_DEPRECATED;
|
||||
|
||||
// deprecated in 0.16. Instead, pass in the magnet link as add_torrent_params::url
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri
|
||||
, add_torrent_params p) TORRENT_DEPRECATED;
|
||||
#endif
|
||||
|
||||
// deprecated in 0.16. Instead, pass in the magnet link as add_torrent_params::url
|
||||
TORRENT_DEPRECATED_PREFIX
|
||||
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri
|
||||
, add_torrent_params p);
|
||||
, add_torrent_params p, error_code& ec) TORRENT_DEPRECATED;
|
||||
|
||||
#endif
|
||||
|
||||
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri
|
||||
, add_torrent_params p, error_code& ec);
|
||||
TORRENT_EXPORT void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -137,8 +137,16 @@ namespace libtorrent
|
|||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
torrent_handle add_magnet_uri(session& ses, std::string const& uri
|
||||
, add_torrent_params p, error_code& ec)
|
||||
{
|
||||
parse_magnet_uri(uri, p, ec);
|
||||
if (ec) return torrent_handle();
|
||||
return ses.add_torrent(p, ec);
|
||||
}
|
||||
|
||||
void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec)
|
||||
{
|
||||
std::string name;
|
||||
std::string tracker;
|
||||
|
@ -146,21 +154,32 @@ namespace libtorrent
|
|||
error_code e;
|
||||
std::string display_name = url_has_argument(uri, "dn");
|
||||
if (!display_name.empty()) name = unescape_string(display_name.c_str(), e);
|
||||
|
||||
// parse trackers out of the magnet link
|
||||
std::string::size_type pos = std::string::npos;
|
||||
std::string tracker_string = url_has_argument(uri, "tr", &pos);
|
||||
if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), e);
|
||||
do
|
||||
{
|
||||
pos = uri.find("&tr=", pos);
|
||||
if (pos == std::string::npos) break;
|
||||
pos += 4;
|
||||
error_code e;
|
||||
std::string url = unescape_string(uri.substr(pos, uri.find('&', pos) - pos), e);
|
||||
if (e) continue;
|
||||
p.trackers.push_back(url);
|
||||
}
|
||||
while (pos != std::string::npos);
|
||||
|
||||
std::string btih = url_has_argument(uri, "xt");
|
||||
if (btih.empty())
|
||||
{
|
||||
ec = errors::missing_info_hash_in_uri;
|
||||
return torrent_handle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (btih.compare(0, 9, "urn:btih:") != 0)
|
||||
{
|
||||
ec = errors::missing_info_hash_in_uri;
|
||||
return torrent_handle();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
@ -173,7 +192,7 @@ namespace libtorrent
|
|||
{
|
||||
int port = atoi(node.c_str()+divider+1);
|
||||
if (port != 0)
|
||||
ses.add_dht_node(std::make_pair(node.substr(0, divider), port));
|
||||
p.dht_nodes.push_back(std::make_pair(node.substr(0, divider), port));
|
||||
}
|
||||
|
||||
node_pos = uri.find("&dht=", node_pos);
|
||||
|
@ -187,26 +206,8 @@ namespace libtorrent
|
|||
if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
|
||||
else info_hash.assign(base32decode(btih.substr(9)));
|
||||
|
||||
if (!tracker.empty()) p.tracker_url = tracker.c_str();
|
||||
p.info_hash = info_hash;
|
||||
if (!name.empty()) p.name = name.c_str();
|
||||
torrent_handle ret = ses.add_torrent(p, ec);
|
||||
|
||||
int tier = 1;
|
||||
// there might be more trackers in the url
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
pos = uri.find("&tr=", pos);
|
||||
if (pos == std::string::npos) break;
|
||||
pos += 4;
|
||||
error_code e;
|
||||
std::string url = unescape_string(uri.substr(pos, uri.find('&', pos) - pos), e);
|
||||
if (e) continue;
|
||||
announce_entry ae(url);
|
||||
ae.tier = tier++;
|
||||
ret.add_tracker(ae);
|
||||
}
|
||||
return ret;
|
||||
if (!name.empty()) p.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -391,7 +391,6 @@ void feed::on_feed(error_code const& ec
|
|||
p.name = i->title.c_str();
|
||||
|
||||
error_code e;
|
||||
// #error session_impl::add_torrent doesn't support magnet links via url
|
||||
torrent_handle h = m_ses.add_torrent(p, e);
|
||||
m_ses.m_alerts.post_alert(add_torrent_alert(h, p, e));
|
||||
m_added.insert(make_pair(i->url, now));
|
||||
|
|
|
@ -591,13 +591,6 @@ namespace libtorrent
|
|||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
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;
|
||||
TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, boost::ref(ec));
|
||||
if (ec) throw libtorrent_exception(ec);
|
||||
|
@ -608,13 +601,6 @@ namespace libtorrent
|
|||
torrent_handle session::add_torrent(add_torrent_params const& params, error_code& ec)
|
||||
{
|
||||
ec.clear();
|
||||
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, boost::ref(ec));
|
||||
return r;
|
||||
}
|
||||
|
@ -623,8 +609,6 @@ namespace libtorrent
|
|||
{
|
||||
add_torrent_params* p = new add_torrent_params(params);
|
||||
if (params.resume_data) p->resume_data = new std::vector<char>(*params.resume_data);
|
||||
if (params.tracker_url) p->tracker_url = strdup(params.tracker_url);
|
||||
if (params.name) p->name = strdup(params.name);
|
||||
TORRENT_ASYNC_CALL1(async_add_torrent, p);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/build_config.hpp"
|
||||
#include "libtorrent/extensions.hpp"
|
||||
#include "libtorrent/random.hpp"
|
||||
#include "libtorrent/magnet_uri.hpp"
|
||||
|
||||
#if defined TORRENT_STATS && defined __MACH__
|
||||
#include <mach/task.h>
|
||||
|
@ -4724,26 +4725,42 @@ namespace aux {
|
|||
torrent_handle handle = add_torrent(*params, ec);
|
||||
m_alerts.post_alert(add_torrent_alert(handle, *params, ec));
|
||||
delete params->resume_data;
|
||||
free((char*)params->tracker_url);
|
||||
free((char*)params->name);
|
||||
delete params;
|
||||
}
|
||||
|
||||
torrent_handle session_impl::add_torrent(add_torrent_params const& params
|
||||
torrent_handle session_impl::add_torrent(add_torrent_params const& p
|
||||
, error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(!params.save_path.empty());
|
||||
TORRENT_ASSERT(!p.save_path.empty());
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
params.update_flags();
|
||||
p.update_flags();
|
||||
#endif
|
||||
|
||||
add_torrent_params params = p;
|
||||
if (string_begins_no_case("magnet:", params.url.c_str()))
|
||||
{
|
||||
parse_magnet_uri(params.url, params, ec);
|
||||
if (ec) return torrent_handle();
|
||||
params.url.clear();
|
||||
}
|
||||
|
||||
if (params.ti && params.ti->is_valid() && params.ti->num_files() == 0)
|
||||
{
|
||||
ec = errors::no_files_in_torrent;
|
||||
return torrent_handle();
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// add p.dht_nodes to the DHT, if enabled
|
||||
if (m_dht && !p.dht_nodes.empty())
|
||||
{
|
||||
for (std::vector<std::pair<std::string, int> >::const_iterator i = p.dht_nodes.begin()
|
||||
, end(p.dht_nodes.end()); i != end; ++i)
|
||||
m_dht->add_node(*i);
|
||||
}
|
||||
#endif
|
||||
|
||||
// INVARIANT_CHECK;
|
||||
|
||||
if (is_aborted())
|
||||
|
|
|
@ -520,7 +520,7 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
if (p.name) m_name.reset(new std::string(p.name));
|
||||
if (!p.name.empty()) m_name.reset(new std::string(p.name));
|
||||
}
|
||||
|
||||
if (!m_url.empty() && m_uuid.empty()) m_uuid = m_url;
|
||||
|
@ -554,6 +554,7 @@ namespace libtorrent
|
|||
|
||||
if (!m_name && !m_url.empty()) m_name.reset(new std::string(m_url));
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
if (p.tracker_url && std::strlen(p.tracker_url) > 0)
|
||||
{
|
||||
m_trackers.push_back(announce_entry(p.tracker_url));
|
||||
|
@ -561,6 +562,16 @@ namespace libtorrent
|
|||
m_trackers.back().source = announce_entry::source_magnet_link;
|
||||
m_torrent_file->add_tracker(p.tracker_url);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (std::vector<std::string>::const_iterator i = p.trackers.begin()
|
||||
, end(p.trackers.end()); i != end; ++i)
|
||||
{
|
||||
m_trackers.push_back(announce_entry(*i));
|
||||
m_trackers.back().fail_limit = 0;
|
||||
m_trackers.back().source = announce_entry::source_magnet_link;
|
||||
m_torrent_file->add_tracker(*i);
|
||||
}
|
||||
|
||||
if (settings().prefer_udp_trackers)
|
||||
prioritize_udp_trackers();
|
||||
|
|
|
@ -1132,7 +1132,7 @@ int test_main()
|
|||
TEST_CHECK(f.open("test_file", file::read_write, ec));
|
||||
#endif
|
||||
TEST_CHECK(!ec);
|
||||
file::iovec_t b = {"test", 4};
|
||||
file::iovec_t b = {(void*)"test", 4};
|
||||
TEST_CHECK(f.writev(0, &b, 1, ec) == 4);
|
||||
TEST_CHECK(!ec);
|
||||
char test_buf[5] = {0};
|
||||
|
|
Loading…
Reference in New Issue