mirror of https://github.com/aria2/aria2
2008-12-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Use BDE instead of Dictionary/List/Data classes. * src/CompactPeerListProcessor.cc * src/CompactPeerListProcessor.h * src/DefaultBtAnnounce.cc * src/DefaultBtContext.cc * src/DefaultBtContext.h * src/DefaultPeerListProcessor.cc * src/DefaultPeerListProcessor.h * src/DelegatingPeerListProcessor.cc * src/DelegatingPeerListProcessor.h * src/PeerListProcessor.h * src/UTPexExtensionMessage.cc * src/Util.h * src/message.h * test/DefaultBtContextTest.cc * test/DefaultPeerListProcessorTest.ccpull/1/head
parent
1b54e64d34
commit
8129042a3a
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
2008-12-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Use BDE instead of Dictionary/List/Data classes.
|
||||
* src/CompactPeerListProcessor.cc
|
||||
* src/CompactPeerListProcessor.h
|
||||
* src/DefaultBtAnnounce.cc
|
||||
* src/DefaultBtContext.cc
|
||||
* src/DefaultBtContext.h
|
||||
* src/DefaultPeerListProcessor.cc
|
||||
* src/DefaultPeerListProcessor.h
|
||||
* src/DelegatingPeerListProcessor.cc
|
||||
* src/DelegatingPeerListProcessor.h
|
||||
* src/PeerListProcessor.h
|
||||
* src/UTPexExtensionMessage.cc
|
||||
* src/Util.h
|
||||
* src/message.h
|
||||
* test/DefaultBtContextTest.cc
|
||||
* test/DefaultPeerListProcessorTest.cc
|
||||
|
||||
2008-12-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Added bencode helper functions and BDE class.
|
||||
|
|
|
@ -32,9 +32,9 @@
|
|||
*/
|
||||
/* copyright --> */
|
||||
#include "CompactPeerListProcessor.h"
|
||||
#include "Peer.h"
|
||||
#include "Data.h"
|
||||
#include "a2netcompat.h"
|
||||
#include "bencode.h"
|
||||
#include "Peer.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -42,23 +42,24 @@ CompactPeerListProcessor::CompactPeerListProcessor() {}
|
|||
|
||||
CompactPeerListProcessor::~CompactPeerListProcessor() {}
|
||||
|
||||
bool CompactPeerListProcessor::canHandle(const MetaEntry* peersEntry) const {
|
||||
return dynamic_cast<const Data*>(peersEntry) != 0;
|
||||
bool CompactPeerListProcessor::canHandle(const bencode::BDE& peerData) const
|
||||
{
|
||||
return peerData.isString();
|
||||
}
|
||||
|
||||
void CompactPeerListProcessor::extractPeer
|
||||
(std::deque<SharedHandle<Peer> >& peers, const MetaEntry* peersEntry)
|
||||
(std::deque<SharedHandle<Peer> >& peers, const bencode::BDE& peerData)
|
||||
{
|
||||
const Data* peersData = dynamic_cast<const Data*>(peersEntry);
|
||||
if(!peersData) {
|
||||
if(!canHandle(peerData)) {
|
||||
return;
|
||||
}
|
||||
if(peersData->getLen()%6 == 0) {
|
||||
for(size_t i = 0; i < peersData->getLen(); i += 6) {
|
||||
size_t length = peerData.s().size();
|
||||
if(length%6 == 0) {
|
||||
for(size_t i = 0; i < length; i += 6) {
|
||||
struct in_addr in;
|
||||
in.s_addr = *(uint32_t*)(peersData->getData()+i);
|
||||
in.s_addr = *(uint32_t*)(peerData.s().c_str()+i);
|
||||
std::string ipaddr = inet_ntoa(in);
|
||||
uint16_t port = ntohs(*(uint16_t*)(peersData->getData()+i+4));
|
||||
uint16_t port = ntohs(*(uint16_t*)(peerData.s().c_str()+i+4));
|
||||
PeerHandle peer(new Peer(ipaddr, port));
|
||||
peers.push_back(peer);
|
||||
}
|
||||
|
|
|
@ -45,9 +45,9 @@ public:
|
|||
virtual ~CompactPeerListProcessor();
|
||||
|
||||
virtual void extractPeer
|
||||
(std::deque<SharedHandle<Peer> >& peers, const MetaEntry* peersEntry);
|
||||
(std::deque<SharedHandle<Peer> >& peers, const bencode::BDE& peerData);
|
||||
|
||||
virtual bool canHandle(const MetaEntry* peersEntry) const;
|
||||
virtual bool canHandle(const bencode::BDE& peerData) const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -35,10 +35,6 @@
|
|||
#include "DefaultBtAnnounce.h"
|
||||
#include "LogFactory.h"
|
||||
#include "Logger.h"
|
||||
#include "MetaFileUtil.h"
|
||||
#include "Dictionary.h"
|
||||
#include "List.h"
|
||||
#include "Data.h"
|
||||
#include "DelegatingPeerListProcessor.h"
|
||||
#include "Util.h"
|
||||
#include "prefs.h"
|
||||
|
@ -54,6 +50,7 @@
|
|||
#include "StringFormat.h"
|
||||
#include "A2STR.h"
|
||||
#include "Request.h"
|
||||
#include "bencode.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -200,48 +197,35 @@ void
|
|||
DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
|
||||
size_t trackerResponseLength)
|
||||
{
|
||||
SharedHandle<MetaEntry> entry(MetaFileUtil::bdecoding(trackerResponse,
|
||||
trackerResponseLength));
|
||||
const Dictionary* response = dynamic_cast<const Dictionary*>(entry.get());
|
||||
if(!response) {
|
||||
logger->debug("Now processing tracker response.");
|
||||
const bencode::BDE dict =
|
||||
bencode::decode(trackerResponse, trackerResponseLength);
|
||||
if(!dict.isDict()) {
|
||||
throw DlAbortEx(MSG_NULL_TRACKER_RESPONSE);
|
||||
}
|
||||
const Data* failureReasonData =
|
||||
dynamic_cast<const Data*>(response->get(BtAnnounce::FAILURE_REASON));
|
||||
if(failureReasonData) {
|
||||
const bencode::BDE& failure = dict[BtAnnounce::FAILURE_REASON];
|
||||
if(failure.isString()) {
|
||||
throw DlAbortEx
|
||||
(StringFormat(EX_TRACKER_FAILURE,
|
||||
failureReasonData->toString().c_str()).str());
|
||||
(StringFormat(EX_TRACKER_FAILURE, failure.s().c_str()).str());
|
||||
}
|
||||
const Data* warningMessageData =
|
||||
dynamic_cast<const Data*>(response->get(BtAnnounce::WARNING_MESSAGE));
|
||||
if(warningMessageData) {
|
||||
logger->warn(MSG_TRACKER_WARNING_MESSAGE,
|
||||
warningMessageData->toString().c_str());
|
||||
const bencode::BDE& warn = dict[BtAnnounce::WARNING_MESSAGE];
|
||||
if(warn.isString()) {
|
||||
logger->warn(MSG_TRACKER_WARNING_MESSAGE, warn.s().c_str());
|
||||
}
|
||||
const Data* trackerIdData =
|
||||
dynamic_cast<const Data*>(response->get(BtAnnounce::TRACKER_ID));
|
||||
if(trackerIdData) {
|
||||
trackerId = trackerIdData->toString();
|
||||
const bencode::BDE& tid = dict[BtAnnounce::TRACKER_ID];
|
||||
if(tid.isString()) {
|
||||
trackerId = tid.s();
|
||||
logger->debug("Tracker ID:%s", trackerId.c_str());
|
||||
}
|
||||
const Data* intervalData =
|
||||
dynamic_cast<const Data*>(response->get(BtAnnounce::INTERVAL));
|
||||
if(intervalData) {
|
||||
time_t t = intervalData->toInt();
|
||||
if(t > 0) {
|
||||
interval = intervalData->toInt();
|
||||
logger->debug("Interval:%d", interval);
|
||||
}
|
||||
const bencode::BDE& ival = dict[BtAnnounce::INTERVAL];
|
||||
if(ival.isInteger() && ival.i() > 0) {
|
||||
interval = ival.i();
|
||||
logger->debug("Interval:%d", interval);
|
||||
}
|
||||
const Data* minIntervalData =
|
||||
dynamic_cast<const Data*>(response->get(BtAnnounce::MIN_INTERVAL));
|
||||
if(minIntervalData) {
|
||||
time_t t = minIntervalData->toInt();
|
||||
if(t > 0) {
|
||||
minInterval = minIntervalData->toInt();
|
||||
logger->debug("Min interval:%d", minInterval);
|
||||
}
|
||||
const bencode::BDE& mival = dict[BtAnnounce::MIN_INTERVAL];
|
||||
if(mival.isInteger() && mival.i() > 0) {
|
||||
minInterval = mival.i();
|
||||
logger->debug("Min interval:%d", minInterval);
|
||||
if(minInterval > interval) {
|
||||
minInterval = interval;
|
||||
}
|
||||
|
@ -249,28 +233,25 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
|
|||
// Use interval as a minInterval if minInterval is not supplied.
|
||||
minInterval = interval;
|
||||
}
|
||||
const Data* completeData =
|
||||
dynamic_cast<const Data*>(response->get(BtAnnounce::COMPLETE));
|
||||
if(completeData) {
|
||||
complete = completeData->toInt();
|
||||
const bencode::BDE& comp = dict[BtAnnounce::COMPLETE];
|
||||
if(comp.isInteger()) {
|
||||
complete = comp.i();
|
||||
logger->debug("Complete:%d", complete);
|
||||
}
|
||||
const Data* incompleteData =
|
||||
dynamic_cast<const Data*>(response->get(BtAnnounce::INCOMPLETE));
|
||||
if(incompleteData) {
|
||||
incomplete = incompleteData->toInt();
|
||||
const bencode::BDE& incomp = dict[BtAnnounce::INCOMPLETE];
|
||||
if(incomp.isInteger()) {
|
||||
incomplete = incomp.i();
|
||||
logger->debug("Incomplete:%d", incomplete);
|
||||
}
|
||||
const MetaEntry* peersEntry = response->get(BtAnnounce::PEERS);
|
||||
if(peersEntry &&
|
||||
!btRuntime->isHalt() &&
|
||||
btRuntime->lessThanMinPeers()) {
|
||||
DelegatingPeerListProcessor proc;
|
||||
std::deque<SharedHandle<Peer> > peers;
|
||||
proc.extractPeer(peers, peersEntry);
|
||||
peerStorage->addPeer(peers);
|
||||
}
|
||||
if(!peersEntry) {
|
||||
const bencode::BDE& peerData = dict[BtAnnounce::PEERS];
|
||||
if(!peerData.isNone()) {
|
||||
if(!btRuntime->isHalt() && btRuntime->lessThanMinPeers()) {
|
||||
DelegatingPeerListProcessor proc;
|
||||
std::deque<SharedHandle<Peer> > peers;
|
||||
proc.extractPeer(peers, peerData);
|
||||
peerStorage->addPeer(peers);
|
||||
}
|
||||
} else {
|
||||
logger->info(MSG_NO_PEER_LIST_RECEIVED);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,12 +33,13 @@
|
|||
*/
|
||||
/* copyright --> */
|
||||
#include "DefaultBtContext.h"
|
||||
#include "MetaFileUtil.h"
|
||||
#include "Dictionary.h"
|
||||
#include "List.h"
|
||||
#include "Data.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
#include "DlAbortEx.h"
|
||||
#include "BencodeVisitor.h"
|
||||
#include "Util.h"
|
||||
#include "MessageDigestHelper.h"
|
||||
#include "a2netcompat.h"
|
||||
|
@ -51,10 +52,7 @@
|
|||
#include "PeerMessageUtil.h"
|
||||
#include "StringFormat.h"
|
||||
#include "A2STR.h"
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include "bencode.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -102,84 +100,67 @@ void DefaultBtContext::clear() {
|
|||
_private = false;
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractPieceHash(const unsigned char* hashData,
|
||||
size_t hashDataLength,
|
||||
size_t hashLength) {
|
||||
size_t numPieces = hashDataLength/hashLength;
|
||||
void DefaultBtContext::extractPieceHash(const std::string& hashData,
|
||||
size_t hashLength)
|
||||
{
|
||||
size_t numPieces = hashData.size()/hashLength;
|
||||
for(size_t i = 0; i < numPieces; i++) {
|
||||
pieceHashes.push_back(Util::toHex(&hashData[i*hashLength],
|
||||
pieceHashes.push_back(Util::toHex(hashData.data()+i*hashLength,
|
||||
hashLength));
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractFileEntries(const Dictionary* infoDic,
|
||||
void DefaultBtContext::extractFileEntries(const bencode::BDE& infoDict,
|
||||
const std::string& defaultName,
|
||||
const std::string& overrideName,
|
||||
const std::deque<std::string>& urlList) {
|
||||
const std::deque<std::string>& urlList)
|
||||
{
|
||||
if(overrideName.empty()) {
|
||||
const Data* nameData =
|
||||
dynamic_cast<const Data*>(infoDic->get(BtContext::C_NAME));
|
||||
if(nameData) {
|
||||
name = nameData->toString();
|
||||
const bencode::BDE& nameData = infoDict[BtContext::C_NAME];
|
||||
if(nameData.isString()) {
|
||||
name = nameData.s();
|
||||
} else {
|
||||
name = File(defaultName).getBasename()+".file";
|
||||
}
|
||||
} else {
|
||||
name = overrideName;
|
||||
}
|
||||
const List* files = dynamic_cast<const List*>(infoDic->get(BtContext::C_FILES));
|
||||
if(files) {
|
||||
const bencode::BDE& filesList = infoDict[BtContext::C_FILES];
|
||||
if(filesList.isList()) {
|
||||
uint64_t length = 0;
|
||||
off_t offset = 0;
|
||||
// multi-file mode
|
||||
fileMode = BtContext::MULTI;
|
||||
const std::deque<MetaEntry*>& metaList = files->getList();
|
||||
for(std::deque<MetaEntry*>::const_iterator itr = metaList.begin();
|
||||
itr != metaList.end(); itr++) {
|
||||
const Dictionary* fileDic = dynamic_cast<const Dictionary*>((*itr));
|
||||
if(!fileDic) {
|
||||
for(bencode::BDE::List::const_iterator itr = filesList.listBegin();
|
||||
itr != filesList.listEnd(); ++itr) {
|
||||
const bencode::BDE& fileDict = *itr;
|
||||
if(!fileDict.isDict()) {
|
||||
continue;
|
||||
}
|
||||
const Data* lengthData =
|
||||
dynamic_cast<const Data*>(fileDic->get(BtContext::C_LENGTH));
|
||||
if(lengthData) {
|
||||
length += lengthData->toLLInt();
|
||||
} else {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "file length").str());
|
||||
|
||||
const bencode::BDE& fileLengthData = fileDict[BtContext::C_LENGTH];
|
||||
if(!fileLengthData.isInteger()) {
|
||||
throw DlAbortEx(StringFormat(MSG_MISSING_BT_INFO,
|
||||
BtContext::C_LENGTH.c_str()).str());
|
||||
}
|
||||
const List* pathList =
|
||||
dynamic_cast<const List*>(fileDic->get(BtContext::C_PATH));
|
||||
if(!pathList) {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "file path list").str());
|
||||
length += fileLengthData.i();
|
||||
|
||||
const bencode::BDE& pathList = fileDict[BtContext::C_PATH];
|
||||
if(!pathList.isList() || pathList.empty()) {
|
||||
throw DlAbortEx("Path is empty.");
|
||||
}
|
||||
const std::deque<MetaEntry*>& paths = pathList->getList();
|
||||
std::string path;
|
||||
for(size_t i = 0; i < paths.size()-1; i++) {
|
||||
const Data* subpath = dynamic_cast<const Data*>(paths[i]);
|
||||
if(subpath) {
|
||||
path += subpath->toString()+"/";
|
||||
} else {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "file path element").str());
|
||||
}
|
||||
}
|
||||
const Data* lastPath = dynamic_cast<const Data*>(paths.back());
|
||||
if(lastPath) {
|
||||
path += lastPath->toString();
|
||||
} else {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "file path element").str());
|
||||
for(size_t i = 0; i < pathList.size()-1; ++i) {
|
||||
path += pathList[i].s()+"/";
|
||||
|
||||
}
|
||||
path += pathList[pathList.size()-1].s();
|
||||
|
||||
std::deque<std::string> uris;
|
||||
std::transform(urlList.begin(), urlList.end(), std::back_inserter(uris),
|
||||
std::bind2nd(std::plus<std::string>(), "/"+name+"/"+path));
|
||||
FileEntryHandle fileEntry(new FileEntry(path,
|
||||
lengthData->toLLInt(),
|
||||
offset,
|
||||
uris));
|
||||
FileEntryHandle fileEntry(new FileEntry(path, fileLengthData.i(),
|
||||
offset, uris));
|
||||
fileEntries.push_back(fileEntry);
|
||||
offset += fileEntry->getLength();
|
||||
}
|
||||
|
@ -187,91 +168,100 @@ void DefaultBtContext::extractFileEntries(const Dictionary* infoDic,
|
|||
} else {
|
||||
// single-file mode;
|
||||
fileMode = BtContext::SINGLE;
|
||||
const Data* length =
|
||||
dynamic_cast<const Data*>(infoDic->get(BtContext::C_LENGTH));
|
||||
if(length) {
|
||||
totalLength = length->toLLInt();
|
||||
} else {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "file length").str());
|
||||
const bencode::BDE& lengthData = infoDict[BtContext::C_LENGTH];
|
||||
if(!lengthData.isInteger()) {
|
||||
throw DlAbortEx(StringFormat(MSG_MISSING_BT_INFO,
|
||||
BtContext::C_LENGTH.c_str()).str());
|
||||
}
|
||||
totalLength = lengthData.i();
|
||||
FileEntryHandle fileEntry(new FileEntry(name, totalLength, 0, urlList));
|
||||
fileEntries.push_back(fileEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractAnnounce(const Data* announceData) {
|
||||
void DefaultBtContext::extractAnnounceURI(const bencode::BDE& announceData)
|
||||
{
|
||||
// Assumed announceData is string
|
||||
std::deque<std::string> urls;
|
||||
urls.push_back(Util::trim(announceData->toString()));
|
||||
urls.push_back(Util::trim(announceData.s()));
|
||||
announceTiers.push_back(AnnounceTierHandle(new AnnounceTier(urls)));
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractAnnounceList(const List* announceListData) {
|
||||
for(std::deque<MetaEntry*>::const_iterator itr = announceListData->getList().begin();
|
||||
itr != announceListData->getList().end(); itr++) {
|
||||
const List* elem = dynamic_cast<const List*>(*itr);
|
||||
if(!elem) {
|
||||
void DefaultBtContext::extractAnnounceList(const bencode::BDE& announceList)
|
||||
{
|
||||
// Assumed announceList is string
|
||||
for(bencode::BDE::List::const_iterator itr = announceList.listBegin();
|
||||
itr != announceList.listEnd(); ++itr) {
|
||||
const bencode::BDE& elemList = *itr;
|
||||
if(!elemList.isList()) {
|
||||
continue;
|
||||
}
|
||||
std::deque<std::string> urls;
|
||||
for(std::deque<MetaEntry*>::const_iterator elemItr = elem->getList().begin();
|
||||
elemItr != elem->getList().end(); elemItr++) {
|
||||
const Data* data = dynamic_cast<const Data*>(*elemItr);
|
||||
if(data) {
|
||||
urls.push_back(Util::trim(data->toString()));
|
||||
for(bencode::BDE::List::const_iterator elemItr = elemList.listBegin();
|
||||
elemItr != elemList.listEnd(); ++elemItr) {
|
||||
const bencode::BDE& url = (*elemItr);
|
||||
if(url.isString()) {
|
||||
urls.push_back(Util::trim(url.s()));
|
||||
}
|
||||
}
|
||||
if(urls.size()) {
|
||||
if(!urls.empty()) {
|
||||
AnnounceTierHandle tier(new AnnounceTier(urls));
|
||||
announceTiers.push_back(tier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractUrlList(std::deque<std::string>& uris,
|
||||
const MetaEntry* obj)
|
||||
void DefaultBtContext::extractAnnounce(const bencode::BDE& rootDict)
|
||||
{
|
||||
if(dynamic_cast<const List*>(obj)) {
|
||||
const List* urlList = reinterpret_cast<const List*>(obj);
|
||||
for(std::deque<MetaEntry*>::const_iterator itr = urlList->getList().begin();
|
||||
itr != urlList->getList().end(); ++itr) {
|
||||
const Data* data = dynamic_cast<const Data*>(*itr);
|
||||
if(data) {
|
||||
uris.push_back(data->toString());
|
||||
}
|
||||
const bencode::BDE& announceList = rootDict[BtContext::C_ANNOUNCE_LIST];
|
||||
if(announceList.isList()) {
|
||||
extractAnnounceList(announceList);
|
||||
} else {
|
||||
const bencode::BDE& announce = rootDict[BtContext::C_ANNOUNCE];
|
||||
if(announce.isString()) {
|
||||
extractAnnounceURI(announce);
|
||||
}
|
||||
} else if(dynamic_cast<const Data*>(obj)) {
|
||||
const Data* urlData = reinterpret_cast<const Data*>(obj);
|
||||
uris.push_back(urlData->toString());
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractNodes(const List* nodes)
|
||||
void DefaultBtContext::extractUrlList(std::deque<std::string>& uris,
|
||||
const bencode::BDE& bde)
|
||||
{
|
||||
|
||||
for(std::deque<MetaEntry*>::const_iterator i = nodes->getList().begin();
|
||||
i != nodes->getList().end(); ++i) {
|
||||
const List* addrPair = dynamic_cast<const List*>(*i);
|
||||
if(!addrPair || addrPair->getList().size() != 2) {
|
||||
if(bde.isList()) {
|
||||
for(bencode::BDE::List::const_iterator itr = bde.listBegin();
|
||||
itr != bde.listEnd(); ++itr) {
|
||||
if((*itr).isString()) {
|
||||
uris.push_back((*itr).s());
|
||||
}
|
||||
}
|
||||
} else if(bde.isString()) {
|
||||
uris.push_back(bde.s());
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractNodes(const bencode::BDE& nodesList)
|
||||
{
|
||||
if(!nodesList.isList()) {
|
||||
return;
|
||||
}
|
||||
for(bencode::BDE::List::const_iterator i = nodesList.listBegin();
|
||||
i != nodesList.listEnd(); ++i) {
|
||||
const bencode::BDE& addrPairList = (*i);
|
||||
if(!addrPairList.isList() || addrPairList.size() != 2) {
|
||||
continue;
|
||||
}
|
||||
const Data* hostname = dynamic_cast<const Data*>(addrPair->getList()[0]);
|
||||
if(!hostname) {
|
||||
const bencode::BDE& hostname = addrPairList[0];
|
||||
if(!hostname.isString()) {
|
||||
continue;
|
||||
}
|
||||
std::string h = hostname->toString();
|
||||
if(Util::trim(h).empty()) {
|
||||
if(Util::trim(hostname.s()).empty()) {
|
||||
continue;
|
||||
}
|
||||
const Data* port = dynamic_cast<const Data*>(addrPair->getList()[1]);
|
||||
if(!port) {
|
||||
const bencode::BDE& port = addrPairList[1];
|
||||
if(!port.isInteger() || !(0 < port.i() && port.i() < 65536)) {
|
||||
continue;
|
||||
}
|
||||
uint16_t p = port->toInt();
|
||||
if(p == 0) {
|
||||
continue;
|
||||
}
|
||||
_nodes.push_back(std::pair<std::string, uint16_t>(h, p));
|
||||
_nodes.push_back(std::pair<std::string, uint16_t>(hostname.s(), port.i()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,103 +270,78 @@ void DefaultBtContext::loadFromMemory(const unsigned char* content,
|
|||
const std::string& defaultName,
|
||||
const std::string& overrideName)
|
||||
{
|
||||
SharedHandle<MetaEntry> rootEntry(MetaFileUtil::bdecoding(content, length));
|
||||
const Dictionary* rootDic = dynamic_cast<const Dictionary*>(rootEntry.get());
|
||||
if(!rootDic) {
|
||||
throw DlAbortEx
|
||||
(StringFormat("torrent file does not contain a root dictionary .").str());
|
||||
}
|
||||
processRootDictionary(rootDic, defaultName, overrideName);
|
||||
processRootDictionary(bencode::decode(content, length), defaultName,
|
||||
overrideName);
|
||||
}
|
||||
|
||||
void DefaultBtContext::load(const std::string& torrentFile,
|
||||
const std::string& overrideName) {
|
||||
SharedHandle<MetaEntry> rootEntry(MetaFileUtil::parseMetaFile(torrentFile));
|
||||
const Dictionary* rootDic = dynamic_cast<const Dictionary*>(rootEntry.get());
|
||||
if(!rootDic) {
|
||||
throw DlAbortEx
|
||||
(StringFormat("torrent file does not contain a root dictionary .").str());
|
||||
}
|
||||
processRootDictionary(rootDic, torrentFile, overrideName);
|
||||
processRootDictionary(bencode::decodeFromFile(torrentFile), torrentFile,
|
||||
overrideName);
|
||||
}
|
||||
|
||||
void DefaultBtContext::processRootDictionary(const Dictionary* rootDic,
|
||||
void DefaultBtContext::processRootDictionary(const bencode::BDE& rootDict,
|
||||
const std::string& defaultName,
|
||||
const std::string& overrideName)
|
||||
{
|
||||
clear();
|
||||
const Dictionary* infoDic =
|
||||
dynamic_cast<const Dictionary*>(rootDic->get(BtContext::C_INFO));
|
||||
if(!infoDic) {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "info directory").str());
|
||||
if(!rootDict.isDict()) {
|
||||
throw DlAbortEx("torrent file does not contain a root dictionary.");
|
||||
}
|
||||
const bencode::BDE& infoDict = rootDict[BtContext::C_INFO];
|
||||
if(!infoDict.isDict()) {
|
||||
throw DlAbortEx(StringFormat(MSG_MISSING_BT_INFO,
|
||||
BtContext::C_INFO.c_str()).str());
|
||||
}
|
||||
// retrieve infoHash
|
||||
BencodeVisitor v;
|
||||
infoDic->accept(&v);
|
||||
std::string encodedInfoDict = bencode::encode(infoDict);
|
||||
MessageDigestHelper::digest(infoHash, INFO_HASH_LENGTH,
|
||||
MessageDigestContext::SHA1,
|
||||
v.getBencodedData().c_str(),
|
||||
v.getBencodedData().size());
|
||||
encodedInfoDict.data(),
|
||||
encodedInfoDict.size());
|
||||
infoHashString = Util::toHex(infoHash, INFO_HASH_LENGTH);
|
||||
// calculate the number of pieces
|
||||
const Data* pieceHashData =
|
||||
dynamic_cast<const Data*>(infoDic->get(BtContext::C_PIECES));
|
||||
if(!pieceHashData) {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "pieces").str());
|
||||
const bencode::BDE& piecesData = infoDict[BtContext::C_PIECES];
|
||||
if(!piecesData.isString()) {
|
||||
throw DlAbortEx(StringFormat(MSG_MISSING_BT_INFO,
|
||||
BtContext::C_PIECES.c_str()).str());
|
||||
}
|
||||
if(pieceHashData->getLen() == 0) {
|
||||
if(piecesData.s().empty()) {
|
||||
throw DlAbortEx("The length of piece hash is 0.");
|
||||
}
|
||||
numPieces = pieceHashData->getLen()/PIECE_HASH_LENGTH;
|
||||
numPieces = piecesData.s().size()/PIECE_HASH_LENGTH;
|
||||
if(numPieces == 0) {
|
||||
throw DlAbortEx("The number of pieces is 0.");
|
||||
}
|
||||
// retrieve piece length
|
||||
const Data* pieceLengthData =
|
||||
dynamic_cast<const Data*>(infoDic->get(BtContext::C_PIECE_LENGTH));
|
||||
if(!pieceLengthData) {
|
||||
throw DlAbortEx
|
||||
(StringFormat(MSG_SOMETHING_MISSING_IN_TORRENT, "piece length").str());
|
||||
const bencode::BDE& pieceLengthData = infoDict[BtContext::C_PIECE_LENGTH];
|
||||
if(!pieceLengthData.isInteger()) {
|
||||
throw DlAbortEx(StringFormat(MSG_MISSING_BT_INFO,
|
||||
BtContext::C_PIECE_LENGTH.c_str()).str());
|
||||
}
|
||||
pieceLength = pieceLengthData->toInt();
|
||||
pieceLength = pieceLengthData.i();
|
||||
// retrieve piece hashes
|
||||
extractPieceHash(pieceHashData->getData(), pieceHashData->getLen(),
|
||||
PIECE_HASH_LENGTH);
|
||||
const Data* privateFlag =
|
||||
dynamic_cast<const Data*>(infoDic->get(BtContext::C_PRIVATE));
|
||||
if(privateFlag) {
|
||||
if(privateFlag->toString() == BtContext::C_PRIVATE_ON) {
|
||||
_private = true;
|
||||
}
|
||||
extractPieceHash(piecesData.s(), PIECE_HASH_LENGTH);
|
||||
// private flag
|
||||
const bencode::BDE& privateData = infoDict[BtContext::C_PRIVATE];
|
||||
if(privateData.isInteger()) {
|
||||
_private = (privateData.i() == 1);
|
||||
}
|
||||
// retrieve uri-list.
|
||||
// This implemantation obeys HTTP-Seeding specification:
|
||||
// see http://www.getright.com/seedtorrent.html
|
||||
std::deque<std::string> urlList;
|
||||
extractUrlList(urlList, rootDic->get(BtContext::C_URL_LIST));
|
||||
extractUrlList(urlList, rootDict[BtContext::C_URL_LIST]);
|
||||
|
||||
// retrieve file entries
|
||||
extractFileEntries(infoDic, defaultName, overrideName, urlList);
|
||||
extractFileEntries(infoDict, defaultName, overrideName, urlList);
|
||||
if((totalLength+pieceLength-1)/pieceLength != numPieces) {
|
||||
throw DlAbortEx("Too few/many piece hash.");
|
||||
}
|
||||
// retrieve announce
|
||||
const Data* announceData =
|
||||
dynamic_cast<const Data*>(rootDic->get(BtContext::C_ANNOUNCE));
|
||||
const List* announceListData =
|
||||
dynamic_cast<const List*>(rootDic->get(BtContext::C_ANNOUNCE_LIST));
|
||||
if(announceListData) {
|
||||
extractAnnounceList(announceListData);
|
||||
} else if(announceData) {
|
||||
extractAnnounce(announceData);
|
||||
}
|
||||
extractAnnounce(rootDict);
|
||||
// retrieve nodes
|
||||
const List* nodes =
|
||||
dynamic_cast<const List*>(rootDic->get(BtContext::C_NODES));
|
||||
if(nodes) {
|
||||
extractNodes(nodes);
|
||||
}
|
||||
extractNodes(rootDict[BtContext::C_NODES]);
|
||||
}
|
||||
|
||||
const std::string& DefaultBtContext::getPieceHash(size_t index) const {
|
||||
|
|
|
@ -36,17 +36,17 @@
|
|||
#define _D_DEFAULT_BT_CONTEXT_H_
|
||||
|
||||
#include "BtContext.h"
|
||||
#include "A2STR.h"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class Randomizer;
|
||||
class Logger;
|
||||
class MetaEntry;
|
||||
class Dictionary;
|
||||
class List;
|
||||
class Data;
|
||||
|
||||
namespace bencode {
|
||||
class BDE;
|
||||
}
|
||||
|
||||
#define INFO_HASH_LENGTH 20
|
||||
#define PIECE_HASH_LENGTH 20
|
||||
|
@ -73,21 +73,20 @@ private:
|
|||
Logger* _logger;
|
||||
|
||||
void clear();
|
||||
void extractPieceHash(const unsigned char* hashData,
|
||||
size_t hashDataLength,
|
||||
size_t hashLength);
|
||||
void extractFileEntries(const Dictionary* infoDic,
|
||||
void extractPieceHash(const std::string& hashData, size_t hashLength);
|
||||
void extractFileEntries(const bencode::BDE& infoDic,
|
||||
const std::string& defaultName,
|
||||
const std::string& overrideName,
|
||||
const std::deque<std::string>& urlList);
|
||||
void extractAnnounce(const Data* announceData);
|
||||
void extractAnnounceList(const List* announceListData);
|
||||
void extractAnnounceURI(const bencode::BDE& announceData);
|
||||
void extractAnnounceList(const bencode::BDE& announceListData);
|
||||
void extractAnnounce(const bencode::BDE& rootDict);
|
||||
|
||||
void extractUrlList(std::deque<std::string>& uris, const MetaEntry* obj);
|
||||
void extractUrlList(std::deque<std::string>& uris, const bencode::BDE& obj);
|
||||
|
||||
void extractNodes(const List* nodes);
|
||||
void extractNodes(const bencode::BDE& nodes);
|
||||
|
||||
void processRootDictionary(const Dictionary* rootDic,
|
||||
void processRootDictionary(const bencode::BDE& rootDic,
|
||||
const std::string& defaultName,
|
||||
const std::string& overrideName);
|
||||
|
||||
|
|
|
@ -34,9 +34,7 @@
|
|||
/* copyright --> */
|
||||
#include "DefaultPeerListProcessor.h"
|
||||
#include "Peer.h"
|
||||
#include "List.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Data.h"
|
||||
#include "bencode.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -48,31 +46,30 @@ DefaultPeerListProcessor::DefaultPeerListProcessor() {}
|
|||
|
||||
DefaultPeerListProcessor::~DefaultPeerListProcessor() {}
|
||||
|
||||
bool DefaultPeerListProcessor::canHandle(const MetaEntry* peersEntry) const {
|
||||
const List* peersList = dynamic_cast<const List*>(peersEntry);
|
||||
return peersList != 0;
|
||||
bool DefaultPeerListProcessor::canHandle(const bencode::BDE& peerData) const
|
||||
{
|
||||
return peerData.isList();
|
||||
}
|
||||
|
||||
void DefaultPeerListProcessor::extractPeer
|
||||
(std::deque<SharedHandle<Peer> >& peers, const MetaEntry* peersEntry)
|
||||
(std::deque<SharedHandle<Peer> >& peers, const bencode::BDE& peerData)
|
||||
{
|
||||
const List* peersList = dynamic_cast<const List*>(peersEntry);
|
||||
if(!peersList) {
|
||||
if(!canHandle(peerData)) {
|
||||
return;
|
||||
}
|
||||
const std::deque<MetaEntry*>& metaList = peersList->getList();
|
||||
for(std::deque<MetaEntry*>::const_iterator itr = metaList.begin();
|
||||
itr != metaList.end(); itr++) {
|
||||
const Dictionary* peerDic = dynamic_cast<const Dictionary*>(*itr);
|
||||
if(!peerDic) {
|
||||
break;
|
||||
}
|
||||
const Data* ip = dynamic_cast<const Data*>(peerDic->get(IP));
|
||||
const Data* port = dynamic_cast<const Data*>(peerDic->get(PORT));
|
||||
if(!ip || !port || !port->isNumber()) {
|
||||
for(bencode::BDE::List::const_iterator itr = peerData.listBegin();
|
||||
itr != peerData.listEnd(); ++itr) {
|
||||
const bencode::BDE& peerDict = *itr;
|
||||
if(!peerDict.isDict()) {
|
||||
continue;
|
||||
}
|
||||
PeerHandle peer(new Peer(ip->toString(), port->toInt()));
|
||||
const bencode::BDE& ip = peerDict[IP];
|
||||
const bencode::BDE& port = peerDict[PORT];
|
||||
if(!ip.isString() || !port.isInteger() ||
|
||||
!(0 < port.i() && port.i() < 65536)) {
|
||||
continue;
|
||||
}
|
||||
PeerHandle peer(new Peer(ip.s(), port.i()));
|
||||
peers.push_back(peer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,9 +50,9 @@ public:
|
|||
virtual ~DefaultPeerListProcessor();
|
||||
|
||||
virtual void extractPeer
|
||||
(std::deque<SharedHandle<Peer> >& peers, const MetaEntry* peersEntry);
|
||||
(std::deque<SharedHandle<Peer> >& peers, const bencode::BDE& peerData);
|
||||
|
||||
virtual bool canHandle(const MetaEntry* peersEntry) const;
|
||||
virtual bool canHandle(const bencode::BDE& peerData) const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -32,10 +32,13 @@
|
|||
*/
|
||||
/* copyright --> */
|
||||
#include "DelegatingPeerListProcessor.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "DefaultPeerListProcessor.h"
|
||||
#include "CompactPeerListProcessor.h"
|
||||
#include "Peer.h"
|
||||
#include <algorithm>
|
||||
#include "bencode.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -54,22 +57,23 @@ DelegatingPeerListProcessor::DelegatingPeerListProcessor()
|
|||
DelegatingPeerListProcessor::~DelegatingPeerListProcessor() {}
|
||||
|
||||
void DelegatingPeerListProcessor::extractPeer
|
||||
(std::deque<SharedHandle<Peer> >& peers, const MetaEntry* peersEntry)
|
||||
(std::deque<SharedHandle<Peer> >& peers, const bencode::BDE& peerData)
|
||||
{
|
||||
for(std::deque<SharedHandle<PeerListProcessor> >::iterator itr = processors.begin();
|
||||
itr != processors.end(); itr++) {
|
||||
for(std::deque<SharedHandle<PeerListProcessor> >::iterator itr =
|
||||
processors.begin(); itr != processors.end(); ++itr) {
|
||||
PeerListProcessorHandle processor = *itr;
|
||||
if(processor->canHandle(peersEntry)) {
|
||||
processor->extractPeer(peers, peersEntry);
|
||||
if(processor->canHandle(peerData)) {
|
||||
processor->extractPeer(peers, peerData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DelegatingPeerListProcessor::canHandle(const MetaEntry* peersEntry) const {
|
||||
for(std::deque<SharedHandle<PeerListProcessor> >::const_iterator itr = processors.begin();
|
||||
itr != processors.end(); itr++) {
|
||||
if((*itr)->canHandle(peersEntry)) {
|
||||
bool DelegatingPeerListProcessor::canHandle(const bencode::BDE& peerData) const
|
||||
{
|
||||
for(std::deque<SharedHandle<PeerListProcessor> >::const_iterator itr =
|
||||
processors.begin(); itr != processors.end(); ++itr) {
|
||||
if((*itr)->canHandle(peerData)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,9 @@ public:
|
|||
virtual ~DelegatingPeerListProcessor();
|
||||
|
||||
virtual void extractPeer
|
||||
(std::deque<SharedHandle<Peer> >& peers, const MetaEntry* peersEntry);
|
||||
(std::deque<SharedHandle<Peer> >& peers, const bencode::BDE& peerData);
|
||||
|
||||
virtual bool canHandle(const MetaEntry* peersEntry) const;
|
||||
virtual bool canHandle(const bencode::BDE& peerData) const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -36,22 +36,26 @@
|
|||
#define _D_PEER_LIST_PROCESSOR_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "SharedHandle.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include "SharedHandle.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class MetaEntry;
|
||||
class Peer;
|
||||
namespace bencode {
|
||||
class BDE;
|
||||
}
|
||||
|
||||
class PeerListProcessor {
|
||||
public:
|
||||
virtual ~PeerListProcessor() {}
|
||||
|
||||
virtual void extractPeer
|
||||
(std::deque<SharedHandle<Peer> >& peers, const MetaEntry* peersEntry) = 0;
|
||||
(std::deque<SharedHandle<Peer> >& peers, const bencode::BDE& peerData) = 0;
|
||||
|
||||
virtual bool canHandle(const MetaEntry* peersEntry) const = 0;
|
||||
virtual bool canHandle(const bencode::BDE& peerData) const = 0;
|
||||
};
|
||||
|
||||
typedef SharedHandle<PeerListProcessor> PeerListProcessorHandle;
|
||||
|
|
|
@ -34,17 +34,14 @@
|
|||
/* copyright --> */
|
||||
#include "UTPexExtensionMessage.h"
|
||||
#include "Peer.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Data.h"
|
||||
#include "BencodeVisitor.h"
|
||||
#include "Util.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "PeerStorage.h"
|
||||
#include "CompactPeerListProcessor.h"
|
||||
#include "MetaFileUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "message.h"
|
||||
#include "StringFormat.h"
|
||||
#include "bencode.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -60,19 +57,20 @@ UTPexExtensionMessage::~UTPexExtensionMessage() {}
|
|||
|
||||
std::string UTPexExtensionMessage::getBencodedData()
|
||||
{
|
||||
SharedHandle<Dictionary> d(new Dictionary());
|
||||
std::pair<std::string, std::string> freshPeerPair = createCompactPeerListAndFlag(_freshPeers);
|
||||
std::pair<std::string, std::string> droppedPeerPair = createCompactPeerListAndFlag(_droppedPeers);
|
||||
d->put("added", new Data(freshPeerPair.first));
|
||||
d->put("added.f", new Data(freshPeerPair.second));
|
||||
d->put("dropped", new Data(droppedPeerPair.first));
|
||||
std::pair<std::string, std::string> freshPeerPair =
|
||||
createCompactPeerListAndFlag(_freshPeers);
|
||||
std::pair<std::string, std::string> droppedPeerPair =
|
||||
createCompactPeerListAndFlag(_droppedPeers);
|
||||
|
||||
BencodeVisitor v;
|
||||
d->accept(&v);
|
||||
return v.getBencodedData();
|
||||
bencode::BDE dict = bencode::BDE::dict();
|
||||
dict["added"] = freshPeerPair.first;
|
||||
dict["added.f"] = freshPeerPair.second;
|
||||
dict["dropped"] = droppedPeerPair.first;
|
||||
return bencode::encode(dict);
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> UTPexExtensionMessage::createCompactPeerListAndFlag(const Peers& peers)
|
||||
std::pair<std::string, std::string>
|
||||
UTPexExtensionMessage::createCompactPeerListAndFlag(const Peers& peers)
|
||||
{
|
||||
std::string addrstring;
|
||||
std::string flagstring;
|
||||
|
@ -173,19 +171,16 @@ UTPexExtensionMessage::create(const unsigned char* data, size_t len)
|
|||
EXTENSION_NAME.c_str(), len).str());
|
||||
}
|
||||
UTPexExtensionMessageHandle msg(new UTPexExtensionMessage(*data));
|
||||
SharedHandle<MetaEntry> root(MetaFileUtil::bdecoding(data+1, len-1));
|
||||
if(root.isNull()) {
|
||||
return msg;
|
||||
}
|
||||
const Dictionary* d = dynamic_cast<const Dictionary*>(root.get());
|
||||
if(d) {
|
||||
|
||||
const bencode::BDE dict = bencode::decode(data+1, len-1);
|
||||
if(dict.isDict()) {
|
||||
CompactPeerListProcessor proc;
|
||||
const Data* added = dynamic_cast<const Data*>(d->get("added"));
|
||||
if(added) {
|
||||
const bencode::BDE& added = dict["added"];
|
||||
if(added.isString()) {
|
||||
proc.extractPeer(msg->_freshPeers, added);
|
||||
}
|
||||
const Data* dropped = dynamic_cast<const Data*>(d->get("dropped"));
|
||||
if(dropped) {
|
||||
const bencode::BDE& dropped = dict["dropped"];
|
||||
if(dropped.isString()) {
|
||||
proc.extractPeer(msg->_droppedPeers, dropped);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,11 @@ public:
|
|||
|
||||
static std::string toHex(const unsigned char* src, size_t len);
|
||||
|
||||
static std::string toHex(const char* src, size_t len)
|
||||
{
|
||||
return toHex(reinterpret_cast<const unsigned char*>(src), len);
|
||||
}
|
||||
|
||||
static std::string toHex(const std::string& src)
|
||||
{
|
||||
return toHex(reinterpret_cast<const unsigned char*>(src.c_str()), src.size());
|
||||
|
|
|
@ -136,7 +136,7 @@
|
|||
#define MSG_TOO_SMALL_PAYLOAD_SIZE _("Too small payload size for %s, size=%d.")
|
||||
#define MSG_REMOVED_DEFUNCT_CONTROL_FILE _("Removed the defunct control file %s because the download file %s doesn't exist.")
|
||||
#define MSG_SHARE_RATIO_REPORT _("Your share ratio was %.1f, uploaded/downloaded=%sB/%sB")
|
||||
#define MSG_SOMETHING_MISSING_IN_TORRENT _("Missing %s in torrent metainfo.")
|
||||
#define MSG_MISSING_BT_INFO _("Missing %s in torrent metainfo.")
|
||||
#define MSG_NULL_TRACKER_RESPONSE _("Tracker returned null data.")
|
||||
#define MSG_WINSOCK_INIT_FAILD _("Windows socket library initialization failed")
|
||||
#define MSG_TIME_HAS_PASSED _("%d second(s) has passed. Stopping application.")
|
||||
|
|
|
@ -372,7 +372,7 @@ void DefaultBtContextTest::testGetNodes()
|
|||
std::string memory =
|
||||
"d5:nodesl"
|
||||
"l11:192.168.0.1i6881ee"
|
||||
"l11:192.168.0.24:6882e"
|
||||
"l11:192.168.0.2i6882ee"
|
||||
"e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
|
||||
"12:piece lengthi262144e"
|
||||
"6:pieces20:AAAAAAAAAAAAAAAAAAAA"
|
||||
|
@ -393,7 +393,7 @@ void DefaultBtContextTest::testGetNodes()
|
|||
std::string memory =
|
||||
"d5:nodesl"
|
||||
"l1: i6881ee"
|
||||
"l11:192.168.0.24:6882e"
|
||||
"l11:192.168.0.2i6882ee"
|
||||
"e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
|
||||
"12:piece lengthi262144e"
|
||||
"6:pieces20:AAAAAAAAAAAAAAAAAAAA"
|
||||
|
@ -412,7 +412,7 @@ void DefaultBtContextTest::testGetNodes()
|
|||
std::string memory =
|
||||
"d5:nodesl"
|
||||
"l11:192.168.0.11:xe"
|
||||
"l11:192.168.0.24:6882e"
|
||||
"l11:192.168.0.2i6882ee"
|
||||
"e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
|
||||
"12:piece lengthi262144e"
|
||||
"6:pieces20:AAAAAAAAAAAAAAAAAAAA"
|
||||
|
@ -431,7 +431,7 @@ void DefaultBtContextTest::testGetNodes()
|
|||
std::string memory =
|
||||
"d5:nodesl"
|
||||
"l11:192.168.0.1e"
|
||||
"l11:192.168.0.24:6882e"
|
||||
"l11:192.168.0.2i6882ee"
|
||||
"e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
|
||||
"12:piece lengthi262144e"
|
||||
"6:pieces20:AAAAAAAAAAAAAAAAAAAA"
|
||||
|
@ -466,7 +466,7 @@ void DefaultBtContextTest::testGetNodes()
|
|||
std::string memory =
|
||||
"d5:nodesl"
|
||||
"ll11:192.168.0.1i6881eee"
|
||||
"l11:192.168.0.24:6882e"
|
||||
"l11:192.168.0.2i6882ee"
|
||||
"e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
|
||||
"12:piece lengthi262144e"
|
||||
"6:pieces20:AAAAAAAAAAAAAAAAAAAA"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "DefaultPeerListProcessor.h"
|
||||
#include "MetaFileUtil.h"
|
||||
#include "Exception.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Peer.h"
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
#include "Exception.h"
|
||||
#include "Peer.h"
|
||||
#include "bencode.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class DefaultPeerListProcessorTest:public CppUnit::TestFixture {
|
||||
|
@ -30,13 +31,12 @@ void DefaultPeerListProcessorTest::testExtractPeer() {
|
|||
DefaultPeerListProcessor proc;
|
||||
std::string peersString = "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-000000000000004:porti2006eeee";
|
||||
|
||||
SharedHandle<Dictionary> dic
|
||||
(dynamic_cast<Dictionary*>(MetaFileUtil::bdecoding(peersString)));
|
||||
const bencode::BDE dict = bencode::decode(peersString);
|
||||
|
||||
CPPUNIT_ASSERT(proc.canHandle(dic->get("peers")));
|
||||
CPPUNIT_ASSERT(proc.canHandle(dict["peers"]));
|
||||
|
||||
std::deque<SharedHandle<Peer> > peers;
|
||||
proc.extractPeer(peers, dic->get("peers"));
|
||||
proc.extractPeer(peers, dict["peers"]);
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
|
||||
SharedHandle<Peer> peer = *peers.begin();
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->ipaddr);
|
||||
|
@ -45,17 +45,16 @@ void DefaultPeerListProcessorTest::testExtractPeer() {
|
|||
|
||||
void DefaultPeerListProcessorTest::testExtract2Peers() {
|
||||
DefaultPeerListProcessor proc;
|
||||
std::string peersString = "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-000000000000004:porti2006eed2:ip11:192.168.0.27:peer id20:aria2-000000000000004:porti2007eeee";
|
||||
std::string peersString = "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-000000000000004:porti65535eed2:ip11:192.168.0.27:peer id20:aria2-000000000000004:porti2007eeee";
|
||||
|
||||
SharedHandle<Dictionary> dic
|
||||
(dynamic_cast<Dictionary*>(MetaFileUtil::bdecoding(peersString)));
|
||||
const bencode::BDE dict = bencode::decode(peersString);
|
||||
|
||||
std::deque<SharedHandle<Peer> > peers;
|
||||
proc.extractPeer(peers, dic->get("peers"));
|
||||
proc.extractPeer(peers, dict["peers"]);
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
|
||||
SharedHandle<Peer> peer = *peers.begin();
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)2006, peer->port);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)65535, peer->port);
|
||||
|
||||
peer = *(peers.begin()+1);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peer->ipaddr);
|
||||
|
|
Loading…
Reference in New Issue