mirror of https://github.com/aria2/aria2
2009-11-24 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten Magnet URI parser. * src/Makefile.am * src/ProtocolDetector.cc * src/bittorrent_helper.cc * src/bittorrent_helper.h * src/download_helper.cc * src/magnet.cc * src/magnet.h * test/BittorrentHelperTest.cc * test/MagnetTest.cc * test/Makefile.am * test/ProtocolDetectorTest.ccpull/1/head
parent
d2cefd8613
commit
512be58217
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2009-11-24 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Rewritten Magnet URI parser.
|
||||
* src/Makefile.am
|
||||
* src/ProtocolDetector.cc
|
||||
* src/bittorrent_helper.cc
|
||||
* src/bittorrent_helper.h
|
||||
* src/download_helper.cc
|
||||
* src/magnet.cc
|
||||
* src/magnet.h
|
||||
* test/BittorrentHelperTest.cc
|
||||
* test/MagnetTest.cc
|
||||
* test/Makefile.am
|
||||
* test/ProtocolDetectorTest.cc
|
||||
|
||||
2009-11-24 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Use hton64
|
||||
|
|
|
@ -355,6 +355,7 @@ SRCS += PeerAbstractCommand.cc PeerAbstractCommand.h\
|
|||
UTMetadataRequestTracker.cc UTMetadataRequestTracker.h\
|
||||
UTMetadataRequestFactory.cc UTMetadataRequestFactory.h\
|
||||
UTMetadataPostDownloadHandler.cc UTMetadataPostDownloadHandler.h\
|
||||
magnet.cc magnet.h\
|
||||
DHTNode.cc DHTNode.h\
|
||||
DHTBucket.cc DHTBucket.h\
|
||||
DHTRoutingTable.cc DHTRoutingTable.h\
|
||||
|
|
|
@ -153,6 +153,7 @@ bin_PROGRAMS = aria2c$(EXEEXT)
|
|||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestTracker.cc UTMetadataRequestTracker.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestFactory.cc UTMetadataRequestFactory.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataPostDownloadHandler.cc UTMetadataPostDownloadHandler.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ magnet.cc magnet.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTNode.cc DHTNode.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTBucket.cc DHTBucket.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTable.cc DHTRoutingTable.h\
|
||||
|
@ -508,12 +509,12 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
|||
UTMetadataDataExtensionMessage.h UTMetadataRequestTracker.cc \
|
||||
UTMetadataRequestTracker.h UTMetadataRequestFactory.cc \
|
||||
UTMetadataRequestFactory.h UTMetadataPostDownloadHandler.cc \
|
||||
UTMetadataPostDownloadHandler.h DHTNode.cc DHTNode.h \
|
||||
DHTBucket.cc DHTBucket.h DHTRoutingTable.cc DHTRoutingTable.h \
|
||||
DHTMessageEntry.cc DHTMessageEntry.h DHTMessageDispatcher.h \
|
||||
DHTMessageDispatcherImpl.cc DHTMessageDispatcherImpl.h \
|
||||
DHTMessageReceiver.cc DHTMessageReceiver.h \
|
||||
DHTMessageTracker.cc DHTMessageTracker.h \
|
||||
UTMetadataPostDownloadHandler.h magnet.cc magnet.h DHTNode.cc \
|
||||
DHTNode.h DHTBucket.cc DHTBucket.h DHTRoutingTable.cc \
|
||||
DHTRoutingTable.h DHTMessageEntry.cc DHTMessageEntry.h \
|
||||
DHTMessageDispatcher.h DHTMessageDispatcherImpl.cc \
|
||||
DHTMessageDispatcherImpl.h DHTMessageReceiver.cc \
|
||||
DHTMessageReceiver.h DHTMessageTracker.cc DHTMessageTracker.h \
|
||||
DHTMessageTrackerEntry.cc DHTMessageTrackerEntry.h \
|
||||
DHTMessage.cc DHTMessage.h DHTConnection.h \
|
||||
DHTConnectionImpl.cc DHTConnectionImpl.h DHTAbstractMessage.cc \
|
||||
|
@ -670,7 +671,8 @@ am__objects_6 =
|
|||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestTracker.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestFactory.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataPostDownloadHandler.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTNode.$(OBJEXT) DHTBucket.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ magnet.$(OBJEXT) DHTNode.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTBucket.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTable.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTMessageEntry.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTMessageDispatcherImpl.$(OBJEXT) \
|
||||
|
@ -1573,6 +1575,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_aton.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgen.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localtime_r.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/magnet.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messageDigest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/option_processing.Po@am__quote@
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
#include "Request.h"
|
||||
#include "File.h"
|
||||
#include "util.h"
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
# include "bittorrent_helper.h"
|
||||
#endif // ENABLE_BITTORRENT
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -70,8 +73,16 @@ bool ProtocolDetector::guessTorrentFile(const std::string& uri) const
|
|||
|
||||
bool ProtocolDetector::guessTorrentMagnet(const std::string& uri) const
|
||||
{
|
||||
return util::startsWith(uri, "magnet:?") &&
|
||||
uri.find("xt=urn:btih:") != std::string::npos;
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
try {
|
||||
bittorrent::parseMagnet(uri);
|
||||
return true;
|
||||
} catch(RecoverableException& e) {
|
||||
return false;
|
||||
}
|
||||
#else // !ENABLE_BITTORRENT
|
||||
return false;
|
||||
#endif // !ENABLE_BITTORRENT
|
||||
}
|
||||
|
||||
bool ProtocolDetector::guessMetalinkFile(const std::string& uri) const
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "BtConstants.h"
|
||||
#include "bitfield.h"
|
||||
#include "base32.h"
|
||||
#include "magnet.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -848,64 +849,58 @@ void generateRandomKey(unsigned char* key)
|
|||
MessageDigestHelper::digest(key, 20, MessageDigestContext::SHA1, bytes, sizeof(bytes));
|
||||
}
|
||||
|
||||
void parseMagnetLink(const std::string& magnetLink,
|
||||
const SharedHandle<DownloadContext>& dctx)
|
||||
BDE parseMagnet(const std::string& magnet)
|
||||
{
|
||||
// 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.");
|
||||
BDE result;
|
||||
BDE r = magnet::parse(magnet);
|
||||
if(r.isNone()) {
|
||||
throw DL_ABORT_EX("Bad BitTorrent Magnet URI.");
|
||||
}
|
||||
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(!r.containsKey("xt")) {
|
||||
throw DL_ABORT_EX("Missing xt parameter in Magnet URI.");
|
||||
}
|
||||
const BDE& xts = r["xt"];
|
||||
if(xts.size() == 0 || !util::startsWith(xts[0].s(), "urn:btih:")) {
|
||||
throw DL_ABORT_EX("Bad BitTorrent Magnet URI.");
|
||||
}
|
||||
std::string infoHash = xts[0].s().substr(9);
|
||||
if(infoHash.size() == 32) {
|
||||
std::string rawhash = base32::decode(infoHash);
|
||||
if(rawhash.size() != 20) {
|
||||
throw DL_ABORT_EX("Invalid info hash");
|
||||
throw DL_ABORT_EX("Invalid BitTorrent Info Hash.");
|
||||
}
|
||||
infoHash = rawhash;
|
||||
} else if(infoHash.size() == 40) {
|
||||
std::string rawhash = util::fromHex(infoHash);
|
||||
if(rawhash.empty()) {
|
||||
throw DL_ABORT_EX("Invalid info hash");
|
||||
throw DL_ABORT_EX("Invalid BitTorrent Info Hash.");
|
||||
}
|
||||
infoHash = rawhash;
|
||||
} else {
|
||||
throw DL_ABORT_EX("Invalid magnet link.");
|
||||
throw DL_ABORT_EX("Invalid BitTorrent Info Hash.");
|
||||
}
|
||||
if(name.empty()) {
|
||||
name = util::toHex(infoHash);
|
||||
BDE announceList = BDE::list();
|
||||
if(r.containsKey("tr")) {
|
||||
announceList << r["tr"];
|
||||
}
|
||||
std::string name;
|
||||
if(r.containsKey("dn") && r["dn"].size()) {
|
||||
name = r["dn"][0].s();
|
||||
} else {
|
||||
name = strconcat("[METADATA]", util::toHex(infoHash));
|
||||
}
|
||||
BDE attrs = BDE::dict();
|
||||
attrs[INFO_HASH] = infoHash;
|
||||
attrs[NAME] = name;
|
||||
attrs[ANNOUNCE_LIST] = announceList;
|
||||
result = attrs;
|
||||
return result;
|
||||
}
|
||||
|
||||
void loadMagnet
|
||||
(const std::string& magnet, const SharedHandle<DownloadContext>& dctx)
|
||||
{
|
||||
BDE attrs = parseMagnet(magnet);
|
||||
dctx->setAttribute(BITTORRENT, attrs);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,10 +119,21 @@ void loadFromMemory(const std::string& context,
|
|||
const std::string& defaultName,
|
||||
const std::string& overrideName = "");
|
||||
|
||||
// Parses BitTorrent magnet link.
|
||||
// Parses BitTorrent Magnet URI and returns BDE::dict() which includes
|
||||
// infoHash, name and announceList. If parsing operation failed, an
|
||||
// RecoverableException will be thrown. infoHash and name are string
|
||||
// and announceList is a list of list of announce URI.
|
||||
//
|
||||
// magnet:?xt=urn:btih:<info-hash>&dn=<name>&tr=<tracker-url>
|
||||
void parseMagnetLink(const std::string& magnetLink,
|
||||
const SharedHandle<DownloadContext>& ctx);
|
||||
// <info-hash> comes in 2 flavors: 40bytes hexadecimal ascii string,
|
||||
// or 32bytes Base32 encoded string.
|
||||
BDE parseMagnet(const std::string& magnet);
|
||||
|
||||
// Parses BitTorrent Magnet URI and set them in ctx as a
|
||||
// bittorrent::BITTORRENT attibute. If parsing operation failed, an
|
||||
// RecoverableException will be thrown.
|
||||
void loadMagnet
|
||||
(const std::string& magnet, const SharedHandle<DownloadContext>& ctx);
|
||||
|
||||
// Generates Peer ID. BitTorrent specification says Peer ID is 20-byte
|
||||
// length. This function uses peerIdPrefix as a Peer ID and it is
|
||||
|
|
|
@ -242,7 +242,7 @@ createBtMagnetRequestGroup(const std::string& magnetLink,
|
|||
dctx->markTotalLengthIsUnknown();
|
||||
rg->setFileAllocationEnabled(false);
|
||||
rg->setPreLocalFileCheckEnabled(false);
|
||||
bittorrent::parseMagnetLink(magnetLink, dctx);
|
||||
bittorrent::loadMagnet(magnetLink, dctx);
|
||||
dctx->getFirstFileEntry()->setPath
|
||||
(dctx->getAttribute(bittorrent::BITTORRENT)[bittorrent::NAME].s());
|
||||
rg->setDownloadContext(dctx);
|
||||
|
@ -327,20 +327,20 @@ public:
|
|||
_requestGroups.push_back(rg);
|
||||
}
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
else if(_detector.guessTorrentFile(uri)) {
|
||||
else if(_detector.guessTorrentMagnet(uri)) {
|
||||
try {
|
||||
_requestGroups.push_back(createBtRequestGroup(uri, _option,
|
||||
std::deque<std::string>()));
|
||||
SharedHandle<RequestGroup> group =
|
||||
createBtMagnetRequestGroup(uri, _option, std::deque<std::string>());
|
||||
_requestGroups.push_back(group);
|
||||
} catch(RecoverableException& e) {
|
||||
// error occurred while parsing torrent file.
|
||||
// We simply ignore it.
|
||||
LogFactory::getInstance()->error(EX_EXCEPTION_CAUGHT, e);
|
||||
}
|
||||
} else if(_detector.guessTorrentMagnet(uri)) {
|
||||
} else if(_detector.guessTorrentFile(uri)) {
|
||||
try {
|
||||
SharedHandle<RequestGroup> group =
|
||||
createBtMagnetRequestGroup(uri, _option, std::deque<std::string>());
|
||||
_requestGroups.push_back(group);
|
||||
_requestGroups.push_back(createBtRequestGroup(uri, _option,
|
||||
std::deque<std::string>()));
|
||||
} catch(RecoverableException& e) {
|
||||
// error occurred while parsing torrent file.
|
||||
// We simply ignore it.
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* Copyright (C) 2009 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "magnet.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
namespace magnet {
|
||||
|
||||
BDE parse(const std::string& magnet)
|
||||
{
|
||||
BDE result;
|
||||
if(!util::startsWith(magnet, "magnet:?")) {
|
||||
return result;
|
||||
}
|
||||
std::deque<std::string> queries;
|
||||
util::split(std::string(magnet.begin()+8, magnet.end()),
|
||||
std::back_inserter(queries), "&");
|
||||
BDE dict = BDE::dict();
|
||||
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(dict.containsKey(kv.first)) {
|
||||
dict[kv.first] << kv.second;
|
||||
} else {
|
||||
BDE list = BDE::list();
|
||||
list << kv.second;
|
||||
dict[kv.first] = list;
|
||||
}
|
||||
}
|
||||
result = dict;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace magnet
|
||||
|
||||
} // namespace aria2
|
|
@ -0,0 +1,56 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* Copyright (C) 2009 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_MAGNET_H_
|
||||
#define _D_MAGNET_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "BDE.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
namespace magnet {
|
||||
|
||||
// Parses Magnet URI magnet and stores parameters in BDE::dict().
|
||||
// Because same parameter name can appear more than once, the value
|
||||
// associated with a key is BDE::list(). A parameter value is stored
|
||||
// in a list. If parsing operation failed, BDE::none is returned.
|
||||
BDE parse(const std::string& magnet);
|
||||
|
||||
} // namespace magnet
|
||||
|
||||
} // namespace aria2
|
||||
|
||||
|
||||
#endif // _D_MAGNET_H_
|
|
@ -59,8 +59,8 @@ class BittorrentHelperTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testCreatecompact);
|
||||
CPPUNIT_TEST(testCheckBitfield);
|
||||
CPPUNIT_TEST(testMetadata);
|
||||
CPPUNIT_TEST(testParseMagnetLink);
|
||||
CPPUNIT_TEST(testParseMagnetLink_base32);
|
||||
CPPUNIT_TEST(testParseMagnet);
|
||||
CPPUNIT_TEST(testParseMagnet_base32);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
public:
|
||||
void setUp() {
|
||||
|
@ -100,8 +100,8 @@ public:
|
|||
void testCreatecompact();
|
||||
void testCheckBitfield();
|
||||
void testMetadata();
|
||||
void testParseMagnetLink();
|
||||
void testParseMagnetLink_base32();
|
||||
void testParseMagnet();
|
||||
void testParseMagnet_base32();
|
||||
};
|
||||
|
||||
|
||||
|
@ -700,33 +700,37 @@ void BittorrentHelperTest::testMetadata() {
|
|||
(size_t)attrs[bittorrent::METADATA_SIZE].i());
|
||||
}
|
||||
|
||||
void BittorrentHelperTest::testParseMagnetLink()
|
||||
void BittorrentHelperTest::testParseMagnet()
|
||||
{
|
||||
SharedHandle<DownloadContext> dctx(new DownloadContext());
|
||||
std::string magnet =
|
||||
"magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2";
|
||||
bittorrent::parseMagnetLink(magnet, dctx);
|
||||
"magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2"
|
||||
"&tr=http://tracker1&tr=http://tracker2";
|
||||
BDE attrs = bittorrent::parseMagnet(magnet);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
|
||||
bittorrent::getInfoHashString(dctx));
|
||||
BDE attrs = dctx->getAttribute(bittorrent::BITTORRENT);
|
||||
util::toHex(attrs[bittorrent::INFO_HASH].s()));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2"), attrs[bittorrent::NAME].s());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"),
|
||||
attrs[bittorrent::ANNOUNCE_LIST][0][0].s());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"),
|
||||
attrs[bittorrent::ANNOUNCE_LIST][0][1].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());
|
||||
attrs = bittorrent::parseMagnet(magnet);
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(std::string("[METADATA]248d0a1cd08284299de78d5c1ed359bb46717d8c"),
|
||||
attrs[bittorrent::NAME].s());
|
||||
CPPUNIT_ASSERT(attrs[bittorrent::ANNOUNCE_LIST].size() == 0);
|
||||
}
|
||||
|
||||
void BittorrentHelperTest::testParseMagnetLink_base32()
|
||||
void BittorrentHelperTest::testParseMagnet_base32()
|
||||
{
|
||||
std::string infoHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
|
||||
std::string base32InfoHash = base32::encode(util::fromHex(infoHash));
|
||||
SharedHandle<DownloadContext> dctx(new DownloadContext());
|
||||
std::string magnet = "magnet:?xt=urn:btih:"+base32InfoHash+"&dn=aria2";
|
||||
bittorrent::parseMagnetLink(magnet, dctx);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
|
||||
bittorrent::getInfoHashString(dctx));
|
||||
BDE attrs = bittorrent::parseMagnet(magnet);
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
|
||||
util::toHex(attrs[bittorrent::INFO_HASH].s()));
|
||||
}
|
||||
|
||||
} // namespace bittorrent
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#include "magnet.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
namespace magnet {
|
||||
|
||||
class MagnetTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(MagnetTest);
|
||||
CPPUNIT_TEST(testParse);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
public:
|
||||
void testParse();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(MagnetTest);
|
||||
|
||||
void MagnetTest::testParse()
|
||||
{
|
||||
BDE r = parse
|
||||
("magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2"
|
||||
"&tr=http://tracker1&tr=http://tracker2");
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(std::string("urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c"),
|
||||
r["xt"][0].s());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2"), r["dn"][0].s());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"), r["tr"][0].s());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"), r["tr"][1].s());
|
||||
|
||||
CPPUNIT_ASSERT(parse("http://localhost").isNone());
|
||||
}
|
||||
|
||||
} // namespace magnet
|
||||
|
||||
} // namespace aria2
|
|
@ -143,6 +143,7 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
|
|||
UTMetadataRequestTrackerTest.cc\
|
||||
UTMetadataRequestFactoryTest.cc\
|
||||
UTMetadataPostDownloadHandlerTest.cc\
|
||||
MagnetTest.cc\
|
||||
DefaultBtMessageFactoryTest.cc\
|
||||
DefaultExtensionMessageFactoryTest.cc\
|
||||
DHTNodeTest.cc\
|
||||
|
|
|
@ -92,6 +92,7 @@ check_PROGRAMS = $(am__EXEEXT_1)
|
|||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestTrackerTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestFactoryTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataPostDownloadHandlerTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ MagnetTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactoryTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactoryTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTNodeTest.cc\
|
||||
|
@ -236,7 +237,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
|
|||
UTMetadataRejectExtensionMessageTest.cc \
|
||||
UTMetadataRequestTrackerTest.cc \
|
||||
UTMetadataRequestFactoryTest.cc \
|
||||
UTMetadataPostDownloadHandlerTest.cc \
|
||||
UTMetadataPostDownloadHandlerTest.cc MagnetTest.cc \
|
||||
DefaultBtMessageFactoryTest.cc \
|
||||
DefaultExtensionMessageFactoryTest.cc DHTNodeTest.cc \
|
||||
DHTBucketTest.cc DHTRoutingTableTest.cc \
|
||||
|
@ -315,6 +316,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
|
|||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestTrackerTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestFactoryTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ UTMetadataPostDownloadHandlerTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ MagnetTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactoryTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactoryTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DHTNodeTest.$(OBJEXT) \
|
||||
|
@ -814,6 +816,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidatorTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LongestSequencePieceSelectorTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshakeTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MagnetTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelperTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Metalink2RequestGroupTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntryTest.Po@am__quote@
|
||||
|
|
|
@ -47,9 +47,9 @@ void ProtocolDetectorTest::testGuessTorrentFile()
|
|||
void ProtocolDetectorTest::testGuessTorrentMagnet()
|
||||
{
|
||||
ProtocolDetector detector;
|
||||
CPPUNIT_ASSERT(detector.guessTorrentMagnet("magnet:?xt=urn:btih:abcdef"));
|
||||
CPPUNIT_ASSERT(detector.guessTorrentMagnet
|
||||
("magnet:?dn=name&xt=urn:btih:abcdef"));
|
||||
CPPUNIT_ASSERT
|
||||
(detector.guessTorrentMagnet
|
||||
("magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c"));
|
||||
CPPUNIT_ASSERT(!detector.guessTorrentMagnet("magnet:?"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue