support multiple trackers in magnet links

This commit is contained in:
Arvid Norberg 2010-03-01 06:46:57 +00:00
parent d15fd0c6d3
commit 77c0fa5872
5 changed files with 53 additions and 5 deletions

View File

@ -19,6 +19,7 @@
0.15 release
* added support for multiple trackers in magnet links
* added support for explicitly flushing the disk cache
* added torrent priority to affect bandwidth allocation for its peers
* reduced the number of floating point operations (to better support

View File

@ -72,7 +72,7 @@ namespace libtorrent
TORRENT_EXPORT std::string base32decode(std::string const& s);
TORRENT_EXPORT std::string url_has_argument(
std::string const& url, std::string argument);
std::string const& url, std::string argument, int* out_pos = 0);
// replaces \ with /
TORRENT_EXPORT void convert_path_to_posix(std::string& path);

View File

@ -473,7 +473,7 @@ namespace libtorrent
}
std::string url_has_argument(
std::string const& url, std::string argument)
std::string const& url, std::string argument, int* out_pos)
{
size_t i = url.find('?');
if (i == std::string::npos) return std::string();
@ -484,12 +484,14 @@ namespace libtorrent
if (url.compare(i, argument.size(), argument) == 0)
{
size_t pos = i + argument.size();
if (out_pos) *out_pos = pos;
return url.substr(pos, url.find('&', pos) - pos);
}
argument.insert(0, "&");
i = url.find(argument, i);
if (i == std::string::npos) return std::string();
size_t pos = i + argument.size();
if (out_pos) *out_pos = pos;
return url.substr(pos, url.find('&', pos) - pos);
}

View File

@ -146,7 +146,8 @@ 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);
std::string tracker_string = url_has_argument(uri, "tr");
int 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);
std::string btih = url_has_argument(uri, "xt");
@ -169,7 +170,20 @@ namespace libtorrent
if (!tracker.empty()) p.tracker_url = tracker.c_str();
p.info_hash = info_hash;
if (!name.empty()) p.name = name.c_str();
return ses.add_torrent(p, ec);
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;
announce_entry ae(uri.substr(pos, uri.find('&', pos) - pos));
ae.tier = tier++;
ret.add_tracker(ae);
}
return ret;
}
}

View File

@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/magnet_uri.hpp"
#include "libtorrent/parse_url.hpp"
#include "libtorrent/http_tracker_connection.hpp"
#include "libtorrent/buffer.hpp"
@ -419,7 +420,37 @@ int test_main()
*/
entry session_state;
s->save_state(session_state);
// test magnet link parsing
add_torrent_params p;
p.save_path = ".";
error_code ec;
const char* magnet_uri = "magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"&tr=http://1&tr=http://2&tr=http://3&dn=foo";
torrent_handle t = add_magnet_uri(*s, magnet_uri, p, ec);
TEST_CHECK(!ec);
if (ec) fprintf(stderr, "%s\n", ec.message().c_str());
std::vector<announce_entry> trackers = t.trackers();
TEST_EQUAL(trackers.size(), 3);
if (trackers.size() > 0)
{
TEST_EQUAL(trackers[0].url, "http://1");
fprintf(stderr, "1: %s\n", trackers[0].url.c_str());
}
if (trackers.size() > 1)
{
TEST_EQUAL(trackers[1].url, "http://2");
fprintf(stderr, "2: %s\n", trackers[1].url.c_str());
}
if (trackers.size() > 2)
{
TEST_EQUAL(trackers[2].url, "http://3");
fprintf(stderr, "3: %s\n", trackers[2].url.c_str());
}
TEST_EQUAL(to_hex(t.info_hash().to_string()), "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd");
delete s;
s = new session(fingerprint("LT",0,0,0,0), 0);