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:
@@ -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();
|
||||
|
Reference in New Issue
Block a user