2009-11-21 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Initial support of Extension for Peers to Send Metadata
	Files(BEP9). Currently aria2 only serves metadata and cannot get
	metadata from swarm.
	* src/BtConstants.h
	* src/DefaultBtInteractive.cc
	* src/DefaultExtensionMessageFactory.cc
	* src/DefaultExtensionMessageFactory.h
	* src/ExtensionMessage.h
	* src/ExtensionMessageRegistry.h
	* src/HandshakeExtensionMessage.cc
	* src/HandshakeExtensionMessage.h
	* src/Makefile.am
	* src/PeerConnection.h
	* src/PeerInteractionCommand.cc
	* src/UTMetadataDataExtensionMessage.cc
	* src/UTMetadataDataExtensionMessage.h
	* src/UTMetadataExtensionMessage.cc
	* src/UTMetadataExtensionMessage.h
	* src/UTMetadataRejectExtensionMessage.cc
	* src/UTMetadataRejectExtensionMessage.h
	* src/UTMetadataRequestExtensionMessage.cc
	* src/UTMetadataRequestExtensionMessage.h
	* src/bittorrent_helper.cc
	* src/bittorrent_helper.h
	* test/BittorrentHelperTest.cc
	* test/DefaultExtensionMessageFactoryTest.cc
	* test/HandshakeExtensionMessageTest.cc
	* test/Makefile.am
	* test/UTMetadataDataExtensionMessageTest.cc
	* test/UTMetadataRejectExtensionMessageTest.cc
	* test/UTMetadataRequestExtensionMessageTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2009-11-20 15:42:25 +00:00
parent 2764b6739d
commit 93968c4fa5
31 changed files with 1262 additions and 32 deletions

View File

@ -1,3 +1,37 @@
2009-11-21 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Initial support of Extension for Peers to Send Metadata
Files(BEP9). Currently aria2 only serves metadata and cannot get
metadata from swarm.
* src/BtConstants.h
* src/DefaultBtInteractive.cc
* src/DefaultExtensionMessageFactory.cc
* src/DefaultExtensionMessageFactory.h
* src/ExtensionMessage.h
* src/ExtensionMessageRegistry.h
* src/HandshakeExtensionMessage.cc
* src/HandshakeExtensionMessage.h
* src/Makefile.am
* src/PeerConnection.h
* src/PeerInteractionCommand.cc
* src/UTMetadataDataExtensionMessage.cc
* src/UTMetadataDataExtensionMessage.h
* src/UTMetadataExtensionMessage.cc
* src/UTMetadataExtensionMessage.h
* src/UTMetadataRejectExtensionMessage.cc
* src/UTMetadataRejectExtensionMessage.h
* src/UTMetadataRequestExtensionMessage.cc
* src/UTMetadataRequestExtensionMessage.h
* src/bittorrent_helper.cc
* src/bittorrent_helper.h
* test/BittorrentHelperTest.cc
* test/DefaultExtensionMessageFactoryTest.cc
* test/HandshakeExtensionMessageTest.cc
* test/Makefile.am
* test/UTMetadataDataExtensionMessageTest.cc
* test/UTMetadataRejectExtensionMessageTest.cc
* test/UTMetadataRequestExtensionMessageTest.cc
2009-11-21 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Cancel segment in prepareForRetry() because there is a chance that

View File

@ -58,4 +58,6 @@ typedef std::map<std::string, uint8_t> Extensions;
// Upper Bound of the number of outstanding request
#define UB_MAX_OUTSTANDING_REQUEST 24
#define METADATA_PIECE_SIZE (16*1024)
#endif // _D_BT_CONSTANTS_

View File

@ -167,7 +167,10 @@ void DefaultBtInteractive::addHandshakeExtendedMessageToQueue()
m->setClientVersion(CLIENT_ARIA2);
m->setTCPPort(_btRuntime->getListenPort());
m->setExtensions(_extensionMessageRegistry->getExtensions());
const BDE& attrs = _downloadContext->getAttribute(bittorrent::BITTORRENT);
if(attrs.containsKey(bittorrent::METADATA)) {
m->setMetadataSize(attrs[bittorrent::METADATA_SIZE].i());
}
SharedHandle<BtMessage> msg = messageFactory->createBtExtendedMessage(m);
dispatcher->addMessageToQueue(msg);
}

View File

@ -42,6 +42,14 @@
#include "StringFormat.h"
#include "PeerStorage.h"
#include "ExtensionMessageRegistry.h"
#include "DownloadContext.h"
#include "BtMessageDispatcher.h"
#include "BtMessageFactory.h"
#include "UTMetadataRequestExtensionMessage.h"
#include "UTMetadataDataExtensionMessage.h"
#include "UTMetadataRejectExtensionMessage.h"
#include "message.h"
#include "bencode.h"
namespace aria2 {
@ -65,6 +73,7 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
// handshake
HandshakeExtensionMessageHandle m = HandshakeExtensionMessage::create(data, length);
m->setPeer(_peer);
m->setDownloadContext(_dctx);
return m;
} else {
std::string extensionName = _registry->getExtensionName(extensionMessageID);
@ -79,6 +88,75 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
UTPexExtensionMessage::create(data, length);
m->setPeerStorage(_peerStorage);
return m;
} else if(extensionName == "ut_metadata") {
if(length == 0) {
throw DL_ABORT_EX(StringFormat(MSG_TOO_SMALL_PAYLOAD_SIZE,
"ut_metadata", length).str());
}
std::string listdata;
listdata += 'l';
listdata += std::string(&data[1], &data[length]);
listdata += 'e';
const BDE& list = bencode::decode(listdata);
if(!list.isList() || list.empty()) {
throw DL_ABORT_EX("Bad ut_metadata");
}
const BDE& dict = list[0];
if(!dict.isDict()) {
throw DL_ABORT_EX("Bad ut_metadata: dictionary not found");
}
const BDE& msgType = dict["msg_type"];
if(!msgType.isInteger()) {
throw DL_ABORT_EX("Bad ut_metadata: msg_type not found");
}
const BDE& index = dict["piece"];
if(!index.isInteger()) {
throw DL_ABORT_EX("Bad ut_metadata: piece not found");
}
switch(msgType.i()) {
case 0: {
SharedHandle<UTMetadataRequestExtensionMessage> m
(new UTMetadataRequestExtensionMessage(extensionMessageID));
m->setIndex(index.i());
m->setDownloadContext(_dctx);
m->setPeer(_peer);
m->setBtMessageFactory(_messageFactory);
m->setBtMessageDispatcher(_dispatcher);
return m;
}
case 1: {
if(list.size() != 2) {
throw DL_ABORT_EX("Bad ut_metadata data: data not found");
}
const BDE& pieceData = list[1];
if(!pieceData.isString()) {
throw DL_ABORT_EX("Bad ut_metadata data: data is not string");
}
const BDE& totalSize = dict["total_size"];
if(!totalSize.isInteger()) {
throw DL_ABORT_EX("Bad ut_metadata data: total_size not found");
}
SharedHandle<UTMetadataDataExtensionMessage> m
(new UTMetadataDataExtensionMessage(extensionMessageID));
m->setIndex(index.i());
m->setTotalSize(totalSize.i());
m->setData(pieceData.s());
// set tracker
// set piecestorage
return m;
}
case 2: {
SharedHandle<UTMetadataRejectExtensionMessage> m
(new UTMetadataRejectExtensionMessage(extensionMessageID));
m->setIndex(index.i());
// set tracker if disconnecing peer on receive.
return m;
}
default:
throw DL_ABORT_EX(StringFormat("Bad ut_metadata: unknown msg_type=%u",
msgType.i()).str());
}
} else {
throw DL_ABORT_EX
(StringFormat("Unsupported extension message received. extensionMessageID=%u, extensionName=%s",

View File

@ -43,6 +43,9 @@ class PeerStorage;
class Peer;
class Logger;
class ExtensionMessageRegistry;
class DownloadContext;
class BtMessageFactory;
class BtMessageDispatcher;
class DefaultExtensionMessageFactory:public ExtensionMessageFactory {
private:
@ -52,6 +55,12 @@ private:
SharedHandle<ExtensionMessageRegistry> _registry;
SharedHandle<DownloadContext> _dctx;
WeakHandle<BtMessageFactory> _messageFactory;
WeakHandle<BtMessageDispatcher> _dispatcher;
Logger* _logger;
public:
@ -75,6 +84,21 @@ public:
{
_registry = registry;
}
void setDownloadContext(const SharedHandle<DownloadContext>& dctx)
{
_dctx = dctx;
}
void setBtMessageFactory(const WeakHandle<BtMessageFactory>& factory)
{
_messageFactory = factory;
}
void setBtMessageDispatcher(const WeakHandle<BtMessageDispatcher>& disp)
{
_dispatcher = disp;
}
};
typedef SharedHandle<DefaultExtensionMessageFactory> DefaultExtensionMessageFactoryHandle;

View File

@ -36,9 +36,11 @@
#define _D_EXTENSION_MESSAGE_H_
#include "common.h"
#include "SharedHandle.h"
#include <string>
#include "SharedHandle.h"
namespace aria2 {
class ExtensionMessage {
public:

View File

@ -51,6 +51,8 @@ public:
ExtensionMessageRegistry()
{
_extensions["ut_pex"] = 8;
// http://www.bittorrent.org/beps/bep_0009.html
_extensions["ut_metadata"] = 9;
}
const Extensions& getExtensions() const

View File

@ -2,7 +2,7 @@
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -41,6 +41,8 @@
#include "message.h"
#include "StringFormat.h"
#include "bencode.h"
#include "DownloadContext.h"
#include "bittorrent_helper.h"
namespace aria2 {
@ -48,6 +50,7 @@ const std::string HandshakeExtensionMessage::EXTENSION_NAME = "handshake";
HandshakeExtensionMessage::HandshakeExtensionMessage():
_tcpPort(0),
_metadataSize(0),
_logger(LogFactory::getInstance()) {}
HandshakeExtensionMessage::~HandshakeExtensionMessage() {}
@ -68,6 +71,9 @@ std::string HandshakeExtensionMessage::getBencodedData()
extDict[vt.first] = vt.second;
}
dict["m"] = extDict;
if(_metadataSize) {
dict["metadata_size"] = _metadataSize;
}
return bencode::encode(dict);
}
@ -80,6 +86,9 @@ std::string HandshakeExtensionMessage::toString() const
if(_tcpPort > 0) {
strappend(s, ", tcpPort=", util::uitos(_tcpPort));
}
if(_metadataSize) {
strappend(s, ", metadataSize=", util::uitos(_metadataSize));
}
for(std::map<std::string, uint8_t>::const_iterator itr = _extensions.begin();
itr != _extensions.end(); ++itr) {
const std::map<std::string, uint8_t>::value_type& vt = *itr;
@ -99,6 +108,12 @@ void HandshakeExtensionMessage::doReceivedAction()
const std::map<std::string, uint8_t>::value_type& vt = *itr;
_peer->setExtension(vt.first, vt.second);
}
if(_metadataSize > 0) {
BDE& attrs = _dctx->getAttribute(bittorrent::BITTORRENT);
if(!attrs.containsKey(bittorrent::METADATA_SIZE)) {
attrs[bittorrent::METADATA_SIZE] = _metadataSize;
}
}
}
void HandshakeExtensionMessage::setPeer(const PeerHandle& peer)
@ -148,6 +163,11 @@ HandshakeExtensionMessage::create(const unsigned char* data, size_t length)
}
}
}
const BDE& metadataSize = dict["metadata_size"];
// Only accept metadata smaller than 1MiB
if(metadataSize.isInteger() && metadataSize.i() <= 1024*1024) {
msg->_metadataSize = metadataSize.i();
}
return msg;
}

View File

@ -2,7 +2,7 @@
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -46,6 +46,7 @@ namespace aria2 {
class Peer;
class Logger;
class HandshakeExtensionMessage;
class DownloadContext;
typedef SharedHandle<HandshakeExtensionMessage> HandshakeExtensionMessageHandle;
class HandshakeExtensionMessage:public ExtensionMessage {
@ -54,8 +55,12 @@ private:
uint16_t _tcpPort;
size_t _metadataSize;
std::map<std::string, uint8_t> _extensions;
SharedHandle<DownloadContext> _dctx;
SharedHandle<Peer> _peer;
Logger* _logger;
@ -103,6 +108,21 @@ public:
return _tcpPort;
}
size_t getMetadataSize()
{
return _metadataSize;
}
void setMetadataSize(size_t size)
{
_metadataSize = size;
}
void setDownloadContext(const SharedHandle<DownloadContext>& dctx)
{
_dctx = dctx;
}
void setExtension(const std::string& name, uint8_t id)
{
_extensions[name] = id;

View File

@ -346,6 +346,11 @@ SRCS += PeerAbstractCommand.cc PeerAbstractCommand.h\
DefaultExtensionMessageFactory.cc DefaultExtensionMessageFactory.h\
HandshakeExtensionMessage.cc HandshakeExtensionMessage.h\
UTPexExtensionMessage.cc UTPexExtensionMessage.h\
UTMetadataExtensionMessage.cc UTMetadataExtensionMessage.h\
UTMetadataRequestExtensionMessage.cc\
UTMetadataRequestExtensionMessage.h\
UTMetadataRejectExtensionMessage.cc UTMetadataRejectExtensionMessage.h\
UTMetadataDataExtensionMessage.cc UTMetadataDataExtensionMessage.h\
DHTNode.cc DHTNode.h\
DHTBucket.cc DHTBucket.h\
DHTRoutingTable.cc DHTRoutingTable.h\

View File

@ -145,6 +145,11 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactory.cc DefaultExtensionMessageFactory.h\
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessage.cc HandshakeExtensionMessage.h\
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.cc UTPexExtensionMessage.h\
@ENABLE_BITTORRENT_TRUE@ UTMetadataExtensionMessage.cc UTMetadataExtensionMessage.h\
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestExtensionMessage.cc\
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestExtensionMessage.h\
@ENABLE_BITTORRENT_TRUE@ UTMetadataRejectExtensionMessage.cc UTMetadataRejectExtensionMessage.h\
@ENABLE_BITTORRENT_TRUE@ UTMetadataDataExtensionMessage.cc UTMetadataDataExtensionMessage.h\
@ENABLE_BITTORRENT_TRUE@ DHTNode.cc DHTNode.h\
@ENABLE_BITTORRENT_TRUE@ DHTBucket.cc DHTBucket.h\
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTable.cc DHTRoutingTable.h\
@ -489,8 +494,15 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
ExtensionMessageFactory.h DefaultExtensionMessageFactory.cc \
DefaultExtensionMessageFactory.h HandshakeExtensionMessage.cc \
HandshakeExtensionMessage.h UTPexExtensionMessage.cc \
UTPexExtensionMessage.h DHTNode.cc DHTNode.h DHTBucket.cc \
DHTBucket.h DHTRoutingTable.cc DHTRoutingTable.h \
UTPexExtensionMessage.h UTMetadataExtensionMessage.cc \
UTMetadataExtensionMessage.h \
UTMetadataRequestExtensionMessage.cc \
UTMetadataRequestExtensionMessage.h \
UTMetadataRejectExtensionMessage.cc \
UTMetadataRejectExtensionMessage.h \
UTMetadataDataExtensionMessage.cc \
UTMetadataDataExtensionMessage.h DHTNode.cc DHTNode.h \
DHTBucket.cc DHTBucket.h DHTRoutingTable.cc DHTRoutingTable.h \
DHTMessageEntry.cc DHTMessageEntry.h DHTMessageDispatcher.h \
DHTMessageDispatcherImpl.cc DHTMessageDispatcherImpl.h \
DHTMessageReceiver.cc DHTMessageReceiver.h \
@ -644,6 +656,10 @@ am__objects_6 =
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactory.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTMetadataExtensionMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestExtensionMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTMetadataRejectExtensionMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTMetadataDataExtensionMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTNode.$(OBJEXT) DHTBucket.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTable.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTMessageEntry.$(OBJEXT) \
@ -1511,6 +1527,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransferStat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URIResult.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataDataExtensionMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataExtensionMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataRejectExtensionMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataRequestExtensionMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnknownLengthPieceStorage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriListParser.Po@am__quote@

View File

@ -47,9 +47,9 @@ class SocketCore;
class ARC4Encryptor;
class ARC4Decryptor;
// we assume maximum length of incoming message is "piece" message with 16KB
// data. Messages beyond that size are dropped.
#define MAX_PAYLOAD_LEN (9+16*1024)
// The maximum length of payload. Messages beyond that length are
// dropped.
#define MAX_PAYLOAD_LEN (16*1024+128)
class PeerConnection {
private:

View File

@ -109,6 +109,8 @@ PeerInteractionCommand::PeerInteractionCommand
SharedHandle<DefaultExtensionMessageFactory> extensionMessageFactory
(new DefaultExtensionMessageFactory(peer, exMsgRegistry));
extensionMessageFactory->setPeerStorage(peerStorage);
extensionMessageFactory->setDownloadContext
(_requestGroup->getDownloadContext());
SharedHandle<DefaultBtMessageFactory> factory(new DefaultBtMessageFactory());
factory->setCuid(cuid);
@ -189,6 +191,9 @@ PeerInteractionCommand::PeerInteractionCommand
factory->setBtRequestFactory(reqFactory);
factory->setPeerConnection(peerConnection);
extensionMessageFactory->setBtMessageDispatcher(dispatcher);
extensionMessageFactory->setBtMessageFactory(factory);
peer->allocateSessionResource
(_requestGroup->getDownloadContext()->getPieceLength(),
_requestGroup->getDownloadContext()->getTotalLength());

View File

@ -0,0 +1,77 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "UTMetadataDataExtensionMessage.h"
#include "BDE.h"
#include "bencode.h"
#include "util.h"
#include "a2functional.h"
namespace aria2 {
UTMetadataDataExtensionMessage::UTMetadataDataExtensionMessage
(uint8_t extensionMessageID):UTMetadataExtensionMessage(extensionMessageID) {}
std::string UTMetadataDataExtensionMessage::getBencodedData()
{
BDE list = BDE::list();
BDE dict = BDE::dict();
dict["msg_type"] = 1;
dict["piece"] = _index;
dict["total_size"] = _totalSize;
BDE data = _data;
list << dict;
list << data;
std::string encodedList = bencode::encode(list);
// Remove first 'l' and last 'e' and return.
return std::string(encodedList.begin()+1, encodedList.end()-1);
}
std::string UTMetadataDataExtensionMessage::toString() const
{
return strconcat("ut_metadata data piece=", util::uitos(_index));
}
void UTMetadataDataExtensionMessage::doReceivedAction()
{
// Update tracker
// Write to pieceStorage
}
} // namespace aria2

View File

@ -0,0 +1,79 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_UT_METADATA_DATA_EXTENSION_MESSAGE_H_
#define _D_UT_METADATA_DATA_EXTENSION_MESSAGE_H_
#include "UTMetadataExtensionMessage.h"
namespace aria2 {
class UTMetadataDataExtensionMessage:public UTMetadataExtensionMessage {
private:
size_t _totalSize;
std::string _data;
public:
UTMetadataDataExtensionMessage(uint8_t extensionMessageID);
virtual std::string getBencodedData();
virtual std::string toString() const;
virtual void doReceivedAction();
void setTotalSize(size_t totalSize)
{
_totalSize = totalSize;
}
size_t getTotalSize() const
{
return _totalSize;
}
void setData(const std::string& data)
{
_data = data;
}
const std::string& getData() const
{
return _data;
}
};
} // namespace aria2
#endif // _D_UT_METADATA_DATA_EXTENSION_MESSAGE_H_

View File

@ -0,0 +1,46 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "UTMetadataExtensionMessage.h"
namespace aria2 {
const std::string UTMetadataExtensionMessage::EXTENSION_NAME = "ut_metadata";
UTMetadataExtensionMessage::UTMetadataExtensionMessage
(uint8_t extensionMessageID):
_extensionMessageID(extensionMessageID),
_index(0) {}
} // namespace aria2

View File

@ -0,0 +1,75 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_UT_METADATA_EXTENSION_MESSAGE_H_
#define _D_UT_METADATA_EXTENSION_MESSAGE_H_
#include "ExtensionMessage.h"
namespace aria2 {
class UTMetadataExtensionMessage:public ExtensionMessage {
protected:
uint8_t _extensionMessageID;
size_t _index;
public:
UTMetadataExtensionMessage(uint8_t extensionMessageID);
virtual uint8_t getExtensionMessageID()
{
return _extensionMessageID;
}
virtual const std::string& getExtensionName() const
{
return EXTENSION_NAME;
}
static const std::string EXTENSION_NAME;
void setIndex(size_t index)
{
_index = index;
}
size_t getIndex()
{
return _index;
}
};
} // namespace aria2
#endif // _D_UT_METADATA_EXTENSION_MESSAGE_H_

View File

@ -0,0 +1,66 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "UTMetadataRejectExtensionMessage.h"
#include "BDE.h"
#include "a2functional.h"
#include "util.h"
#include "bencode.h"
namespace aria2 {
UTMetadataRejectExtensionMessage::UTMetadataRejectExtensionMessage
(uint8_t extensionMessageID):
UTMetadataExtensionMessage(extensionMessageID) {}
std::string UTMetadataRejectExtensionMessage::getBencodedData()
{
BDE dict = BDE::dict();
dict["msg_type"] = 2;
dict["piece"] = _index;
return bencode::encode(dict);
}
std::string UTMetadataRejectExtensionMessage::toString() const
{
return strconcat("ut_metadata reject piece=", util::uitos(_index));
}
void UTMetadataRejectExtensionMessage::doReceivedAction()
{
// TODO Remove outstanding metadata request from tracker.
// OR drop connection.
}
} // namespace aria2

View File

@ -0,0 +1,55 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_UT_METADATA_REJECT_EXTENSION_MESSAGE_H_
#define _D_UT_METADATA_REJECT_EXTENSION_MESSAGE_H_
#include "UTMetadataExtensionMessage.h"
namespace aria2 {
class UTMetadataRejectExtensionMessage:public UTMetadataExtensionMessage {
public:
UTMetadataRejectExtensionMessage(uint8_t extensionMessageID);
virtual std::string getBencodedData();
virtual std::string toString() const;
virtual void doReceivedAction();
};
} // namespace aria2
#endif // _D_UT_METADATA_REJECT_EXTENSION_MESSAGE_H_

View File

@ -0,0 +1,101 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "UTMetadataRequestExtensionMessage.h"
#include "BDE.h"
#include "bencode.h"
#include "util.h"
#include "a2functional.h"
#include "bittorrent_helper.h"
#include "DlAbortEx.h"
#include "StringFormat.h"
#include "BtMessageFactory.h"
#include "BtMessageDispatcher.h"
#include "Peer.h"
#include "UTMetadataRejectExtensionMessage.h"
#include "UTMetadataDataExtensionMessage.h"
#include "BtConstants.h"
#include "DownloadContext.h"
#include "BtMessage.h"
namespace aria2 {
UTMetadataRequestExtensionMessage::UTMetadataRequestExtensionMessage
(uint8_t extensionMessageID):UTMetadataExtensionMessage(extensionMessageID) {}
std::string UTMetadataRequestExtensionMessage::getBencodedData()
{
BDE dict = BDE::dict();
dict["msg_type"] = 0;
dict["piece"] = _index;
return bencode::encode(dict);
}
std::string UTMetadataRequestExtensionMessage::toString() const
{
return strconcat("ut_metadata request piece=", util::uitos(_index));
}
void UTMetadataRequestExtensionMessage::doReceivedAction()
{
const BDE& attrs = _dctx->getAttribute(bittorrent::BITTORRENT);
uint8_t id = _peer->getExtensionMessageID("ut_metadata");
if(!attrs.containsKey(bittorrent::METADATA)) {
SharedHandle<UTMetadataRejectExtensionMessage> m
(new UTMetadataRejectExtensionMessage(id));
m->setIndex(_index);
SharedHandle<BtMessage> msg = _messageFactory->createBtExtendedMessage(m);
_dispatcher->addMessageToQueue(msg);
}else if(_index*METADATA_PIECE_SIZE <
(size_t)attrs[bittorrent::METADATA_SIZE].i()){
SharedHandle<UTMetadataDataExtensionMessage> m
(new UTMetadataDataExtensionMessage(id));
m->setIndex(_index);
m->setTotalSize(attrs[bittorrent::METADATA_SIZE].i());
const BDE& metadata = attrs[bittorrent::METADATA];
std::string::const_iterator begin =
metadata.s().begin()+_index*METADATA_PIECE_SIZE;
std::string::const_iterator end =
(_index+1)*METADATA_PIECE_SIZE <= metadata.s().size()?
metadata.s().begin()+(_index+1)*METADATA_PIECE_SIZE:metadata.s().end();
m->setData(std::string(begin, end));
SharedHandle<BtMessage> msg = _messageFactory->createBtExtendedMessage(m);
_dispatcher->addMessageToQueue(msg);
} else {
throw DL_ABORT_EX
(StringFormat("Metadata piece index is too big. piece=%d", _index).str());
}
}
} // namespace aria2

View File

@ -0,0 +1,88 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2009 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_UT_METADATA_REQUEST_EXTENSION_MESSAGE_H_
#define _D_UT_METADATA_REQUEST_EXTENSION_MESSAGE_H_
#include "UTMetadataExtensionMessage.h"
namespace aria2 {
class DownloadContext;
class BtMessageDispatcher;
class BtMessageFactory;
class Peer;
class UTMetadataRequestExtensionMessage:public UTMetadataExtensionMessage {
private:
SharedHandle<DownloadContext> _dctx;
SharedHandle<Peer> _peer;
WeakHandle<BtMessageDispatcher> _dispatcher;
WeakHandle<BtMessageFactory> _messageFactory;
public:
UTMetadataRequestExtensionMessage(uint8_t extensionMessageID);
virtual std::string getBencodedData();
virtual std::string toString() const;
virtual void doReceivedAction();
void setDownloadContext(const SharedHandle<DownloadContext>& dctx)
{
_dctx = dctx;
}
void setBtMessageDispatcher(const WeakHandle<BtMessageDispatcher>& disp)
{
_dispatcher = disp;
}
void setBtMessageFactory(const WeakHandle<BtMessageFactory>& factory)
{
_messageFactory = factory;
}
void setPeer(const SharedHandle<Peer>& peer)
{
_peer = peer;
}
};
} // namespace aria2
#endif // _D_UT_METADATA_REQUEST_EXTENSION_MESSAGE_H_

View File

@ -125,6 +125,10 @@ const std::string MULTI("multi");
const std::string SINGLE("single");
const std::string METADATA_SIZE("metadataSize");
const std::string METADATA("metadata");
static void extractPieceHash(const SharedHandle<DownloadContext>& ctx,
const std::string& hashData,
size_t hashLength,
@ -364,6 +368,8 @@ static void processRootDictionary
encodedInfoDict.data(),
encodedInfoDict.size());
torrent[INFO_HASH] = std::string(&infoHash[0], &infoHash[INFO_HASH_LENGTH]);
torrent[METADATA] = encodedInfoDict;
torrent[METADATA_SIZE] = encodedInfoDict.size();
// calculate the number of pieces
const BDE& piecesData = infoDict[C_PIECES];

View File

@ -84,6 +84,10 @@ extern const std::string MULTI;
extern const std::string BITTORRENT;
extern const std::string METADATA_SIZE;
extern const std::string METADATA;
void load(const std::string& torrentFile,
const SharedHandle<DownloadContext>& ctx,
const std::string& overrideName = "");

View File

@ -14,6 +14,8 @@
#include "array_fun.h"
#include "messageDigest.h"
#include "a2netcompat.h"
#include "bencode.h"
#include "TestUtil.h"
namespace aria2 {
@ -52,9 +54,10 @@ class BittorrentHelperTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testSetFileFilter_single);
CPPUNIT_TEST(testSetFileFilter_multi);
CPPUNIT_TEST(testUTF8Torrent);
CPPUNIT_TEST(testMetaData);
CPPUNIT_TEST(testEtc);
CPPUNIT_TEST(testCreatecompact);
CPPUNIT_TEST(testCheckBitfield);
CPPUNIT_TEST(testMetadata);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
@ -90,9 +93,10 @@ public:
void testSetFileFilter_single();
void testSetFileFilter_multi();
void testUTF8Torrent();
void testMetaData();
void testEtc();
void testCreatecompact();
void testCheckBitfield();
void testMetadata();
};
@ -634,7 +638,7 @@ void BittorrentHelperTest::testUTF8Torrent()
dctx->getAttribute(BITTORRENT)[COMMENT].s());
}
void BittorrentHelperTest::testMetaData()
void BittorrentHelperTest::testEtc()
{
SharedHandle<DownloadContext> dctx(new DownloadContext());
load("test.torrent", dctx);
@ -678,6 +682,19 @@ void BittorrentHelperTest::testCheckBitfield()
}
}
void BittorrentHelperTest::testMetadata() {
SharedHandle<DownloadContext> dctx(new DownloadContext());
load("test.torrent", dctx);
std::string torrentData = readFile("test.torrent");
BDE tr = bencode::decode(torrentData);
BDE infoDic = tr["info"];
std::string metadata = bencode::encode(infoDic);
const BDE& attrs = dctx->getAttribute(bittorrent::BITTORRENT);
CPPUNIT_ASSERT(metadata == attrs[bittorrent::METADATA].s());
CPPUNIT_ASSERT_EQUAL(metadata.size(),
(size_t)attrs[bittorrent::METADATA_SIZE].i());
}
} // namespace bittorrent
} // namespace aria2

View File

@ -12,6 +12,15 @@
#include "Exception.h"
#include "FileEntry.h"
#include "ExtensionMessageRegistry.h"
#include "DownloadContext.h"
#include "MockBtMessageDispatcher.h"
#include "MockBtMessageFactory.h"
#include "DownloadContext.h"
#include "BtHandshakeMessage.h"
#include "StringFormat.h"
#include "UTMetadataRequestExtensionMessage.h"
#include "UTMetadataDataExtensionMessage.h"
#include "UTMetadataRejectExtensionMessage.h"
namespace aria2 {
@ -21,12 +30,18 @@ class DefaultExtensionMessageFactoryTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreateMessage_unknown);
CPPUNIT_TEST(testCreateMessage_Handshake);
CPPUNIT_TEST(testCreateMessage_UTPex);
CPPUNIT_TEST(testCreateMessage_UTMetadataRequest);
CPPUNIT_TEST(testCreateMessage_UTMetadataData);
CPPUNIT_TEST(testCreateMessage_UTMetadataReject);
CPPUNIT_TEST_SUITE_END();
private:
SharedHandle<MockPeerStorage> _peerStorage;
SharedHandle<Peer> _peer;
SharedHandle<DefaultExtensionMessageFactory> _factory;
SharedHandle<ExtensionMessageRegistry> _registry;
SharedHandle<MockBtMessageDispatcher> _dispatcher;
SharedHandle<MockBtMessageFactory> _messageFactory;
SharedHandle<DownloadContext> _dctx;
public:
void setUp()
{
@ -38,15 +53,41 @@ public:
_registry.reset(new ExtensionMessageRegistry());
_dispatcher.reset(new MockBtMessageDispatcher());
_messageFactory.reset(new MockBtMessageFactory());
_dctx.reset(new DownloadContext());
_factory.reset(new DefaultExtensionMessageFactory());
_factory->setPeerStorage(_peerStorage);
_factory->setPeer(_peer);
_factory->setExtensionMessageRegistry(_registry);
_factory->setBtMessageDispatcher(_dispatcher);
_factory->setBtMessageFactory(_messageFactory);
_factory->setDownloadContext(_dctx);
}
std::string getExtensionMessageID(const std::string& name)
{
char id[1] = { _registry->getExtensionMessageID(name) };
return std::string(&id[0], &id[1]);
}
template<typename T>
SharedHandle<T> createMessage(const std::string& data)
{
return dynamic_pointer_cast<T>
(_factory->createMessage
(reinterpret_cast<const unsigned char*>(data.c_str()), data.size()));
}
void testCreateMessage_unknown();
void testCreateMessage_Handshake();
void testCreateMessage_UTPex();
void testCreateMessage_UTMetadataRequest();
void testCreateMessage_UTMetadataData();
void testCreateMessage_UTMetadataReject();
};
@ -74,10 +115,8 @@ void DefaultExtensionMessageFactoryTest::testCreateMessage_Handshake()
char id[1] = { 0 };
std::string data = std::string(&id[0], &id[1])+"d1:v5:aria2e";
SharedHandle<HandshakeExtensionMessage> m
(dynamic_pointer_cast<HandshakeExtensionMessage>
(_factory->createMessage
(reinterpret_cast<const unsigned char*>(data.c_str()), data.size())));
SharedHandle<HandshakeExtensionMessage> m =
createMessage<HandshakeExtensionMessage>(data);
CPPUNIT_ASSERT_EQUAL(std::string("aria2"), m->getClientVersion());
}
@ -92,20 +131,45 @@ void DefaultExtensionMessageFactoryTest::testCreateMessage_UTPex()
bittorrent::createcompact(c3, "192.168.0.2", 6882);
bittorrent::createcompact(c4, "10.1.1.3",10000);
char id[1] = { _registry->getExtensionMessageID("ut_pex") };
std::string data = std::string(&id[0], &id[1])+"d5:added12:"+
std::string data = getExtensionMessageID("ut_pex")+"d5:added12:"+
std::string(&c1[0], &c1[6])+std::string(&c2[0], &c2[6])+
"7:added.f2:207:dropped12:"+
std::string(&c3[0], &c3[6])+std::string(&c4[0], &c4[6])+
"e";
SharedHandle<UTPexExtensionMessage> m
(dynamic_pointer_cast<UTPexExtensionMessage>
(_factory->createMessage
(reinterpret_cast<const unsigned char*>(data.c_str()), data.size())));
SharedHandle<UTPexExtensionMessage> m =
createMessage<UTPexExtensionMessage>(data);
CPPUNIT_ASSERT_EQUAL(_registry->getExtensionMessageID("ut_pex"),
m->getExtensionMessageID());
}
void DefaultExtensionMessageFactoryTest::testCreateMessage_UTMetadataRequest()
{
std::string data = getExtensionMessageID("ut_metadata")+
"d8:msg_typei0e5:piecei1ee";
SharedHandle<UTMetadataRequestExtensionMessage> m =
createMessage<UTMetadataRequestExtensionMessage>(data);
CPPUNIT_ASSERT_EQUAL((size_t)1, m->getIndex());
}
void DefaultExtensionMessageFactoryTest::testCreateMessage_UTMetadataData()
{
std::string data = getExtensionMessageID("ut_metadata")+
"d8:msg_typei1e5:piecei1e10:total_sizei300ee10:0000000000";
SharedHandle<UTMetadataDataExtensionMessage> m =
createMessage<UTMetadataDataExtensionMessage>(data);
CPPUNIT_ASSERT_EQUAL((size_t)1, m->getIndex());
CPPUNIT_ASSERT_EQUAL((size_t)300, m->getTotalSize());
CPPUNIT_ASSERT_EQUAL(std::string(10, '0'), m->getData());
}
void DefaultExtensionMessageFactoryTest::testCreateMessage_UTMetadataReject()
{
std::string data = getExtensionMessageID("ut_metadata")+
"d8:msg_typei2e5:piecei1ee";
SharedHandle<UTMetadataRejectExtensionMessage> m =
createMessage<UTMetadataRejectExtensionMessage>(data);
CPPUNIT_ASSERT_EQUAL((size_t)1, m->getIndex());
}
} // namespace aria2

View File

@ -7,6 +7,8 @@
#include "Peer.h"
#include "Exception.h"
#include "FileEntry.h"
#include "DownloadContext.h"
#include "bittorrent_helper.h"
namespace aria2 {
@ -57,11 +59,18 @@ void HandshakeExtensionMessageTest::testGetBencodedData()
msg.setTCPPort(6889);
msg.setExtension("ut_pex", 1);
msg.setExtension("a2_dht", 2);
CPPUNIT_ASSERT_EQUAL(std::string("d"
"1:md6:a2_dhti2e6:ut_pexi1ee"
"1:pi6889e"
"1:v5:aria2"
"e"), msg.getBencodedData());
msg.setMetadataSize(1024);
CPPUNIT_ASSERT_EQUAL
(std::string("d"
"1:md6:a2_dhti2e6:ut_pexi1ee"
"13:metadata_sizei1024e"
"1:pi6889e"
"1:v5:aria2"
"e"), msg.getBencodedData());
msg.setMetadataSize(0);
CPPUNIT_ASSERT
(msg.getBencodedData().find("metadata_size") == std::string::npos);
}
void HandshakeExtensionMessageTest::testToString()
@ -71,11 +80,18 @@ void HandshakeExtensionMessageTest::testToString()
msg.setTCPPort(6889);
msg.setExtension("ut_pex", 1);
msg.setExtension("a2_dht", 2);
CPPUNIT_ASSERT_EQUAL(std::string("handshake client=aria2, tcpPort=6889, a2_dht=2, ut_pex=1"), msg.toString());
msg.setMetadataSize(1024);
CPPUNIT_ASSERT_EQUAL
(std::string("handshake client=aria2, tcpPort=6889, metadataSize=1024,"
" a2_dht=2, ut_pex=1"), msg.toString());
}
void HandshakeExtensionMessageTest::testDoReceivedAction()
{
SharedHandle<DownloadContext> ctx(new DownloadContext());
BDE attrs = BDE::dict();
ctx->setAttribute(bittorrent::BITTORRENT, attrs);
SharedHandle<Peer> peer(new Peer("192.168.0.1", 0));
peer->allocateSessionResource(1024, 1024*1024);
HandshakeExtensionMessage msg;
@ -83,25 +99,29 @@ void HandshakeExtensionMessageTest::testDoReceivedAction()
msg.setTCPPort(6889);
msg.setExtension("ut_pex", 1);
msg.setExtension("a2_dht", 2);
msg.setMetadataSize(1024);
msg.setPeer(peer);
msg.setDownloadContext(ctx);
msg.doReceivedAction();
CPPUNIT_ASSERT_EQUAL((uint16_t)6889, peer->port);
CPPUNIT_ASSERT_EQUAL((uint8_t)1, peer->getExtensionMessageID("ut_pex"));
CPPUNIT_ASSERT_EQUAL((uint8_t)2, peer->getExtensionMessageID("a2_dht"));
CPPUNIT_ASSERT_EQUAL((int64_t)1024, attrs[bittorrent::METADATA_SIZE].i());
}
void HandshakeExtensionMessageTest::testCreate()
{
std::string in = "0d1:pi6881e1:v5:aria21:md6:ut_pexi1eee";
std::string in =
"0d1:pi6881e1:v5:aria21:md6:ut_pexi1ee13:metadata_sizei1024ee";
SharedHandle<HandshakeExtensionMessage> m =
HandshakeExtensionMessage::create(reinterpret_cast<const unsigned char*>(in.c_str()),
in.size());
CPPUNIT_ASSERT_EQUAL(std::string("aria2"), m->getClientVersion());
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, m->getTCPPort());
CPPUNIT_ASSERT_EQUAL((uint8_t)1, m->getExtensionMessageID("ut_pex"));
CPPUNIT_ASSERT_EQUAL((size_t)1024, m->getMetadataSize());
try {
// bad payload format
std::string in = "011:hello world";

View File

@ -136,6 +136,9 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
BtExtendedMessageTest.cc\
HandshakeExtensionMessageTest.cc\
UTPexExtensionMessageTest.cc\
UTMetadataRequestExtensionMessageTest.cc\
UTMetadataDataExtensionMessageTest.cc\
UTMetadataRejectExtensionMessageTest.cc\
DefaultBtMessageFactoryTest.cc\
DefaultExtensionMessageFactoryTest.cc\
DHTNodeTest.cc\

View File

@ -86,6 +86,9 @@ check_PROGRAMS = $(am__EXEEXT_1)
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestExtensionMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ UTMetadataDataExtensionMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ UTMetadataRejectExtensionMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactoryTest.cc\
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactoryTest.cc\
@ENABLE_BITTORRENT_TRUE@ DHTNodeTest.cc\
@ -224,7 +227,11 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
BtRegistryTest.cc BtDependencyTest.cc \
BtPostDownloadHandlerTest.cc TimeSeedCriteriaTest.cc \
BtExtendedMessageTest.cc HandshakeExtensionMessageTest.cc \
UTPexExtensionMessageTest.cc DefaultBtMessageFactoryTest.cc \
UTPexExtensionMessageTest.cc \
UTMetadataRequestExtensionMessageTest.cc \
UTMetadataDataExtensionMessageTest.cc \
UTMetadataRejectExtensionMessageTest.cc \
DefaultBtMessageFactoryTest.cc \
DefaultExtensionMessageFactoryTest.cc DHTNodeTest.cc \
DHTBucketTest.cc DHTRoutingTableTest.cc \
DHTMessageTrackerEntryTest.cc DHTMessageTrackerTest.cc \
@ -296,6 +303,9 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTMetadataRequestExtensionMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTMetadataDataExtensionMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ UTMetadataRejectExtensionMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactoryTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactoryTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTNodeTest.$(OBJEXT) \
@ -840,6 +850,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataDataExtensionMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataRejectExtensionMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTMetadataRequestExtensionMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriListParserTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@

View File

@ -0,0 +1,60 @@
#include "UTMetadataDataExtensionMessage.h"
#include <iostream>
#include <cppunit/extensions/HelperMacros.h>
#include "BtConstants.h"
namespace aria2 {
class UTMetadataDataExtensionMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(UTMetadataDataExtensionMessageTest);
CPPUNIT_TEST(testGetExtensionMessageID);
CPPUNIT_TEST(testGetBencodedData);
CPPUNIT_TEST(testToString);
CPPUNIT_TEST(testDoReceivedAction);
CPPUNIT_TEST_SUITE_END();
public:
void testGetExtensionMessageID();
void testGetBencodedData();
void testToString();
void testDoReceivedAction();
};
CPPUNIT_TEST_SUITE_REGISTRATION(UTMetadataDataExtensionMessageTest);
void UTMetadataDataExtensionMessageTest::testGetExtensionMessageID()
{
UTMetadataDataExtensionMessage msg(1);
CPPUNIT_ASSERT_EQUAL((uint8_t)1, msg.getExtensionMessageID());
}
void UTMetadataDataExtensionMessageTest::testGetBencodedData()
{
std::string data(METADATA_PIECE_SIZE, '0');
UTMetadataDataExtensionMessage msg(1);
msg.setIndex(1);
msg.setTotalSize(data.size());
msg.setData(data);
CPPUNIT_ASSERT_EQUAL
(std::string("d8:msg_typei1e5:piecei1e10:total_sizei16384ee16384:")+data,
msg.getBencodedData());
}
void UTMetadataDataExtensionMessageTest::testToString()
{
UTMetadataDataExtensionMessage msg(1);
msg.setIndex(100);
CPPUNIT_ASSERT_EQUAL(std::string("ut_metadata data piece=100"),
msg.toString());
}
void UTMetadataDataExtensionMessageTest::testDoReceivedAction()
{
}
} // namespace aria2

View File

@ -0,0 +1,55 @@
#include "UTMetadataRejectExtensionMessage.h"
#include <iostream>
#include <cppunit/extensions/HelperMacros.h>
#include "BtConstants.h"
namespace aria2 {
class UTMetadataRejectExtensionMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(UTMetadataRejectExtensionMessageTest);
CPPUNIT_TEST(testGetExtensionMessageID);
CPPUNIT_TEST(testGetBencodedReject);
CPPUNIT_TEST(testToString);
CPPUNIT_TEST(testDoReceivedAction);
CPPUNIT_TEST_SUITE_END();
public:
void testGetExtensionMessageID();
void testGetBencodedReject();
void testToString();
void testDoReceivedAction();
};
CPPUNIT_TEST_SUITE_REGISTRATION(UTMetadataRejectExtensionMessageTest);
void UTMetadataRejectExtensionMessageTest::testGetExtensionMessageID()
{
UTMetadataRejectExtensionMessage msg(1);
CPPUNIT_ASSERT_EQUAL((uint8_t)1, msg.getExtensionMessageID());
}
void UTMetadataRejectExtensionMessageTest::testGetBencodedReject()
{
UTMetadataRejectExtensionMessage msg(1);
msg.setIndex(1);
CPPUNIT_ASSERT_EQUAL
(std::string("d8:msg_typei2e5:piecei1ee"), msg.getBencodedData());
}
void UTMetadataRejectExtensionMessageTest::testToString()
{
UTMetadataRejectExtensionMessage msg(1);
msg.setIndex(100);
CPPUNIT_ASSERT_EQUAL(std::string("ut_metadata reject piece=100"),
msg.toString());
}
void UTMetadataRejectExtensionMessageTest::testDoReceivedAction()
{
}
} // namespace aria2

View File

@ -0,0 +1,186 @@
#include "UTMetadataRequestExtensionMessage.h"
#include <iostream>
#include <cppunit/extensions/HelperMacros.h>
#include "Peer.h"
#include "DownloadContext.h"
#include "MockBtMessage.h"
#include "MockBtMessageDispatcher.h"
#include "MockBtMessageFactory.h"
#include "bittorrent_helper.h"
#include "BtHandshakeMessage.h"
#include "UTMetadataRejectExtensionMessage.h"
#include "UTMetadataDataExtensionMessage.h"
namespace aria2 {
class UTMetadataRequestExtensionMessageTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(UTMetadataRequestExtensionMessageTest);
CPPUNIT_TEST(testGetExtensionMessageID);
CPPUNIT_TEST(testGetExtensionName);
CPPUNIT_TEST(testGetBencodedData);
CPPUNIT_TEST(testToString);
CPPUNIT_TEST(testDoReceivedAction_reject);
CPPUNIT_TEST(testDoReceivedAction_data);
CPPUNIT_TEST_SUITE_END();
public:
class MockExtensionMessage:public MockBtMessage {
public:
SharedHandle<ExtensionMessage> _m;
MockExtensionMessage(const SharedHandle<ExtensionMessage>& m):_m(m) {}
};
class MockBtMessageFactory2:public MockBtMessageFactory {
public:
virtual SharedHandle<BtMessage>
createBtExtendedMessage(const SharedHandle<ExtensionMessage>& extmsg)
{
return SharedHandle<BtMessage>(new MockExtensionMessage(extmsg));
}
};
SharedHandle<DownloadContext> _dctx;
SharedHandle<MockBtMessageFactory2> _messageFactory;
SharedHandle<MockBtMessageDispatcher> _dispatcher;
SharedHandle<Peer> _peer;
void setUp()
{
_messageFactory.reset(new MockBtMessageFactory2());
_dispatcher.reset(new MockBtMessageDispatcher());
_dctx.reset(new DownloadContext());
BDE attrs = BDE::dict();
_dctx->setAttribute(bittorrent::BITTORRENT, attrs);
_peer.reset(new Peer("host", 6880));
_peer->allocateSessionResource(0, 0);
_peer->setExtension("ut_metadata", 1);
}
template<typename T>
SharedHandle<T> getFirstDispatchedMessage()
{
SharedHandle<MockExtensionMessage> wrapmsg =
dynamic_pointer_cast<MockExtensionMessage>
(_dispatcher->messageQueue.front());
SharedHandle<T> msg = dynamic_pointer_cast<T>(wrapmsg->_m);
return msg;
}
void testGetExtensionMessageID();
void testGetExtensionName();
void testGetBencodedData();
void testToString();
void testDoReceivedAction_reject();
void testDoReceivedAction_data();
};
CPPUNIT_TEST_SUITE_REGISTRATION(UTMetadataRequestExtensionMessageTest);
void UTMetadataRequestExtensionMessageTest::testGetExtensionMessageID()
{
UTMetadataRequestExtensionMessage msg(1);
CPPUNIT_ASSERT_EQUAL((uint8_t)1, msg.getExtensionMessageID());
}
void UTMetadataRequestExtensionMessageTest::testGetExtensionName()
{
UTMetadataRequestExtensionMessage msg(1);
CPPUNIT_ASSERT_EQUAL(std::string("ut_metadata"), msg.getExtensionName());
}
void UTMetadataRequestExtensionMessageTest::testGetBencodedData()
{
UTMetadataRequestExtensionMessage msg(1);
msg.setIndex(99);
CPPUNIT_ASSERT_EQUAL
(std::string("d8:msg_typei0e5:piecei99ee"), msg.getBencodedData());
}
void UTMetadataRequestExtensionMessageTest::testToString()
{
UTMetadataRequestExtensionMessage msg(1);
msg.setIndex(100);
CPPUNIT_ASSERT_EQUAL(std::string("ut_metadata request piece=100"),
msg.toString());
}
void UTMetadataRequestExtensionMessageTest::testDoReceivedAction_reject()
{
UTMetadataRequestExtensionMessage msg(1);
msg.setIndex(10);
msg.setDownloadContext(_dctx);
msg.setPeer(_peer);
msg.setBtMessageFactory(_messageFactory);
msg.setBtMessageDispatcher(_dispatcher);
msg.doReceivedAction();
SharedHandle<UTMetadataRejectExtensionMessage> m =
getFirstDispatchedMessage<UTMetadataRejectExtensionMessage>();
CPPUNIT_ASSERT(!m.isNull());
CPPUNIT_ASSERT_EQUAL((size_t)10, m->getIndex());
CPPUNIT_ASSERT_EQUAL((uint8_t)1, m->getExtensionMessageID());
}
void UTMetadataRequestExtensionMessageTest::testDoReceivedAction_data()
{
UTMetadataRequestExtensionMessage msg(1);
msg.setIndex(1);
msg.setDownloadContext(_dctx);
msg.setPeer(_peer);
msg.setBtMessageFactory(_messageFactory);
msg.setBtMessageDispatcher(_dispatcher);
size_t metadataSize = METADATA_PIECE_SIZE*2;
BDE& attrs = _dctx->getAttribute(bittorrent::BITTORRENT);
std::string first(METADATA_PIECE_SIZE, '0');
std::string second(METADATA_PIECE_SIZE, '1');
attrs[bittorrent::METADATA] = first+second;
attrs[bittorrent::METADATA_SIZE] = metadataSize;
msg.doReceivedAction();
SharedHandle<UTMetadataDataExtensionMessage> m =
getFirstDispatchedMessage<UTMetadataDataExtensionMessage>();
CPPUNIT_ASSERT(!m.isNull());
CPPUNIT_ASSERT_EQUAL((size_t)1, m->getIndex());
CPPUNIT_ASSERT_EQUAL(second, m->getData());
CPPUNIT_ASSERT_EQUAL(metadataSize, m->getTotalSize());
CPPUNIT_ASSERT_EQUAL((uint8_t)1, m->getExtensionMessageID());
_dispatcher->messageQueue.clear();
msg.setIndex(2);
metadataSize += 100;
std::string third(100, '2');
attrs[bittorrent::METADATA] = attrs[bittorrent::METADATA].s()+third;
attrs[bittorrent::METADATA_SIZE] = metadataSize;
msg.doReceivedAction();
m = getFirstDispatchedMessage<UTMetadataDataExtensionMessage>();
CPPUNIT_ASSERT(!m.isNull());
CPPUNIT_ASSERT_EQUAL((size_t)2, m->getIndex());
CPPUNIT_ASSERT_EQUAL(third, m->getData());
CPPUNIT_ASSERT_EQUAL(metadataSize, m->getTotalSize());
msg.setIndex(3);
try {
msg.doReceivedAction();
CPPUNIT_FAIL("exception must be thrown.");
} catch(DlAbortEx& e) {
// success
}
}
} // namespace aria2