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
pull/1/head
Tatsuhiro Tsujikawa 2009-11-24 14:47:42 +00:00
parent d2cefd8613
commit 512be58217
14 changed files with 294 additions and 84 deletions

View File

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

View File

@ -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\

View File

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

View File

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

View File

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

View File

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

View File

@ -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,16 +327,7 @@ public:
_requestGroups.push_back(rg);
}
#ifdef ENABLE_BITTORRENT
else if(_detector.guessTorrentFile(uri)) {
try {
_requestGroups.push_back(createBtRequestGroup(uri, _option,
std::deque<std::string>()));
} 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.guessTorrentMagnet(uri)) {
try {
SharedHandle<RequestGroup> group =
createBtMagnetRequestGroup(uri, _option, std::deque<std::string>());
@ -346,7 +337,16 @@ public:
// We simply ignore it.
LogFactory::getInstance()->error(EX_EXCEPTION_CAUGHT, e);
}
}
} else if(_detector.guessTorrentFile(uri)) {
try {
_requestGroups.push_back(createBtRequestGroup(uri, _option,
std::deque<std::string>()));
} catch(RecoverableException& e) {
// error occurred while parsing torrent file.
// We simply ignore it.
LogFactory::getInstance()->error(EX_EXCEPTION_CAUGHT, e);
}
}
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
else if(_detector.guessMetalinkFile(uri)) {

70
src/magnet.cc Normal file
View File

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

56
src/magnet.h Normal file
View File

@ -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_

View File

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

40
test/MagnetTest.cc Normal file
View File

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

View File

@ -143,6 +143,7 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
UTMetadataRequestTrackerTest.cc\
UTMetadataRequestFactoryTest.cc\
UTMetadataPostDownloadHandlerTest.cc\
MagnetTest.cc\
DefaultBtMessageFactoryTest.cc\
DefaultExtensionMessageFactoryTest.cc\
DHTNodeTest.cc\

View File

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

View File

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