mirror of https://github.com/aria2/aria2
2008-08-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Now aria2 uses name attribute in Metalink as local filename in BitTorrent downloads. BUG#2033999 * src/BtContext.h * src/BtDependency.cc * src/DefaultBtContext.cc * src/DefaultBtContext.h * src/SingleFileDownloadContext.cc * src/SingleFileDownloadContext.h * test/BtDependencyTest.cc * test/DefaultBtContextTest.cc * test/MockBtContext.hpull/1/head
parent
057516d1bc
commit
70b457da01
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2008-08-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
Now aria2 uses name attribute in Metalink as local filename in
|
||||||
|
BitTorrent downloads. BUG#2033999
|
||||||
|
* src/BtContext.h
|
||||||
|
* src/BtDependency.cc
|
||||||
|
* src/DefaultBtContext.cc
|
||||||
|
* src/DefaultBtContext.h
|
||||||
|
* src/SingleFileDownloadContext.cc
|
||||||
|
* src/SingleFileDownloadContext.h
|
||||||
|
* test/BtDependencyTest.cc
|
||||||
|
* test/DefaultBtContextTest.cc
|
||||||
|
* test/MockBtContext.h
|
||||||
|
|
||||||
2008-08-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2008-08-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Added AC_C_BIGENDIAN
|
Added AC_C_BIGENDIAN
|
||||||
|
|
|
@ -61,7 +61,8 @@ public:
|
||||||
virtual std::deque<SharedHandle<AnnounceTier> >
|
virtual std::deque<SharedHandle<AnnounceTier> >
|
||||||
getAnnounceTiers() const = 0;
|
getAnnounceTiers() const = 0;
|
||||||
|
|
||||||
virtual void load(const std::string& torrentFile) = 0;
|
virtual void load(const std::string& torrentFile,
|
||||||
|
const std::string& overrideName = "") = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the peer id of localhost, 20 byte length
|
* Returns the peer id of localhost, 20 byte length
|
||||||
|
|
|
@ -70,7 +70,8 @@ bool BtDependency::resolve()
|
||||||
diskAdaptor->openExistingFile();
|
diskAdaptor->openExistingFile();
|
||||||
std::string content = Util::toString(diskAdaptor);
|
std::string content = Util::toString(diskAdaptor);
|
||||||
btContext->loadFromMemory(content,
|
btContext->loadFromMemory(content,
|
||||||
File(dependee->getFilePath()).getBasename());
|
File(dependee->getFilePath()).getBasename(),
|
||||||
|
_dependant->getDownloadContext()->getName());
|
||||||
if(_option->defined(PREF_PEER_ID_PREFIX)) {
|
if(_option->defined(PREF_PEER_ID_PREFIX)) {
|
||||||
btContext->setPeerIdPrefix(_option->get(PREF_PEER_ID_PREFIX));
|
btContext->setPeerIdPrefix(_option->get(PREF_PEER_ID_PREFIX));
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,12 +114,18 @@ void DefaultBtContext::extractPieceHash(const unsigned char* hashData,
|
||||||
|
|
||||||
void DefaultBtContext::extractFileEntries(const Dictionary* infoDic,
|
void DefaultBtContext::extractFileEntries(const Dictionary* infoDic,
|
||||||
const std::string& defaultName,
|
const std::string& defaultName,
|
||||||
|
const std::string& overrideName,
|
||||||
const std::deque<std::string>& urlList) {
|
const std::deque<std::string>& urlList) {
|
||||||
const Data* nameData = dynamic_cast<const Data*>(infoDic->get(BtContext::C_NAME));
|
if(overrideName.empty()) {
|
||||||
if(nameData) {
|
const Data* nameData =
|
||||||
name = nameData->toString();
|
dynamic_cast<const Data*>(infoDic->get(BtContext::C_NAME));
|
||||||
|
if(nameData) {
|
||||||
|
name = nameData->toString();
|
||||||
|
} else {
|
||||||
|
name = File(defaultName).getBasename()+".file";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
name = File(defaultName).getBasename()+".file";
|
name = overrideName;
|
||||||
}
|
}
|
||||||
const List* files = dynamic_cast<const List*>(infoDic->get(BtContext::C_FILES));
|
const List* files = dynamic_cast<const List*>(infoDic->get(BtContext::C_FILES));
|
||||||
if(files) {
|
if(files) {
|
||||||
|
@ -271,7 +277,8 @@ void DefaultBtContext::extractNodes(const List* nodes)
|
||||||
|
|
||||||
void DefaultBtContext::loadFromMemory(const unsigned char* content,
|
void DefaultBtContext::loadFromMemory(const unsigned char* content,
|
||||||
size_t length,
|
size_t length,
|
||||||
const std::string& defaultName)
|
const std::string& defaultName,
|
||||||
|
const std::string& overrideName)
|
||||||
{
|
{
|
||||||
SharedHandle<MetaEntry> rootEntry(MetaFileUtil::bdecoding(content, length));
|
SharedHandle<MetaEntry> rootEntry(MetaFileUtil::bdecoding(content, length));
|
||||||
const Dictionary* rootDic = dynamic_cast<const Dictionary*>(rootEntry.get());
|
const Dictionary* rootDic = dynamic_cast<const Dictionary*>(rootEntry.get());
|
||||||
|
@ -279,20 +286,23 @@ void DefaultBtContext::loadFromMemory(const unsigned char* content,
|
||||||
throw DlAbortEx
|
throw DlAbortEx
|
||||||
(StringFormat("torrent file does not contain a root dictionary .").str());
|
(StringFormat("torrent file does not contain a root dictionary .").str());
|
||||||
}
|
}
|
||||||
processRootDictionary(rootDic, defaultName);
|
processRootDictionary(rootDic, defaultName, overrideName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultBtContext::load(const std::string& torrentFile) {
|
void DefaultBtContext::load(const std::string& torrentFile,
|
||||||
|
const std::string& overrideName) {
|
||||||
SharedHandle<MetaEntry> rootEntry(MetaFileUtil::parseMetaFile(torrentFile));
|
SharedHandle<MetaEntry> rootEntry(MetaFileUtil::parseMetaFile(torrentFile));
|
||||||
const Dictionary* rootDic = dynamic_cast<const Dictionary*>(rootEntry.get());
|
const Dictionary* rootDic = dynamic_cast<const Dictionary*>(rootEntry.get());
|
||||||
if(!rootDic) {
|
if(!rootDic) {
|
||||||
throw DlAbortEx
|
throw DlAbortEx
|
||||||
(StringFormat("torrent file does not contain a root dictionary .").str());
|
(StringFormat("torrent file does not contain a root dictionary .").str());
|
||||||
}
|
}
|
||||||
processRootDictionary(rootDic, torrentFile);
|
processRootDictionary(rootDic, torrentFile, overrideName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultBtContext::processRootDictionary(const Dictionary* rootDic, const std::string& defaultName)
|
void DefaultBtContext::processRootDictionary(const Dictionary* rootDic,
|
||||||
|
const std::string& defaultName,
|
||||||
|
const std::string& overrideName)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
const Dictionary* infoDic =
|
const Dictionary* infoDic =
|
||||||
|
@ -347,7 +357,7 @@ void DefaultBtContext::processRootDictionary(const Dictionary* rootDic, const st
|
||||||
std::deque<std::string> urlList;
|
std::deque<std::string> urlList;
|
||||||
extractUrlList(urlList, rootDic->get(BtContext::C_URL_LIST));
|
extractUrlList(urlList, rootDic->get(BtContext::C_URL_LIST));
|
||||||
// retrieve file entries
|
// retrieve file entries
|
||||||
extractFileEntries(infoDic, defaultName, urlList);
|
extractFileEntries(infoDic, defaultName, overrideName, urlList);
|
||||||
if((totalLength+pieceLength-1)/pieceLength != numPieces) {
|
if((totalLength+pieceLength-1)/pieceLength != numPieces) {
|
||||||
throw DlAbortEx("Too few/many piece hash.");
|
throw DlAbortEx("Too few/many piece hash.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ private:
|
||||||
size_t hashLength);
|
size_t hashLength);
|
||||||
void extractFileEntries(const Dictionary* infoDic,
|
void extractFileEntries(const Dictionary* infoDic,
|
||||||
const std::string& defaultName,
|
const std::string& defaultName,
|
||||||
|
const std::string& overrideName,
|
||||||
const std::deque<std::string>& urlList);
|
const std::deque<std::string>& urlList);
|
||||||
void extractAnnounce(const Data* announceData);
|
void extractAnnounce(const Data* announceData);
|
||||||
void extractAnnounceList(const List* announceListData);
|
void extractAnnounceList(const List* announceListData);
|
||||||
|
@ -86,7 +87,9 @@ private:
|
||||||
|
|
||||||
void extractNodes(const List* nodes);
|
void extractNodes(const List* nodes);
|
||||||
|
|
||||||
void processRootDictionary(const Dictionary* rootDic, const std::string& defaultName);
|
void processRootDictionary(const Dictionary* rootDic,
|
||||||
|
const std::string& defaultName,
|
||||||
|
const std::string& overrideName);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DefaultBtContext();
|
DefaultBtContext();
|
||||||
|
@ -115,15 +118,19 @@ private:
|
||||||
|
|
||||||
virtual std::deque<SharedHandle<AnnounceTier> > getAnnounceTiers() const;
|
virtual std::deque<SharedHandle<AnnounceTier> > getAnnounceTiers() const;
|
||||||
|
|
||||||
virtual void load(const std::string& torrentFile);
|
virtual void load(const std::string& torrentFile,
|
||||||
|
const std::string& overrideName = "");
|
||||||
|
|
||||||
void loadFromMemory(const unsigned char* content, size_t length,
|
void loadFromMemory(const unsigned char* content, size_t length,
|
||||||
const std::string& defaultName);
|
const std::string& defaultName,
|
||||||
|
const std::string& overrideName = "");
|
||||||
|
|
||||||
void loadFromMemory(const std::string& context, const std::string& defaultName)
|
void loadFromMemory(const std::string& context,
|
||||||
|
const std::string& defaultName,
|
||||||
|
const std::string& overrideName = "")
|
||||||
{
|
{
|
||||||
loadFromMemory(reinterpret_cast<const unsigned char*>(context.c_str()),
|
loadFromMemory(reinterpret_cast<const unsigned char*>(context.c_str()),
|
||||||
context.size(), defaultName);
|
context.size(), defaultName, overrideName);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const std::string& getName() const;
|
virtual const std::string& getName() const;
|
||||||
|
|
|
@ -96,4 +96,9 @@ void SingleFileDownloadContext::setTotalLength(uint64_t totalLength)
|
||||||
_fileEntry->setLength(totalLength);
|
_fileEntry->setLength(totalLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& SingleFileDownloadContext::getName() const
|
||||||
|
{
|
||||||
|
return _fileEntry->getPath();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -95,10 +95,7 @@ public:
|
||||||
|
|
||||||
virtual std::deque<SharedHandle<FileEntry> > getFileEntries() const;
|
virtual std::deque<SharedHandle<FileEntry> > getFileEntries() const;
|
||||||
|
|
||||||
virtual const std::string& getName() const
|
virtual const std::string& getName() const;
|
||||||
{
|
|
||||||
return _filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual size_t getPieceLength() const
|
virtual size_t getPieceLength() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ class BtDependencyTest:public CppUnit::TestFixture {
|
||||||
{
|
{
|
||||||
SharedHandle<RequestGroup> dependant(new RequestGroup(option, std::deque<std::string>()));
|
SharedHandle<RequestGroup> dependant(new RequestGroup(option, std::deque<std::string>()));
|
||||||
SharedHandle<SingleFileDownloadContext> dctx
|
SharedHandle<SingleFileDownloadContext> dctx
|
||||||
(new SingleFileDownloadContext(0, 0, ""));
|
(new SingleFileDownloadContext(0, 0, "outfile.path"));
|
||||||
dctx->setDir("/tmp");
|
dctx->setDir("/tmp");
|
||||||
dependant->setDownloadContext(dctx);
|
dependant->setDownloadContext(dctx);
|
||||||
return dependant;
|
return dependant;
|
||||||
|
@ -73,7 +73,8 @@ void BtDependencyTest::testResolve()
|
||||||
SharedHandle<BtContext> btContext
|
SharedHandle<BtContext> btContext
|
||||||
(dynamic_pointer_cast<BtContext>(dependant->getDownloadContext()));
|
(dynamic_pointer_cast<BtContext>(dependant->getDownloadContext()));
|
||||||
CPPUNIT_ASSERT(!btContext.isNull());
|
CPPUNIT_ASSERT(!btContext.isNull());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/tmp/aria2-test"), btContext->getActualBasePath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/tmp/outfile.path"),
|
||||||
|
btContext->getActualBasePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BtDependencyTest::testResolve_loadError()
|
void BtDependencyTest::testResolve_loadError()
|
||||||
|
@ -88,9 +89,11 @@ void BtDependencyTest::testResolve_loadError()
|
||||||
CPPUNIT_ASSERT(dep.resolve());
|
CPPUNIT_ASSERT(dep.resolve());
|
||||||
|
|
||||||
SharedHandle<SingleFileDownloadContext> dctx
|
SharedHandle<SingleFileDownloadContext> dctx
|
||||||
(dynamic_pointer_cast<SingleFileDownloadContext>(dependant->getDownloadContext()));
|
(dynamic_pointer_cast<SingleFileDownloadContext>
|
||||||
|
(dependant->getDownloadContext()));
|
||||||
CPPUNIT_ASSERT(!dctx.isNull());
|
CPPUNIT_ASSERT(!dctx.isNull());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/tmp/index.html"), dctx->getActualBasePath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/tmp/outfile.path"),
|
||||||
|
dctx->getActualBasePath());
|
||||||
} catch(Exception& e) {
|
} catch(Exception& e) {
|
||||||
std::cerr << e.stackTrace() << std::endl;
|
std::cerr << e.stackTrace() << std::endl;
|
||||||
CPPUNIT_FAIL("an exception was thrown.");
|
CPPUNIT_FAIL("an exception was thrown.");
|
||||||
|
@ -107,9 +110,11 @@ void BtDependencyTest::testResolve_dependeeFailure()
|
||||||
CPPUNIT_ASSERT(dep.resolve());
|
CPPUNIT_ASSERT(dep.resolve());
|
||||||
|
|
||||||
SharedHandle<SingleFileDownloadContext> dctx
|
SharedHandle<SingleFileDownloadContext> dctx
|
||||||
(dynamic_pointer_cast<SingleFileDownloadContext>(dependant->getDownloadContext()));
|
(dynamic_pointer_cast<SingleFileDownloadContext>
|
||||||
|
(dependant->getDownloadContext()));
|
||||||
CPPUNIT_ASSERT(!dctx.isNull());
|
CPPUNIT_ASSERT(!dctx.isNull());
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/tmp/index.html"), dctx->getActualBasePath());
|
CPPUNIT_ASSERT_EQUAL(std::string("/tmp/outfile.path"),
|
||||||
|
dctx->getActualBasePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BtDependencyTest::testResolve_dependeeInProgress()
|
void BtDependencyTest::testResolve_dependeeInProgress()
|
||||||
|
|
|
@ -24,6 +24,7 @@ class DefaultBtContextTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testGetFileModeSingle);
|
CPPUNIT_TEST(testGetFileModeSingle);
|
||||||
CPPUNIT_TEST(testGetNameMulti);
|
CPPUNIT_TEST(testGetNameMulti);
|
||||||
CPPUNIT_TEST(testGetNameSingle);
|
CPPUNIT_TEST(testGetNameSingle);
|
||||||
|
CPPUNIT_TEST(testOverrideName);
|
||||||
CPPUNIT_TEST(testGetAnnounceTier);
|
CPPUNIT_TEST(testGetAnnounceTier);
|
||||||
CPPUNIT_TEST(testGetAnnounceTierAnnounceList);
|
CPPUNIT_TEST(testGetAnnounceTierAnnounceList);
|
||||||
CPPUNIT_TEST(testGetPieceLength);
|
CPPUNIT_TEST(testGetPieceLength);
|
||||||
|
@ -34,6 +35,7 @@ class DefaultBtContextTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testGetFileEntries_singleFileUrlList);
|
CPPUNIT_TEST(testGetFileEntries_singleFileUrlList);
|
||||||
CPPUNIT_TEST(testLoadFromMemory);
|
CPPUNIT_TEST(testLoadFromMemory);
|
||||||
CPPUNIT_TEST(testLoadFromMemory_somethingMissing);
|
CPPUNIT_TEST(testLoadFromMemory_somethingMissing);
|
||||||
|
CPPUNIT_TEST(testLoadFromMemory_overrideName);
|
||||||
CPPUNIT_TEST(testGetNodes);
|
CPPUNIT_TEST(testGetNodes);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
public:
|
public:
|
||||||
|
@ -50,6 +52,7 @@ public:
|
||||||
void testGetFileModeSingle();
|
void testGetFileModeSingle();
|
||||||
void testGetNameMulti();
|
void testGetNameMulti();
|
||||||
void testGetNameSingle();
|
void testGetNameSingle();
|
||||||
|
void testOverrideName();
|
||||||
void testGetAnnounceTier();
|
void testGetAnnounceTier();
|
||||||
void testGetAnnounceTierAnnounceList();
|
void testGetAnnounceTierAnnounceList();
|
||||||
void testGetPieceLength();
|
void testGetPieceLength();
|
||||||
|
@ -60,6 +63,7 @@ public:
|
||||||
void testGetFileEntries_singleFileUrlList();
|
void testGetFileEntries_singleFileUrlList();
|
||||||
void testLoadFromMemory();
|
void testLoadFromMemory();
|
||||||
void testLoadFromMemory_somethingMissing();
|
void testLoadFromMemory_somethingMissing();
|
||||||
|
void testLoadFromMemory_overrideName();
|
||||||
void testGetNodes();
|
void testGetNodes();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,6 +171,13 @@ void DefaultBtContextTest::testGetNameSingle() {
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.8.2.tar.bz2"), btContext.getName());
|
CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.8.2.tar.bz2"), btContext.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefaultBtContextTest::testOverrideName()
|
||||||
|
{
|
||||||
|
DefaultBtContext btContext;
|
||||||
|
btContext.load("test.torrent", "aria2-override.name");
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("aria2-override.name"), btContext.getName());
|
||||||
|
}
|
||||||
|
|
||||||
void DefaultBtContextTest::testGetAnnounceTier() {
|
void DefaultBtContextTest::testGetAnnounceTier() {
|
||||||
DefaultBtContext btContext;
|
DefaultBtContext btContext;
|
||||||
btContext.load("single.torrent");
|
btContext.load("single.torrent");
|
||||||
|
@ -342,6 +353,16 @@ void DefaultBtContextTest::testLoadFromMemory_somethingMissing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefaultBtContextTest::testLoadFromMemory_overrideName()
|
||||||
|
{
|
||||||
|
std::string memory = "d8:announce36:http://aria.rednoah.com/announce.php13:announce-listll16:http://tracker1 el15:http://tracker2el15:http://tracker3ee7:comment17:REDNOAH.COM RULES13:creation datei1123456789e4:infod5:filesld6:lengthi284e4:pathl5:aria23:src6:aria2ceed6:lengthi100e4:pathl19:aria2-0.2.2.tar.bz2eee4:name10:aria2-test12:piece lengthi128e6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCee";
|
||||||
|
|
||||||
|
DefaultBtContext btContext;
|
||||||
|
btContext.loadFromMemory(memory, "default", "aria2-override.name");
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("aria2-override.name"), btContext.getName());
|
||||||
|
}
|
||||||
|
|
||||||
void DefaultBtContextTest::testGetNodes()
|
void DefaultBtContextTest::testGetNodes()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,7 +92,8 @@ public:
|
||||||
announceTiers.push_back(announceTier);
|
announceTiers.push_back(announceTier);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void load(const std::string& torrentFile) {}
|
virtual void load(const std::string& torrentFile,
|
||||||
|
const std::string& overrideName = "") {}
|
||||||
|
|
||||||
virtual const std::string& getName() const {
|
virtual const std::string& getName() const {
|
||||||
return name;
|
return name;
|
||||||
|
|
Loading…
Reference in New Issue