summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-11-20 15:42:25 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-11-20 15:42:25 +0000
commit93968c4fa525d44bf83fb221874a8b8febee3905 (patch)
treeca34cb33f56f18a04b0a154d19f0bd8df47edf33
parent2764b6739d0b0414cf0ce31c2f8db5b24f68b75e (diff)
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
-rw-r--r--ChangeLog34
-rw-r--r--src/BtConstants.h2
-rw-r--r--src/DefaultBtInteractive.cc5
-rw-r--r--src/DefaultExtensionMessageFactory.cc78
-rw-r--r--src/DefaultExtensionMessageFactory.h24
-rw-r--r--src/ExtensionMessage.h4
-rw-r--r--src/ExtensionMessageRegistry.h2
-rw-r--r--src/HandshakeExtensionMessage.cc22
-rw-r--r--src/HandshakeExtensionMessage.h22
-rw-r--r--src/Makefile.am5
-rw-r--r--src/Makefile.in24
-rw-r--r--src/PeerConnection.h6
-rw-r--r--src/PeerInteractionCommand.cc5
-rw-r--r--src/UTMetadataDataExtensionMessage.cc77
-rw-r--r--src/UTMetadataDataExtensionMessage.h79
-rw-r--r--src/UTMetadataExtensionMessage.cc46
-rw-r--r--src/UTMetadataExtensionMessage.h75
-rw-r--r--src/UTMetadataRejectExtensionMessage.cc66
-rw-r--r--src/UTMetadataRejectExtensionMessage.h55
-rw-r--r--src/UTMetadataRequestExtensionMessage.cc101
-rw-r--r--src/UTMetadataRequestExtensionMessage.h88
-rw-r--r--src/bittorrent_helper.cc6
-rw-r--r--src/bittorrent_helper.h4
-rw-r--r--test/BittorrentHelperTest.cc23
-rw-r--r--test/DefaultExtensionMessageFactoryTest.cc86
-rw-r--r--test/HandshakeExtensionMessageTest.cc36
-rw-r--r--test/Makefile.am3
-rw-r--r--test/Makefile.in15
-rw-r--r--test/UTMetadataDataExtensionMessageTest.cc60
-rw-r--r--test/UTMetadataRejectExtensionMessageTest.cc55
-rw-r--r--test/UTMetadataRequestExtensionMessageTest.cc186
31 files changed, 1262 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index fc997f87..bcd54661 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,39 @@
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
the command has segments.
* src/CreateRequestCommand.cc
diff --git a/src/BtConstants.h b/src/BtConstants.h
index 4108755a..e9c40dcc 100644
--- a/src/BtConstants.h
+++ b/src/BtConstants.h
@@ -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_
diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc
index 16cbf4d3..3dd62096 100644
--- a/src/DefaultBtInteractive.cc
+++ b/src/DefaultBtInteractive.cc
@@ -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);
}
diff --git a/src/DefaultExtensionMessageFactory.cc b/src/DefaultExtensionMessageFactory.cc
index f28680a4..4dad47e4 100644
--- a/src/DefaultExtensionMessageFactory.cc
+++ b/src/DefaultExtensionMessageFactory.cc
@@ -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",
diff --git a/src/DefaultExtensionMessageFactory.h b/src/DefaultExtensionMessageFactory.h
index dfc1c0ec..319528f6 100644
--- a/src/DefaultExtensionMessageFactory.h
+++ b/src/DefaultExtensionMessageFactory.h
@@ -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;
diff --git a/src/ExtensionMessage.h b/src/ExtensionMessage.h
index 44902f0b..7d996380 100644
--- a/src/ExtensionMessage.h
+++ b/src/ExtensionMessage.h
@@ -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:
diff --git a/src/ExtensionMessageRegistry.h b/src/ExtensionMessageRegistry.h
index d79c8e4b..e79a6619 100644
--- a/src/ExtensionMessageRegistry.h
+++ b/src/ExtensionMessageRegistry.h
@@ -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
diff --git a/src/HandshakeExtensionMessage.cc b/src/HandshakeExtensionMessage.cc
index 5ce2bd7f..a0c04c3a 100644
--- a/src/HandshakeExtensionMessage.cc
+++ b/src/HandshakeExtensionMessage.cc
@@ -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;
}
diff --git a/src/HandshakeExtensionMessage.h b/src/HandshakeExtensionMessage.h
index 3c9c7dd9..73386883 100644
--- a/src/HandshakeExtensionMessage.h
+++ b/src/HandshakeExtensionMessage.h
@@ -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;
diff --git a/src/Makefile.am b/src/Makefile.am
index a3ea139e..1cfe5221 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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\
diff --git a/src/Makefile.in b/src/Makefile.in
index d21dacc6..1bb60b99 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -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@
diff --git a/src/PeerConnection.h b/src/PeerConnection.h
index 2e01ba5b..18ae037c 100644
--- a/src/PeerConnection.h
+++ b/src/PeerConnection.h
@@ -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:
diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc
index 3fe2035f..7507be30 100644
--- a/src/PeerInteractionCommand.cc
+++ b/src/PeerInteractionCommand.cc
@@ -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());
diff --git a/src/UTMetadataDataExtensionMessage.cc b/src/UTMetadataDataExtensionMessage.cc
new file mode 100644
index 00000000..7f80a608
--- /dev/null
+++ b/src/UTMetadataDataExtensionMessage.cc
@@ -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
diff --git a/src/UTMetadataDataExtensionMessage.h b/src/UTMetadataDataExtensionMessage.h
new file mode 100644
index 00000000..d2d6aa39
--- /dev/null
+++ b/src/UTMetadataDataExtensionMessage.h
@@ -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_
diff --git a/src/UTMetadataExtensionMessage.cc b/src/UTMetadataExtensionMessage.cc
new file mode 100644
index 00000000..2842fb5f
--- /dev/null
+++ b/src/UTMetadataExtensionMessage.cc
@@ -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
diff --git a/src/UTMetadataExtensionMessage.h b/src/UTMetadataExtensionMessage.h
new file mode 100644
index 00000000..0a890ac0
--- /dev/null
+++ b/src/UTMetadataExtensionMessage.h
@@ -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_
diff --git a/src/UTMetadataRejectExtensionMessage.cc b/src/UTMetadataRejectExtensionMessage.cc
new file mode 100644
index 00000000..243d1302
--- /dev/null
+++ b/src/UTMetadataRejectExtensionMessage.cc
@@ -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
diff --git a/src/UTMetadataRejectExtensionMessage.h b/src/UTMetadataRejectExtensionMessage.h
new file mode 100644
index 00000000..7ce47f03
--- /dev/null
+++ b/src/UTMetadataRejectExtensionMessage.h
@@ -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_
diff --git a/src/UTMetadataRequestExtensionMessage.cc b/src/UTMetadataRequestExtensionMessage.cc
new file mode 100644
index 00000000..92de8fae
--- /dev/null
+++ b/src/UTMetadataRequestExtensionMessage.cc
@@ -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
diff --git a/src/UTMetadataRequestExtensionMessage.h b/src/UTMetadataRequestExtensionMessage.h
new file mode 100644
index 00000000..682af99d
--- /dev/null
+++ b/src/UTMetadataRequestExtensionMessage.h
@@ -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_
diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc
index 68ebb915..0fa05cc4 100644
--- a/src/bittorrent_helper.cc
+++ b/src/bittorrent_helper.cc
@@ -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];
diff --git a/src/bittorrent_helper.h b/src/bittorrent_helper.h
index bc9c8fe9..bf1269a3 100644
--- a/src/bittorrent_helper.h
+++ b/src/bittorrent_helper.h
@@ -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 = "");
diff --git a/test/BittorrentHelperTest.cc b/test/BittorrentHelperTest.cc
index 246a98d0..756ed2de 100644
--- a/test/BittorrentHelperTest.cc
+++ b/test/BittorrentHelperTest.cc
@@ -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
diff --git a/test/DefaultExtensionMessageFactoryTest.cc b/test/DefaultExtensionMessageFactoryTest.cc
index 23b71fcc..878bdb06 100644
--- a/test/DefaultExtensionMessageFactoryTest.cc
+++ b/test/DefaultExtensionMessageFactoryTest.cc
@@ -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
diff --git a/test/HandshakeExtensionMessageTest.cc b/test/HandshakeExtensionMessageTest.cc
index b05154d9..b8ceb4dc 100644
--- a/test/HandshakeExtensionMessageTest.cc
+++ b/test/HandshakeExtensionMessageTest.cc
@@ -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";
diff --git a/test/Makefile.am b/test/Makefile.am
index e5d222f1..9198d007 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -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\
diff --git a/test/Makefile.in b/test/Makefile.in
index c66893d5..c8559c7e 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -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@
diff --git a/test/UTMetadataDataExtensionMessageTest.cc b/test/UTMetadataDataExtensionMessageTest.cc
new file mode 100644
index 00000000..463aa3a1
--- /dev/null
+++ b/test/UTMetadataDataExtensionMessageTest.cc
@@ -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
diff --git a/test/UTMetadataRejectExtensionMessageTest.cc b/test/UTMetadataRejectExtensionMessageTest.cc
new file mode 100644
index 00000000..831ccdf5
--- /dev/null
+++ b/test/UTMetadataRejectExtensionMessageTest.cc
@@ -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
diff --git a/test/UTMetadataRequestExtensionMessageTest.cc b/test/UTMetadataRequestExtensionMessageTest.cc
new file mode 100644
index 00000000..6d21d776
--- /dev/null
+++ b/test/UTMetadataRequestExtensionMessageTest.cc
@@ -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