mirror of https://github.com/aria2/aria2
2009-11-28 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Accept BitTorrent Magnet URI in Metalink resource type bittorrent. Rewritten UTMetadataPostDownloadHandler. To create torrent data from metadata, use new metadata2Torrent() function. * src/BtDependency.cc * src/UTMetadataPostDownloadHandler.cc * src/bittorrent_helper.cc * src/bittorrent_helper.h * test/BittorrentHelperTest.cc * test/BtDependencyTest.ccpull/1/head
parent
96205abc67
commit
339795311b
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2009-11-28 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Accept BitTorrent Magnet URI in Metalink resource type bittorrent.
|
||||
Rewritten UTMetadataPostDownloadHandler. To create torrent data
|
||||
from metadata, use new metadata2Torrent() function.
|
||||
* src/BtDependency.cc
|
||||
* src/UTMetadataPostDownloadHandler.cc
|
||||
* src/bittorrent_helper.cc
|
||||
* src/bittorrent_helper.h
|
||||
* test/BittorrentHelperTest.cc
|
||||
* test/BtDependencyTest.cc
|
||||
|
||||
2009-11-28 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Use createRequestGroupForUri to create the download for torrent
|
||||
|
|
|
@ -71,8 +71,15 @@ bool BtDependency::resolve()
|
|||
dependee->getPieceStorage()->getDiskAdaptor();
|
||||
diskAdaptor->openExistingFile();
|
||||
std::string content = util::toString(diskAdaptor);
|
||||
if(dependee->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
|
||||
const BDE& attrs =
|
||||
dependee->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
|
||||
bittorrent::loadFromMemory
|
||||
(bittorrent::metadata2Torrent(content, attrs), context, "default");
|
||||
} else {
|
||||
bittorrent::loadFromMemory
|
||||
(content, context, File(dependee->getFirstFilePath()).getBasename());
|
||||
}
|
||||
if(context->getFileEntries().size() !=
|
||||
_dependant->getDownloadContext()->getFileEntries().size()) {
|
||||
throw DL_ABORT_EX("The number of file in torrent doesn't match to"
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "a2functional.h"
|
||||
#include "DiskAdaptor.h"
|
||||
#include "PieceStorage.h"
|
||||
#include "bencode.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -72,35 +73,13 @@ void UTMetadataPostDownloadHandler::getNextRequestGroups
|
|||
{
|
||||
SharedHandle<DownloadContext> dctx = requestGroup->getDownloadContext();
|
||||
const BDE& attrs = dctx->getAttribute(bittorrent::BITTORRENT);
|
||||
std::string torrent =
|
||||
strconcat("d4:info",
|
||||
util::toString(requestGroup->getPieceStorage()->getDiskAdaptor()),
|
||||
"e");
|
||||
std::string metadata =
|
||||
util::toString(requestGroup->getPieceStorage()->getDiskAdaptor());
|
||||
std::string torrent = bittorrent::metadata2Torrent(metadata, attrs);
|
||||
try {
|
||||
std::deque<SharedHandle<RequestGroup> > newRgs;
|
||||
createRequestGroupForBitTorrent(newRgs, requestGroup->getOption(),
|
||||
std::deque<std::string>(), torrent);
|
||||
if(attrs.containsKey(bittorrent::ANNOUNCE_LIST)) {
|
||||
for(std::deque<SharedHandle<RequestGroup> >::const_iterator i =
|
||||
newRgs.begin(); i != newRgs.end(); ++i) {
|
||||
SharedHandle<DownloadContext> newDctx = (*i)->getDownloadContext();
|
||||
if(!newDctx->hasAttribute(bittorrent::BITTORRENT)) {
|
||||
continue;
|
||||
}
|
||||
BDE& newAttrs = newDctx->getAttribute(bittorrent::BITTORRENT);
|
||||
if(attrs[bittorrent::INFO_HASH].s() !=
|
||||
newAttrs[bittorrent::INFO_HASH].s()) {
|
||||
continue;
|
||||
}
|
||||
assert(newAttrs[bittorrent::ANNOUNCE_LIST].isList());
|
||||
if(newAttrs[bittorrent::ANNOUNCE_LIST].size() == 0) {
|
||||
newAttrs[bittorrent::ANNOUNCE_LIST] =
|
||||
attrs[bittorrent::ANNOUNCE_LIST];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
groups.insert(groups.end(), newRgs.begin(), newRgs.end());
|
||||
} catch(RecoverableException& e) {
|
||||
_logger->error("Failed to parse BitTorrent metadata.", e);
|
||||
|
|
|
@ -904,6 +904,21 @@ void loadMagnet
|
|||
dctx->setAttribute(BITTORRENT, attrs);
|
||||
}
|
||||
|
||||
std::string metadata2Torrent(const std::string& metadata, const BDE& attrs)
|
||||
{
|
||||
std::string torrent = "d";
|
||||
if(attrs.containsKey(bittorrent::ANNOUNCE_LIST)) {
|
||||
const BDE& announceList = attrs[bittorrent::ANNOUNCE_LIST];
|
||||
if(announceList.size() > 0) {
|
||||
torrent += "13:announce-list";
|
||||
torrent += bencode::encode(announceList);
|
||||
}
|
||||
}
|
||||
torrent +=
|
||||
strconcat("4:info", metadata, "e");
|
||||
return torrent;
|
||||
}
|
||||
|
||||
} // namespace bittorrent
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -230,6 +230,11 @@ void assertID
|
|||
|
||||
void generateRandomKey(unsigned char* key);
|
||||
|
||||
// Converts attrs into torrent data. attrs must be a BDE::dict. This
|
||||
// function does not guarantee the returned string is valid torrent
|
||||
// data.
|
||||
std::string metadata2Torrent(const std::string& metadata, const BDE& attrs);
|
||||
|
||||
} // namespace bittorrent
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -61,6 +61,7 @@ class BittorrentHelperTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testMetadata);
|
||||
CPPUNIT_TEST(testParseMagnet);
|
||||
CPPUNIT_TEST(testParseMagnet_base32);
|
||||
CPPUNIT_TEST(testMetadata2Torrent);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
public:
|
||||
void setUp() {
|
||||
|
@ -102,6 +103,7 @@ public:
|
|||
void testMetadata();
|
||||
void testParseMagnet();
|
||||
void testParseMagnet_base32();
|
||||
void testMetadata2Torrent();
|
||||
};
|
||||
|
||||
|
||||
|
@ -734,6 +736,25 @@ void BittorrentHelperTest::testParseMagnet_base32()
|
|||
util::toHex(attrs[bittorrent::INFO_HASH].s()));
|
||||
}
|
||||
|
||||
void BittorrentHelperTest::testMetadata2Torrent()
|
||||
{
|
||||
std::string metadata = "METADATA";
|
||||
BDE attrs = BDE::dict();
|
||||
BDE announceList = BDE::list();
|
||||
attrs[ANNOUNCE_LIST] = announceList;
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(std::string("d4:infoMETADATAe"), metadata2Torrent(metadata, attrs));
|
||||
announceList << BDE::list();
|
||||
announceList[0] << std::string("http://localhost/announce");
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(std::string("d"
|
||||
"13:announce-list"
|
||||
"ll25:http://localhost/announceee"
|
||||
"4:infoMETADATA"
|
||||
"e"),
|
||||
metadata2Torrent(metadata, attrs));
|
||||
}
|
||||
|
||||
} // namespace bittorrent
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include "FileEntry.h"
|
||||
#include "PieceSelector.h"
|
||||
#include "bittorrent_helper.h"
|
||||
#include "DirectDiskAdaptor.h"
|
||||
#include "ByteArrayDiskWriter.h"
|
||||
#include "MockPieceStorage.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -20,6 +23,7 @@ class BtDependencyTest:public CppUnit::TestFixture {
|
|||
|
||||
CPPUNIT_TEST_SUITE(BtDependencyTest);
|
||||
CPPUNIT_TEST(testResolve);
|
||||
CPPUNIT_TEST(testResolve_metadata);
|
||||
CPPUNIT_TEST(testResolve_loadError);
|
||||
CPPUNIT_TEST(testResolve_dependeeFailure);
|
||||
CPPUNIT_TEST(testResolve_dependeeInProgress);
|
||||
|
@ -64,6 +68,7 @@ public:
|
|||
}
|
||||
|
||||
void testResolve();
|
||||
void testResolve_metadata();
|
||||
void testResolve_loadError();
|
||||
void testResolve_dependeeFailure();
|
||||
void testResolve_dependeeInProgress();
|
||||
|
@ -93,6 +98,34 @@ void BtDependencyTest::testResolve()
|
|||
CPPUNIT_ASSERT_EQUAL((size_t)1, firstFileEntry->getRemainingUris().size());
|
||||
}
|
||||
|
||||
void BtDependencyTest::testResolve_metadata()
|
||||
{
|
||||
SharedHandle<RequestGroup> dependant = createDependant(_option);
|
||||
SharedHandle<RequestGroup> dependee =
|
||||
createDependee(_option, "metadata", 0);
|
||||
|
||||
SharedHandle<DirectDiskAdaptor> diskAdaptor(new DirectDiskAdaptor());
|
||||
SharedHandle<ByteArrayDiskWriter> diskWriter(new ByteArrayDiskWriter());
|
||||
diskAdaptor->setDiskWriter(diskWriter);
|
||||
diskWriter->setString
|
||||
("d4:name19:aria2-0.8.2.tar.bz26:lengthi384e12:piece lengthi128e"
|
||||
"6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCC"
|
||||
"e");
|
||||
SharedHandle<MockPieceStorage> pieceStorage(new MockPieceStorage());
|
||||
pieceStorage->setDiskAdaptor(diskAdaptor);
|
||||
pieceStorage->setDownloadFinished(true);
|
||||
dependee->setPieceStorage(pieceStorage);
|
||||
BDE attrs = BDE::dict();
|
||||
dependee->getDownloadContext()->setAttribute(bittorrent::BITTORRENT, attrs);
|
||||
|
||||
BtDependency dep(dependant, dependee);
|
||||
CPPUNIT_ASSERT(dep.resolve());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(std::string("cd41c7fdddfd034a15a04d7ff881216e01c4ceaf"),
|
||||
bittorrent::getInfoHashString(dependant->getDownloadContext()));
|
||||
}
|
||||
|
||||
void BtDependencyTest::testResolve_loadError()
|
||||
{
|
||||
SharedHandle<RequestGroup> dependant = createDependant(_option);
|
||||
|
|
Loading…
Reference in New Issue