mirror of https://github.com/aria2/aria2
2009-11-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added parseMagnetLink(). Hex encoded info hash is supported. Base32 encoded info hash is not supported yet. * src/bittorrent_helper.cc * src/bittorrent_helper.h * test/BittorrentHelperTest.ccpull/1/head
parent
e0d9798b94
commit
66e6191d10
|
@ -1,3 +1,11 @@
|
||||||
|
2009-11-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Added parseMagnetLink(). Hex encoded info hash is supported.
|
||||||
|
Base32 encoded info hash is not supported yet.
|
||||||
|
* src/bittorrent_helper.cc
|
||||||
|
* src/bittorrent_helper.h
|
||||||
|
* test/BittorrentHelperTest.cc
|
||||||
|
|
||||||
2009-11-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2009-11-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Added FromHex()
|
Added FromHex()
|
||||||
|
|
|
@ -847,6 +847,64 @@ void generateRandomKey(unsigned char* key)
|
||||||
MessageDigestHelper::digest(key, 20, MessageDigestContext::SHA1, bytes, sizeof(bytes));
|
MessageDigestHelper::digest(key, 20, MessageDigestContext::SHA1, bytes, sizeof(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parseMagnetLink(const std::string& magnetLink,
|
||||||
|
const SharedHandle<DownloadContext>& dctx)
|
||||||
|
{
|
||||||
|
// magnet:?xt=urn:btih:<info-hash>&dn=<name>&tr=<tracker-url>
|
||||||
|
// <info-hash> comes in 2 flavors: 40bytes hexadecimal ascii info hash,
|
||||||
|
// or 32bytes Base32 encoded info hash.
|
||||||
|
if(!util::startsWith(magnetLink, "magnet:?")) {
|
||||||
|
throw DL_ABORT_EX("Invalid magnet link.");
|
||||||
|
}
|
||||||
|
std::deque<std::string> queries;
|
||||||
|
util::split(std::string(magnetLink.begin()+8, magnetLink.end()),
|
||||||
|
std::back_inserter(queries), "&");
|
||||||
|
std::string infoHash;
|
||||||
|
std::string name;
|
||||||
|
BDE announceList = BDE::list();
|
||||||
|
announceList << BDE::list();
|
||||||
|
for(std::deque<std::string>::const_iterator i = queries.begin();
|
||||||
|
i != queries.end(); ++i) {
|
||||||
|
std::pair<std::string, std::string> kv;
|
||||||
|
util::split(kv, *i, '=');
|
||||||
|
if(kv.first == "xt") {
|
||||||
|
if(!util::startsWith(kv.second, "urn:btih:")) {
|
||||||
|
throw DL_ABORT_EX("Bad BitTorrent Magnet Link.");
|
||||||
|
}
|
||||||
|
if(infoHash.empty()) {
|
||||||
|
infoHash = kv.second.substr(9);
|
||||||
|
} else {
|
||||||
|
throw DL_ABORT_EX("More than 1 info hash in magnet link.");
|
||||||
|
}
|
||||||
|
} else if(kv.first == "dn") {
|
||||||
|
name = kv.second;
|
||||||
|
} else if(kv.first == "tr") {
|
||||||
|
announceList[0] << kv.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(infoHash.size() == 32) {
|
||||||
|
// Not yet implemented
|
||||||
|
abort();
|
||||||
|
} else if(infoHash.size() == 40) {
|
||||||
|
std::string rawhash = util::fromHex(infoHash);
|
||||||
|
if(rawhash.empty()) {
|
||||||
|
throw DL_ABORT_EX("Invalid info hash");
|
||||||
|
}
|
||||||
|
infoHash = rawhash;
|
||||||
|
} else {
|
||||||
|
throw DL_ABORT_EX("Invalid magnet link.");
|
||||||
|
}
|
||||||
|
if(name.empty()) {
|
||||||
|
name = util::toHex(infoHash);
|
||||||
|
}
|
||||||
|
BDE attrs = BDE::dict();
|
||||||
|
attrs[INFO_HASH] = infoHash;
|
||||||
|
attrs[NAME] = name;
|
||||||
|
attrs[ANNOUNCE_LIST] = announceList;
|
||||||
|
|
||||||
|
dctx->setAttribute(BITTORRENT, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace bittorrent
|
} // namespace bittorrent
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -119,6 +119,11 @@ void loadFromMemory(const std::string& context,
|
||||||
const std::string& defaultName,
|
const std::string& defaultName,
|
||||||
const std::string& overrideName = "");
|
const std::string& overrideName = "");
|
||||||
|
|
||||||
|
// Parses BitTorrent magnet link.
|
||||||
|
// magnet:?xt=urn:btih:<info-hash>&dn=<name>&tr=<tracker-url>
|
||||||
|
void parseMagnetLink(const std::string& magnetLink,
|
||||||
|
const SharedHandle<DownloadContext>& ctx);
|
||||||
|
|
||||||
// Generates Peer ID. BitTorrent specification says Peer ID is 20-byte
|
// Generates Peer ID. BitTorrent specification says Peer ID is 20-byte
|
||||||
// length. This function uses peerIdPrefix as a Peer ID and it is
|
// length. This function uses peerIdPrefix as a Peer ID and it is
|
||||||
// less than 20bytes, random bytes are generated and appened to it. If
|
// less than 20bytes, random bytes are generated and appened to it. If
|
||||||
|
|
|
@ -58,6 +58,7 @@ class BittorrentHelperTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testCreatecompact);
|
CPPUNIT_TEST(testCreatecompact);
|
||||||
CPPUNIT_TEST(testCheckBitfield);
|
CPPUNIT_TEST(testCheckBitfield);
|
||||||
CPPUNIT_TEST(testMetadata);
|
CPPUNIT_TEST(testMetadata);
|
||||||
|
CPPUNIT_TEST(testParseMagnetLink);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
public:
|
public:
|
||||||
void setUp() {
|
void setUp() {
|
||||||
|
@ -97,6 +98,7 @@ public:
|
||||||
void testCreatecompact();
|
void testCreatecompact();
|
||||||
void testCheckBitfield();
|
void testCheckBitfield();
|
||||||
void testMetadata();
|
void testMetadata();
|
||||||
|
void testParseMagnetLink();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -695,6 +697,24 @@ void BittorrentHelperTest::testMetadata() {
|
||||||
(size_t)attrs[bittorrent::METADATA_SIZE].i());
|
(size_t)attrs[bittorrent::METADATA_SIZE].i());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BittorrentHelperTest::testParseMagnetLink()
|
||||||
|
{
|
||||||
|
SharedHandle<DownloadContext> dctx(new DownloadContext());
|
||||||
|
std::string magnet =
|
||||||
|
"magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2";
|
||||||
|
bittorrent::parseMagnetLink(magnet, dctx);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
|
||||||
|
bittorrent::getInfoHashString(dctx));
|
||||||
|
BDE attrs = dctx->getAttribute(bittorrent::BITTORRENT);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("aria2"), attrs[bittorrent::NAME].s());
|
||||||
|
|
||||||
|
magnet = "magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c";
|
||||||
|
bittorrent::parseMagnetLink(magnet, dctx);
|
||||||
|
attrs = dctx->getAttribute(bittorrent::BITTORRENT);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
|
||||||
|
attrs[bittorrent::NAME].s());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace bittorrent
|
} // namespace bittorrent
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue