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
pull/1/head
Tatsuhiro Tsujikawa 2008-08-08 16:44:59 +00:00
parent 057516d1bc
commit 70b457da01
10 changed files with 90 additions and 28 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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()
{ {
{ {

View File

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