mirror of https://github.com/aria2/aria2
2007-10-27 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added the ability to recognize url-list in a torrent file. The retrieved URLs are attached to the corresponding FileEntry. * src/DefaultBtContext.{h, cc} * src/FileEntry.{h, cc} * test/DefaultBtContextTest.ccpull/1/head
parent
fdb2ee28cc
commit
368d53071a
|
@ -98,7 +98,8 @@ void DefaultBtContext::extractPieceHash(const unsigned char* hashData,
|
|||
}
|
||||
|
||||
void DefaultBtContext::extractFileEntries(Dictionary* infoDic,
|
||||
const string& defaultName) {
|
||||
const string& defaultName,
|
||||
const Strings& urlList) {
|
||||
// TODO use dynamic_cast
|
||||
Data* nameData = (Data*)infoDic->get("name");
|
||||
if(nameData) {
|
||||
|
@ -134,9 +135,13 @@ void DefaultBtContext::extractFileEntries(Dictionary* infoDic,
|
|||
Data* lastPath = (Data*)paths.back();
|
||||
path += lastPath->toString();
|
||||
|
||||
Strings uris;
|
||||
transform(urlList.begin(), urlList.end(), back_inserter(uris),
|
||||
bind2nd(plus<string>(), "/"+name+"/"+path));
|
||||
FileEntryHandle fileEntry(new FileEntry(path,
|
||||
lengthData->toLLInt(),
|
||||
offset));
|
||||
offset,
|
||||
uris));
|
||||
fileEntries.push_back(fileEntry);
|
||||
offset += fileEntry->getLength();
|
||||
}
|
||||
|
@ -146,7 +151,7 @@ void DefaultBtContext::extractFileEntries(Dictionary* infoDic,
|
|||
fileMode = BtContext::SINGLE;
|
||||
Data* length = (Data*)infoDic->get("length");
|
||||
totalLength = length->toLLInt();
|
||||
FileEntryHandle fileEntry(new FileEntry(name, totalLength, 0));
|
||||
FileEntryHandle fileEntry(new FileEntry(name, totalLength, 0, urlList));
|
||||
fileEntries.push_back(fileEntry);
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +179,25 @@ void DefaultBtContext::extractAnnounceList(List* announceListData) {
|
|||
}
|
||||
}
|
||||
|
||||
Strings DefaultBtContext::extractUrlList(const MetaEntry* obj)
|
||||
{
|
||||
Strings uris;
|
||||
if(dynamic_cast<const List*>(obj)) {
|
||||
const List* urlList = (const List*)obj;
|
||||
for(MetaList::const_iterator itr = urlList->getList().begin();
|
||||
itr != urlList->getList().end(); ++itr) {
|
||||
Data* data = dynamic_cast<Data*>(*itr);
|
||||
if(data) {
|
||||
uris.push_back(data->toString());
|
||||
}
|
||||
}
|
||||
} else if(dynamic_cast<const Data*>(obj)) {
|
||||
const Data* urlData = (const Data*)obj;
|
||||
uris.push_back(urlData->toString());
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
|
||||
void DefaultBtContext::load(const string& torrentFile) {
|
||||
clear();
|
||||
MetaEntry* rootEntry = MetaFileUtil::parseMetaFile(torrentFile);
|
||||
|
@ -199,8 +223,12 @@ void DefaultBtContext::load(const string& torrentFile) {
|
|||
extractPieceHash((unsigned char*)pieceHashData->getData(),
|
||||
pieceHashData->getLen(),
|
||||
PIECE_HASH_LENGTH);
|
||||
// retrieve uri-list.
|
||||
// This implemantation obeys HTTP-Seeding specification:
|
||||
// see http://www.getright.com/seedtorrent.html
|
||||
Strings urlList = extractUrlList(rootDic->get("url-list"));
|
||||
// retrieve file entries
|
||||
extractFileEntries(infoDic, torrentFile);
|
||||
extractFileEntries(infoDic, torrentFile, urlList);
|
||||
// retrieve announce
|
||||
Data* announceData = (Data*)rootDic->get("announce");
|
||||
List* announceListData = (List*)rootDic->get("announce-list");
|
||||
|
|
|
@ -66,9 +66,13 @@ private:
|
|||
int32_t hashDataLength,
|
||||
int32_t hashLength);
|
||||
void extractFileEntries(Dictionary* infoDic,
|
||||
const string& defaultName);
|
||||
const string& defaultName,
|
||||
const Strings& urlList);
|
||||
void extractAnnounce(Data* announceData);
|
||||
void extractAnnounceList(List* announceListData);
|
||||
|
||||
Strings extractUrlList(const MetaEntry* obj);
|
||||
|
||||
public:
|
||||
DefaultBtContext();
|
||||
virtual ~DefaultBtContext();
|
||||
|
|
|
@ -39,8 +39,9 @@
|
|||
|
||||
FileEntry::FileEntry(const string& path,
|
||||
int64_t length,
|
||||
int64_t offset):
|
||||
path(path), length(length), offset(offset),
|
||||
int64_t offset,
|
||||
const Strings& uris):
|
||||
path(path), _uris(uris), length(length), offset(offset),
|
||||
extracted(false), requested(true) {}
|
||||
|
||||
FileEntry::~FileEntry() {}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
class FileEntry {
|
||||
private:
|
||||
string path;
|
||||
Strings _uris;
|
||||
int64_t length;
|
||||
int64_t offset;
|
||||
bool extracted;
|
||||
|
@ -48,7 +49,7 @@ private:
|
|||
public:
|
||||
FileEntry():length(0), offset(0), extracted(false), requested(false) {}
|
||||
|
||||
FileEntry(const string& path, int64_t length, int64_t offset);
|
||||
FileEntry(const string& path, int64_t length, int64_t offset, const Strings& uris = Strings());
|
||||
|
||||
~FileEntry();
|
||||
|
||||
|
@ -85,6 +86,11 @@ public:
|
|||
void setRequested(bool flag) { this->requested = flag; }
|
||||
|
||||
void setupDir(const string& parentDir);
|
||||
|
||||
const Strings& getAssociatedUris() const
|
||||
{
|
||||
return _uris;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<FileEntry> FileEntryHandle;
|
||||
|
|
|
@ -25,6 +25,8 @@ class DefaultBtContextTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testGetInfoHashAsString);
|
||||
CPPUNIT_TEST(testGetPeerId);
|
||||
CPPUNIT_TEST(testComputeFastSet);
|
||||
CPPUNIT_TEST(testGetFileEntries_multiFileUrlList);
|
||||
CPPUNIT_TEST(testGetFileEntries_singleFileUrlList);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
public:
|
||||
void setUp() {
|
||||
|
@ -46,6 +48,8 @@ public:
|
|||
void testGetInfoHashAsString();
|
||||
void testGetPeerId();
|
||||
void testComputeFastSet();
|
||||
void testGetFileEntries_multiFileUrlList();
|
||||
void testGetFileEntries_singleFileUrlList();
|
||||
};
|
||||
|
||||
|
||||
|
@ -255,3 +259,51 @@ void DefaultBtContextTest::testComputeFastSet()
|
|||
Integers ansSet2(&ans2[0], &ans2[10]);
|
||||
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet2.begin()));
|
||||
}
|
||||
|
||||
void DefaultBtContextTest::testGetFileEntries_multiFileUrlList() {
|
||||
DefaultBtContext btContext;
|
||||
btContext.load("url-list-multiFile.torrent");
|
||||
// This is multi-file torrent.
|
||||
FileEntries fileEntries = btContext.getFileEntries();
|
||||
// There are 2 file entries.
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntries.size());
|
||||
FileEntries::iterator itr = fileEntries.begin();
|
||||
|
||||
FileEntryHandle fileEntry1 = *itr;
|
||||
CPPUNIT_ASSERT_EQUAL(string("aria2/src/aria2c"),
|
||||
fileEntry1->getPath());
|
||||
Strings uris1 = fileEntry1->getAssociatedUris();
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, uris1.size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("http://localhost/dist/aria2-test/aria2/src/aria2c"),
|
||||
uris1[0]);
|
||||
CPPUNIT_ASSERT_EQUAL(string("http://mirror/dist/aria2-test/aria2/src/aria2c"),
|
||||
uris1[1]);
|
||||
|
||||
itr++;
|
||||
FileEntryHandle fileEntry2 = *itr;
|
||||
CPPUNIT_ASSERT_EQUAL(string("aria2-0.2.2.tar.bz2"),
|
||||
fileEntry2->getPath());
|
||||
Strings uris2 = fileEntry2->getAssociatedUris();
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, uris2.size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("http://localhost/dist/aria2-test/aria2-0.2.2.tar.bz2"),
|
||||
uris2[0]);
|
||||
CPPUNIT_ASSERT_EQUAL(string("http://mirror/dist/aria2-test/aria2-0.2.2.tar.bz2"),
|
||||
uris2[1]);
|
||||
}
|
||||
|
||||
void DefaultBtContextTest::testGetFileEntries_singleFileUrlList() {
|
||||
DefaultBtContext btContext;
|
||||
btContext.load("url-list-singleFile.torrent");
|
||||
// This is multi-file torrent.
|
||||
FileEntries fileEntries = btContext.getFileEntries();
|
||||
// There are 1 file entries.
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
|
||||
|
||||
FileEntryHandle fileEntry1 = fileEntries.front();
|
||||
CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"),
|
||||
fileEntry1->getPath());
|
||||
Strings uris1 = fileEntry1->getAssociatedUris();
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, uris1.size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("http://localhost/dist/aria2.tar.bz2"),
|
||||
uris1[0]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
d8:url-listl21:http://localhost/dist18:http://mirror/diste8:announce36:http://aria.rednoah.com/announce.php13:announce-listll15:http://tracker1el15: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
|
|
@ -0,0 +1 @@
|
|||
d8:url-list35:http://localhost/dist/aria2.tar.bz28:announce36:http://aria.rednoah.com/announce.php13:announce-listll15:http://tracker1el15:http://tracker2el15:http://tracker3ee7:comment17:REDNOAH.COM RULES13:creation datei1123456789e4:infod6:lengthi7680e4:name13:aria2.tar.bz212:piece lengthi128e6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCee
|
Loading…
Reference in New Issue