36
36
#include "libtorrent/escape_string.hpp"
40
#include <boost/lexical_cast.hpp>
42
40
namespace libtorrent
44
42
std::string make_magnet_uri(torrent_handle const& handle)
46
std::stringstream ret;
47
if (!handle.is_valid()) return ret.str();
44
if (!handle.is_valid()) return "";
47
sha1_hash const& ih = handle.info_hash();
48
int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
49
, base32encode(std::string((char const*)&ih[0], 20)).c_str());
49
51
std::string name = handle.name();
51
ret << "magnet:?xt=urn:btih:" << base32encode(
52
std::string((char*)handle.info_hash().begin(), 20));
54
ret << "&dn=" << escape_string(name.c_str(), name.length());
54
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
55
, escape_string(name.c_str(), name.length()).c_str());
57
char const* tracker = 0;
55
58
torrent_status st = handle.status();
56
59
if (!st.current_tracker.empty())
58
ret << "&tr=" << escape_string(st.current_tracker.c_str()
59
, st.current_tracker.length());
61
tracker = st.current_tracker.c_str();
63
65
std::vector<announce_entry> const& tr = handle.trackers();
66
ret << "&tr=" << escape_string(tr[0].url.c_str()
67
, tr[0].url.length());
66
if (!tr.empty()) tracker = tr[0].url.c_str();
69
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
70
, escape_string(tracker, strlen(tracker)).c_str());
73
75
std::string make_magnet_uri(torrent_info const& info)
75
std::stringstream ret;
76
if (!info.is_valid()) return ret.str();
78
std::string name = info.name();
80
ret << "magnet:?xt=urn:btih:" << base32encode(
81
std::string((char*)info.info_hash().begin(), 20));
78
sha1_hash const& ih = info.info_hash();
79
int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
80
, base32encode(std::string((char*)&ih[0], 20)).c_str());
82
std::string const& name = info.name();
83
ret << "&dn=" << escape_string(name.c_str(), name.length());
85
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
86
, escape_string(name.c_str(), name.length()).c_str());
84
88
std::vector<announce_entry> const& tr = info.trackers();
87
ret << "&tr=" << escape_string(tr[0].url.c_str()
88
, tr[0].url.length());
91
num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
92
, escape_string(tr[0].url.c_str(), tr[0].url.length()).c_str());
98
#ifndef BOOST_NO_EXCEPTIONS
93
99
#ifndef TORRENT_NO_DEPRECATE
94
100
torrent_handle add_magnet_uri(session& ses, std::string const& uri
95
101
, fs::path const& save_path
101
107
std::string name;
102
108
std::string tracker;
104
111
boost::optional<std::string> display_name = url_has_argument(uri, "dn");
105
if (display_name) name = unescape_string(display_name->c_str());
112
if (display_name) name = unescape_string(display_name->c_str(), ec);
106
113
boost::optional<std::string> tracker_string = url_has_argument(uri, "tr");
107
if (tracker_string) tracker = unescape_string(tracker_string->c_str());
114
if (tracker_string) tracker = unescape_string(tracker_string->c_str(), ec);
109
116
boost::optional<std::string> btih = url_has_argument(uri, "xt");
110
117
if (!btih) return torrent_handle();
124
131
torrent_handle add_magnet_uri(session& ses, std::string const& uri
125
132
, add_torrent_params p)
135
torrent_handle ret = add_magnet_uri(ses, uri, p, ec);
136
if (ec) throw libtorrent_exception(ec);
140
torrent_handle add_magnet_uri(session& ses, std::string const& uri
141
, add_torrent_params p, error_code& ec)
127
143
std::string name;
128
144
std::string tracker;
130
147
boost::optional<std::string> display_name = url_has_argument(uri, "dn");
131
if (display_name) name = unescape_string(display_name->c_str());
132
boost::optional<std::string> tracker_string = url_has_argument(uri, "tr");
133
if (tracker_string) tracker = unescape_string(tracker_string->c_str());
148
if (display_name) name = unescape_string(display_name->c_str(), e);
149
int pos = std::string::npos;
150
boost::optional<std::string> tracker_string = url_has_argument(uri, "tr", &pos);
151
if (tracker_string) tracker = unescape_string(tracker_string->c_str(), e);
135
153
boost::optional<std::string> btih = url_has_argument(uri, "xt");
136
if (!btih) return torrent_handle();
156
ec = errors::missing_info_hash_in_uri;
157
return torrent_handle();
138
if (btih->compare(0, 9, "urn:btih:") != 0) return torrent_handle();
160
if (btih->compare(0, 9, "urn:btih:") != 0)
162
ec = errors::missing_info_hash_in_uri;
163
return torrent_handle();
140
166
sha1_hash info_hash;
141
if (btih->size() == 40 + 9) info_hash = boost::lexical_cast<sha1_hash>(btih->substr(9));
167
if (btih->size() == 40 + 9) from_hex(&(*btih)[9], 40, (char*)&info_hash[0]);
142
168
else info_hash.assign(base32decode(btih->substr(9)));
144
170
if (!tracker.empty()) p.tracker_url = tracker.c_str();
145
171
p.info_hash = info_hash;
146
172
if (!name.empty()) p.name = name.c_str();
147
return ses.add_torrent(p);
173
torrent_handle ret = ses.add_torrent(p, ec);
176
// there might be more trackers in the url
177
while (pos != std::string::npos)
179
pos = uri.find("&tr=", pos);
180
if (pos == std::string::npos) break;
182
announce_entry ae(uri.substr(pos, uri.find('&', pos) - pos));