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:
Arvid Norberg
2012-03-08 09:54:44 +00:00
parent 9bd40e950b
commit 341967dab7
10 changed files with 129 additions and 67 deletions

View File

@@ -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;
}
}

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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())

View File

@@ -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();