Refactor DownloadHandlerFactory

pull/150/head
Tatsuhiro Tsujikawa 2013-11-10 17:14:54 +09:00
parent ba3b823a66
commit 9e52483c04
24 changed files with 265 additions and 364 deletions

View File

@ -57,17 +57,13 @@ namespace aria2 {
BtPostDownloadHandler::BtPostDownloadHandler()
{
std::shared_ptr<RequestGroupCriteria> cri
(new ContentTypeRequestGroupCriteria
(getBtContentTypes(), getBtExtensions()));
setCriteria(cri);
setCriteria(make_unique<ContentTypeRequestGroupCriteria>
(getBtContentTypes(), getBtExtensions()));
}
BtPostDownloadHandler::~BtPostDownloadHandler() {}
void BtPostDownloadHandler::getNextRequestGroups
(std::vector<std::shared_ptr<RequestGroup> >& groups,
RequestGroup* requestGroup)
RequestGroup* requestGroup) const
{
A2_LOG_INFO(fmt("Generating RequestGroups for Torrent file %s",
requestGroup->getFirstFilePath().c_str()));
@ -100,13 +96,13 @@ void BtPostDownloadHandler::getNextRequestGroups
throw DL_ABORT_EX2("Could not parse BitTorrent metainfo",
error_code::BENCODE_PARSE_ERROR);
}
std::vector<std::shared_ptr<RequestGroup> > newRgs;
std::vector<std::shared_ptr<RequestGroup>> newRgs;
createRequestGroupForBitTorrent(newRgs, requestGroup->getOption(),
std::vector<std::string>(),
"",
torrent.get());
requestGroup->followedBy(newRgs.begin(), newRgs.end());
std::shared_ptr<MetadataInfo> mi =
auto mi =
createMetadataInfoFromFirstFileEntry(requestGroup->getGroupId(),
requestGroup->getDownloadContext());
if(mi) {

View File

@ -44,11 +44,9 @@ class BtPostDownloadHandler:public PostDownloadHandler
public:
BtPostDownloadHandler();
virtual ~BtPostDownloadHandler();
virtual void
getNextRequestGroups(std::vector<std::shared_ptr<RequestGroup> >& groups,
RequestGroup* requestGroup) CXX11_OVERRIDE;
RequestGroup* requestGroup) const CXX11_OVERRIDE;
};
} // namespace aria2

View File

@ -39,19 +39,15 @@
namespace aria2 {
DownloadHandler::DownloadHandler() {}
DownloadHandler::~DownloadHandler() {}
bool DownloadHandler::canHandle(const RequestGroup* requestGroup) const
{
return criteria_ && criteria_->match(requestGroup);
return !criteria_ || criteria_->match(requestGroup);
}
void DownloadHandler::setCriteria
(const std::shared_ptr<RequestGroupCriteria>& criteria)
(std::unique_ptr<RequestGroupCriteria> criteria)
{
criteria_ = criteria;
criteria_ = std::move(criteria);
}
} // namespace aria2

View File

@ -47,16 +47,14 @@ class RequestGroupCriteria;
class DownloadHandler
{
private:
std::shared_ptr<RequestGroupCriteria> criteria_;
public:
DownloadHandler();
virtual ~DownloadHandler();
virtual ~DownloadHandler() {}
bool canHandle(const RequestGroup* requestGroup) const;
void setCriteria(const std::shared_ptr<RequestGroupCriteria>& criteria);
void setCriteria(std::unique_ptr<RequestGroupCriteria> criteria);
private:
std::unique_ptr<RequestGroupCriteria> criteria_;
};
} // namespace aria2

View File

@ -1,131 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 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 "DownloadHandlerFactory.h"
#include "MemoryBufferPreDownloadHandler.h"
#include "MetalinkPostDownloadHandler.h"
#include "BtPostDownloadHandler.h"
#include "DownloadHandlerConstants.h"
#include "ContentTypeRequestGroupCriteria.h"
#include "UTMetadataPostDownloadHandler.h"
namespace aria2 {
#ifdef ENABLE_METALINK
std::shared_ptr<PreDownloadHandler>
DownloadHandlerFactory::metalinkPreDownloadHandler_;
std::shared_ptr<PostDownloadHandler>
DownloadHandlerFactory::metalinkPostDownloadHandler_;
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
std::shared_ptr<PreDownloadHandler>
DownloadHandlerFactory::btPreDownloadHandler_;
std::shared_ptr<PostDownloadHandler>
DownloadHandlerFactory::btPostDownloadHandler_;
std::shared_ptr<PostDownloadHandler>
DownloadHandlerFactory::btMetadataPostDownloadHandler_;
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
std::shared_ptr<PreDownloadHandler>
DownloadHandlerFactory::getMetalinkPreDownloadHandler()
{
if(!metalinkPreDownloadHandler_) {
metalinkPreDownloadHandler_.reset(new MemoryBufferPreDownloadHandler());
std::shared_ptr<RequestGroupCriteria> criteria
(new ContentTypeRequestGroupCriteria
(getMetalinkContentTypes(), getMetalinkExtensions()));
metalinkPreDownloadHandler_->setCriteria(criteria);
}
return metalinkPreDownloadHandler_;
}
std::shared_ptr<PostDownloadHandler>
DownloadHandlerFactory::getMetalinkPostDownloadHandler()
{
if(!metalinkPostDownloadHandler_) {
metalinkPostDownloadHandler_.reset(new MetalinkPostDownloadHandler());
}
return metalinkPostDownloadHandler_;
}
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
std::shared_ptr<PreDownloadHandler>
DownloadHandlerFactory::getBtPreDownloadHandler()
{
if(!btPreDownloadHandler_) {
btPreDownloadHandler_.reset
(new bittorrent::MemoryBencodePreDownloadHandler());
std::shared_ptr<RequestGroupCriteria> criteria
(new ContentTypeRequestGroupCriteria
(getBtContentTypes(), getBtExtensions()));
btPreDownloadHandler_->setCriteria(criteria);
}
return btPreDownloadHandler_;
}
std::shared_ptr<PostDownloadHandler>
DownloadHandlerFactory::getBtPostDownloadHandler()
{
if(!btPostDownloadHandler_) {
btPostDownloadHandler_.reset(new BtPostDownloadHandler());
}
return btPostDownloadHandler_;
}
std::shared_ptr<PostDownloadHandler>
DownloadHandlerFactory::getUTMetadataPostDownloadHandler()
{
if(!btMetadataPostDownloadHandler_) {
btMetadataPostDownloadHandler_.reset(new UTMetadataPostDownloadHandler());
}
return btMetadataPostDownloadHandler_;
}
#endif // ENABLE_BITTORRENT
} // namespace aria2

View File

@ -1,101 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 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_DOWNLOAD_HANDLER_FACTORY_H
#define D_DOWNLOAD_HANDLER_FACTORY_H
#include "common.h"
#include <memory>
#include "MemoryBufferPreDownloadHandler.h"
#ifdef ENABLE_BITTORRENT
# include "MemoryBencodePreDownloadHandler.h"
#endif // ENABLE_BITTORRENT
namespace aria2 {
#ifdef ENABLE_METALINK
class MetalinkPostDownloadHandler;
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
class BtPostDownloadHandler;
class UTMetadataPostDownloadHandler;
#endif // ENABLE_BITTORRENT
class DownloadHandlerFactory
{
private:
#ifdef ENABLE_METALINK
static std::shared_ptr<PreDownloadHandler>
metalinkPreDownloadHandler_;
static std::shared_ptr<PostDownloadHandler>
metalinkPostDownloadHandler_;
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
static std::shared_ptr<PreDownloadHandler>
btPreDownloadHandler_;
static std::shared_ptr<PostDownloadHandler>
btPostDownloadHandler_;
static std::shared_ptr<PostDownloadHandler>
btMetadataPostDownloadHandler_;
#endif // ENABLE_BITTORRENT
public:
#ifdef ENABLE_METALINK
static std::shared_ptr<PreDownloadHandler>
getMetalinkPreDownloadHandler();
static std::shared_ptr<PostDownloadHandler>
getMetalinkPostDownloadHandler();
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
static std::shared_ptr<PreDownloadHandler>
getBtPreDownloadHandler();
static std::shared_ptr<PostDownloadHandler>
getBtPostDownloadHandler();
static std::shared_ptr<PostDownloadHandler>
getUTMetadataPostDownloadHandler();
#endif // ENABLE_BITTORRENT
};
} // namespace aria2
#endif // D_DOWNLOAD_HANDLER_FACTORY_H

View File

@ -115,7 +115,7 @@ SRCS = option_processing.cc\
ContentTypeRequestGroupCriteria.cc ContentTypeRequestGroupCriteria.h\
DownloadHandler.cc DownloadHandler.h\
DownloadHandlerConstants.cc DownloadHandlerConstants.h\
DownloadHandlerFactory.cc DownloadHandlerFactory.h\
download_handlers.cc download_handlers.h\
MemoryPreDownloadHandler.h\
MemoryBufferPreDownloadHandler.h\
HaveEraseCommand.cc HaveEraseCommand.h\

View File

@ -44,13 +44,9 @@ template<class DiskWriterFactoryType>
class MemoryPreDownloadHandler:public PreDownloadHandler
{
public:
MemoryPreDownloadHandler() {}
virtual ~MemoryPreDownloadHandler() {}
virtual void execute(RequestGroup* requestGroup) CXX11_OVERRIDE
virtual void execute(RequestGroup* requestGroup) const CXX11_OVERRIDE
{
std::shared_ptr<DiskWriterFactory> dwf(new DiskWriterFactoryType());
auto dwf = std::make_shared<DiskWriterFactoryType>();
requestGroup->setDiskWriterFactory(dwf);
requestGroup->setFileAllocationEnabled(false);
requestGroup->setPreLocalFileCheckEnabled(false);

View File

@ -47,7 +47,6 @@
#include "metalink_helper.h"
#include "BinaryStream.h"
#include "MemoryBufferPreDownloadHandler.h"
#include "TrueRequestGroupCriteria.h"
#include "MetalinkEntry.h"
#include "MetalinkResource.h"
#include "MetalinkMetaurl.h"
@ -59,6 +58,8 @@
#include "SegList.h"
#include "DownloadFailureException.h"
#include "Signature.h"
#include "download_handlers.h"
#include "RequestGroupCriteria.h"
#ifdef ENABLE_BITTORRENT
# include "BtDependency.h"
# include "download_helper.h"
@ -233,9 +234,8 @@ Metalink2RequestGroup::createRequestGroup
// tranparent metalink
torrentRg->getDownloadContext()->setAcceptMetalink(false);
// make it in-memory download
auto preh = std::make_shared<MemoryBufferPreDownloadHandler>();
preh->setCriteria(std::make_shared<TrueRequestGroupCriteria>());
torrentRg->addPreDownloadHandler(preh);
torrentRg->addPreDownloadHandler
(download_handlers::getMemoryPreDownloadHandler());
groups.push_back(torrentRg);
}
}

View File

@ -56,27 +56,22 @@ namespace aria2 {
MetalinkPostDownloadHandler::MetalinkPostDownloadHandler()
{
std::shared_ptr<RequestGroupCriteria> cri
(new ContentTypeRequestGroupCriteria
(getMetalinkContentTypes(), getMetalinkExtensions()));
setCriteria(cri);
setCriteria(make_unique<ContentTypeRequestGroupCriteria>
(getMetalinkContentTypes(), getMetalinkExtensions()));
}
MetalinkPostDownloadHandler::~MetalinkPostDownloadHandler() {}
namespace {
const std::string& getBaseUri(RequestGroup* requestGroup)
{
const std::shared_ptr<DownloadContext>& dctx =
requestGroup->getDownloadContext();
auto& dctx = requestGroup->getDownloadContext();
if(dctx->getFileEntries().empty()) {
return A2STR::NIL;
} else {
// TODO Check download result for each URI
const std::shared_ptr<FileEntry>& entry = dctx->getFirstFileEntry();
const std::deque<std::string>& spentUris = entry->getSpentUris();
auto& entry = dctx->getFirstFileEntry();
auto& spentUris = entry->getSpentUris();
if(spentUris.empty()) {
const std::deque<std::string>& remainingUris = entry->getRemainingUris();
auto& remainingUris = entry->getRemainingUris();
if(remainingUris.empty()) {
return A2STR::NIL;
} else {
@ -90,22 +85,21 @@ const std::string& getBaseUri(RequestGroup* requestGroup)
} // namespace
void MetalinkPostDownloadHandler::getNextRequestGroups
(std::vector<std::shared_ptr<RequestGroup> >& groups,
RequestGroup* requestGroup)
(std::vector<std::shared_ptr<RequestGroup>>& groups,
RequestGroup* requestGroup) const
{
A2_LOG_DEBUG(fmt("Generating RequestGroups for Metalink file %s",
requestGroup->getFirstFilePath().c_str()));
std::shared_ptr<DiskAdaptor> diskAdaptor =
requestGroup->getPieceStorage()->getDiskAdaptor();
auto diskAdaptor = requestGroup->getPieceStorage()->getDiskAdaptor();
try {
diskAdaptor->openExistingFile();
//requestOption.put(PREF_DIR, requestGroup->getDownloadContext()->getDir());
const std::string& baseUri = getBaseUri(requestGroup);
std::vector<std::shared_ptr<RequestGroup> > newRgs;
std::vector<std::shared_ptr<RequestGroup>> newRgs;
Metalink2RequestGroup().generate(newRgs, diskAdaptor,
requestGroup->getOption(), baseUri);
requestGroup->followedBy(newRgs.begin(), newRgs.end());
std::shared_ptr<MetadataInfo> mi =
auto mi =
createMetadataInfoFromFirstFileEntry(requestGroup->getGroupId(),
requestGroup->getDownloadContext());
if(mi) {

View File

@ -44,11 +44,9 @@ class MetalinkPostDownloadHandler:public PostDownloadHandler
public:
MetalinkPostDownloadHandler();
virtual ~MetalinkPostDownloadHandler();
virtual void
getNextRequestGroups(std::vector<std::shared_ptr<RequestGroup> >& groups,
RequestGroup* requestGroup) CXX11_OVERRIDE;
getNextRequestGroups(std::vector<std::shared_ptr<RequestGroup>>& groups,
RequestGroup* requestGroup) const CXX11_OVERRIDE;
};
} // namespace aria2

View File

@ -44,13 +44,11 @@ namespace aria2 {
class PostDownloadHandler:public DownloadHandler
{
public:
PostDownloadHandler() {}
virtual ~PostDownloadHandler() {}
virtual void
getNextRequestGroups(std::vector<std::shared_ptr<RequestGroup> >& groups,
RequestGroup* requestGroup) = 0;
getNextRequestGroups(std::vector<std::shared_ptr<RequestGroup>>& groups,
RequestGroup* requestGroup) const = 0;
};
} // namespace aria2

View File

@ -46,7 +46,7 @@ public:
virtual ~PreDownloadHandler() {}
virtual void execute(RequestGroup* requestGroup) = 0;
virtual void execute(RequestGroup* requestGroup) const = 0;
};
} // namespace aria2

View File

@ -61,7 +61,7 @@
#include "RequestGroupMan.h"
#include "DefaultBtProgressInfoFile.h"
#include "DefaultPieceStorage.h"
#include "DownloadHandlerFactory.h"
#include "download_handlers.h"
#include "MemoryBufferPreDownloadHandler.h"
#include "DownloadHandlerConstants.h"
#include "Option.h"
@ -78,6 +78,7 @@
#include "SimpleRandomizer.h"
#include "Segment.h"
#include "SocketRecvBuffer.h"
#include "RequestGroupCriteria.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "CheckIntegrityCommand.h"
# include "ChecksumCheckIntegrityEntry.h"
@ -1052,12 +1053,14 @@ void RequestGroup::initializePreDownloadHandler()
{
#ifdef ENABLE_BITTORRENT
if(option_->get(PREF_FOLLOW_TORRENT) == V_MEM) {
preDownloadHandlers_.push_back(DownloadHandlerFactory::getBtPreDownloadHandler());
preDownloadHandlers_.push_back
(download_handlers::getBtPreDownloadHandler());
}
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
if(option_->get(PREF_FOLLOW_METALINK) == V_MEM) {
preDownloadHandlers_.push_back(DownloadHandlerFactory::getMetalinkPreDownloadHandler());
preDownloadHandlers_.push_back
(download_handlers::getMetalinkPreDownloadHandler());
}
#endif // ENABLE_METALINK
}
@ -1067,13 +1070,15 @@ void RequestGroup::initializePostDownloadHandler()
#ifdef ENABLE_BITTORRENT
if(option_->getAsBool(PREF_FOLLOW_TORRENT) ||
option_->get(PREF_FOLLOW_TORRENT) == V_MEM) {
postDownloadHandlers_.push_back(DownloadHandlerFactory::getBtPostDownloadHandler());
postDownloadHandlers_.push_back
(download_handlers::getBtPostDownloadHandler());
}
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
if(option_->getAsBool(PREF_FOLLOW_METALINK) ||
option_->get(PREF_FOLLOW_METALINK) == V_MEM) {
postDownloadHandlers_.push_back(DownloadHandlerFactory::getMetalinkPostDownloadHandler());
postDownloadHandlers_.push_back
(download_handlers::getMetalinkPostDownloadHandler());
}
#endif // ENABLE_METALINK
}
@ -1097,14 +1102,12 @@ void RequestGroup::setDiskWriterFactory(
diskWriterFactory_ = diskWriterFactory;
}
void RequestGroup::addPostDownloadHandler
(const std::shared_ptr<PostDownloadHandler>& handler)
void RequestGroup::addPostDownloadHandler(const PostDownloadHandler* handler)
{
postDownloadHandlers_.push_back(handler);
}
void RequestGroup::addPreDownloadHandler(
const std::shared_ptr<PreDownloadHandler>& handler)
void RequestGroup::addPreDownloadHandler(const PreDownloadHandler* handler)
{
preDownloadHandlers_.push_back(handler);
}

View File

@ -131,9 +131,9 @@ private:
bool pauseRequested_;
std::vector<std::shared_ptr<PreDownloadHandler> > preDownloadHandlers_;
std::vector<const PreDownloadHandler*> preDownloadHandlers_;
std::vector<std::shared_ptr<PostDownloadHandler> > postDownloadHandlers_;
std::vector<const PostDownloadHandler*> postDownloadHandlers_;
std::unique_ptr<URISelector> uriSelector_;
@ -375,13 +375,13 @@ public:
void postDownloadProcessing(std::vector<std::shared_ptr<RequestGroup> >& groups);
void addPostDownloadHandler(const std::shared_ptr<PostDownloadHandler>& handler);
void addPostDownloadHandler(const PostDownloadHandler* handler);
void clearPostDownloadHandler();
void preDownloadProcessing();
void addPreDownloadHandler(const std::shared_ptr<PreDownloadHandler>& handler);
void addPreDownloadHandler(const PreDownloadHandler* handler);
void clearPreDownloadHandler();

View File

@ -53,29 +53,33 @@
namespace aria2 {
bool UTMetadataPostDownloadHandler::Criteria::match
(const RequestGroup* requestGroup) const
namespace {
class Criteria:public RequestGroupCriteria
{
const std::shared_ptr<DownloadContext>& dctx =
requestGroup->getDownloadContext();
if(dctx->hasAttribute(CTX_ATTR_BT)) {
if(bittorrent::getTorrentAttrs(dctx)->metadata.empty()) {
return true;
public:
virtual bool match(const RequestGroup* requestGroup) const CXX11_OVERRIDE
{
auto& dctx = requestGroup->getDownloadContext();
if(dctx->hasAttribute(CTX_ATTR_BT)) {
if(bittorrent::getTorrentAttrs(dctx)->metadata.empty()) {
return true;
}
}
return false;
}
return false;
}
};
} // namespace
UTMetadataPostDownloadHandler::UTMetadataPostDownloadHandler()
{
std::shared_ptr<Criteria> cri(new Criteria());
setCriteria(cri);
setCriteria(make_unique<Criteria>());
}
void UTMetadataPostDownloadHandler::getNextRequestGroups
(std::vector<std::shared_ptr<RequestGroup> >& groups, RequestGroup* requestGroup)
(std::vector<std::shared_ptr<RequestGroup> >& groups,
RequestGroup* requestGroup) const
{
const std::shared_ptr<DownloadContext>& dctx =requestGroup->getDownloadContext();
auto& dctx =requestGroup->getDownloadContext();
auto attrs = bittorrent::getTorrentAttrs(dctx);
std::string metadata =
util::toString(requestGroup->getPieceStorage()->getDiskAdaptor());
@ -92,7 +96,7 @@ void UTMetadataPostDownloadHandler::getNextRequestGroups
}
}
if(!requestGroup->getOption()->getAsBool(PREF_BT_METADATA_ONLY)) {
std::vector<std::shared_ptr<RequestGroup> > newRgs;
std::vector<std::shared_ptr<RequestGroup>> newRgs;
// Don't adjust announce URI because it has been done when
// RequestGroup is created with magnet URI.
createRequestGroupForBitTorrent(newRgs, requestGroup->getOption(),

View File

@ -43,17 +43,12 @@ namespace aria2 {
class UTMetadataPostDownloadHandler:public PostDownloadHandler
{
private:
class Criteria:public RequestGroupCriteria
{
public:
virtual bool match(const RequestGroup* requestGroup) const CXX11_OVERRIDE;
};
public:
UTMetadataPostDownloadHandler();
virtual void
getNextRequestGroups(std::vector<std::shared_ptr<RequestGroup> >& groups,
RequestGroup* requestGroup) CXX11_OVERRIDE;
RequestGroup* requestGroup) const CXX11_OVERRIDE;
};
} // namespace aria2

134
src/download_handlers.cc Normal file
View File

@ -0,0 +1,134 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 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 "download_handlers.h"
#include "DownloadHandlerConstants.h"
#include "ContentTypeRequestGroupCriteria.h"
#include "MemoryBufferPreDownloadHandler.h"
#include "a2functional.h"
#ifdef ENABLE_METALINK
# include "MetalinkPostDownloadHandler.h"
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
# include "BtPostDownloadHandler.h"
# include "MemoryBencodePreDownloadHandler.h"
# include "UTMetadataPostDownloadHandler.h"
#endif // ENABLE_BITTORRENT
namespace aria2 {
namespace download_handlers {
namespace {
std::unique_ptr<PreDownloadHandler> memoryPreDownloadHandler;
} // namespace
const PreDownloadHandler* getMemoryPreDownloadHandler()
{
if(!memoryPreDownloadHandler) {
memoryPreDownloadHandler = make_unique<MemoryBufferPreDownloadHandler>();
}
return memoryPreDownloadHandler.get();
}
#ifdef ENABLE_METALINK
namespace {
std::unique_ptr<PreDownloadHandler> metalinkPreDownloadHandler;
std::unique_ptr<PostDownloadHandler> metalinkPostDownloadHandler;
} // namespace
const PreDownloadHandler* getMetalinkPreDownloadHandler()
{
if(!metalinkPreDownloadHandler) {
metalinkPreDownloadHandler = make_unique<MemoryBufferPreDownloadHandler>();
metalinkPreDownloadHandler->setCriteria
(make_unique<ContentTypeRequestGroupCriteria>(getMetalinkContentTypes(),
getMetalinkExtensions()));
}
return metalinkPreDownloadHandler.get();
}
const PostDownloadHandler* getMetalinkPostDownloadHandler()
{
if(!metalinkPostDownloadHandler) {
metalinkPostDownloadHandler = make_unique<MetalinkPostDownloadHandler>();
}
return metalinkPostDownloadHandler.get();
}
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
namespace {
std::unique_ptr<PreDownloadHandler> btPreDownloadHandler;
std::unique_ptr<PostDownloadHandler> btPostDownloadHandler;
std::unique_ptr<PostDownloadHandler> btMetadataPostDownloadHandler;
} // namespace
const PreDownloadHandler* getBtPreDownloadHandler()
{
if(!btPreDownloadHandler) {
btPreDownloadHandler =
make_unique<bittorrent::MemoryBencodePreDownloadHandler>();
btPreDownloadHandler->setCriteria
(make_unique<ContentTypeRequestGroupCriteria>(getBtContentTypes(),
getBtExtensions()));
}
return btPreDownloadHandler.get();
}
const PostDownloadHandler* getBtPostDownloadHandler()
{
if(!btPostDownloadHandler) {
btPostDownloadHandler = make_unique<BtPostDownloadHandler>();
}
return btPostDownloadHandler.get();
}
const PostDownloadHandler* getUTMetadataPostDownloadHandler()
{
if(!btMetadataPostDownloadHandler) {
btMetadataPostDownloadHandler =
make_unique<UTMetadataPostDownloadHandler>();
}
return btMetadataPostDownloadHandler.get();
}
#endif // ENABLE_BITTORRENT
} // namespace download_handlers
} // namespace aria2

View File

@ -32,26 +32,39 @@
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_TRUE_REQUEST_GROUP_CRITERIA_H
#define D_TRUE_REQUEST_GROUP_CRITERIA_H
#ifndef D_DOWNLOAD_HANDLER_FACTORY_H
#define D_DOWNLOAD_HANDLER_FACTORY_H
#include "RequestGroupCriteria.h"
#include "common.h"
#include <memory>
namespace aria2 {
class TrueRequestGroupCriteria:public RequestGroupCriteria
{
public:
TrueRequestGroupCriteria() {}
class PreDownloadHandler;
class PostDownloadHandler;
virtual ~TrueRequestGroupCriteria() {}
namespace download_handlers {
virtual bool match(const RequestGroup* requestGroup) const CXX11_OVERRIDE
{
return true;
}
};
const PreDownloadHandler* getMemoryPreDownloadHandler();
#ifdef ENABLE_METALINK
const PreDownloadHandler* getMetalinkPreDownloadHandler();
const PostDownloadHandler* getMetalinkPostDownloadHandler();
#endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT
const PreDownloadHandler* getBtPreDownloadHandler();
const PostDownloadHandler* getBtPostDownloadHandler();
const PostDownloadHandler* getUTMetadataPostDownloadHandler();
#endif // ENABLE_BITTORRENT
} // namespace download_handlers
} // namespace aria2
#endif // D_TRUE_REQUEST_GROUP_CRITERIA_H
#endif // D_DOWNLOAD_HANDLER_FACTORY_H

View File

@ -61,10 +61,10 @@
#include "MetadataInfo.h"
#include "OptionParser.h"
#include "SegList.h"
#include "download_handlers.h"
#ifdef ENABLE_BITTORRENT
# include "bittorrent_helper.h"
# include "BtConstants.h"
# include "UTMetadataPostDownloadHandler.h"
# include "ValueBaseBencodeParser.h"
#endif // ENABLE_BITTORRENT
@ -244,9 +244,8 @@ createBtMagnetRequestGroup
dctx->getFirstFileEntry()->setPath(torrentAttrs->name);
rg->setDownloadContext(dctx);
rg->clearPostDownloadHandler();
auto utMetadataPostHandler =
std::make_shared<UTMetadataPostDownloadHandler>();
rg->addPostDownloadHandler(utMetadataPostHandler);
rg->addPostDownloadHandler
(download_handlers::getUTMetadataPostDownloadHandler());
rg->setDiskWriterFactory(std::make_shared<ByteArrayDiskWriterFactory>());
rg->setMetadataInfo(createMetadataInfo(gid, magnetLink));
rg->markInMemoryDownload();

View File

@ -9,6 +9,7 @@
#include "bittorrent_helper.h"
#include "PieceStorage.h"
#include "DiskAdaptor.h"
#include "RequestGroupCriteria.h"
namespace aria2 {

View File

@ -1,4 +1,4 @@
#include "DownloadHandlerFactory.h"
#include "download_handlers.h"
#include <cppunit/extensions/HelperMacros.h>
@ -7,12 +7,14 @@
#include "DownloadContext.h"
#include "MemoryBufferPreDownloadHandler.h"
#include "FileEntry.h"
#include "RequestGroupCriteria.h"
namespace aria2 {
class DownloadHandlerFactoryTest:public CppUnit::TestFixture {
class DownloadHandlersTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DownloadHandlerFactoryTest);
CPPUNIT_TEST_SUITE(DownloadHandlersTest);
CPPUNIT_TEST(testGetMemoryPreDownloadHandler);
#ifdef ENABLE_METALINK
CPPUNIT_TEST(testGetMetalinkPreDownloadHandler_extension);
CPPUNIT_TEST(testGetMetalinkPreDownloadHandler_contentType);
@ -29,8 +31,9 @@ private:
public:
void setUp()
{
option_.reset(new Option());
option_ = std::make_shared<Option>();
}
void testGetMemoryPreDownloadHandler();
#ifdef ENABLE_METALINK
void testGetMetalinkPreDownloadHandler_extension();
void testGetMetalinkPreDownloadHandler_contentType();
@ -44,17 +47,23 @@ public:
};
CPPUNIT_TEST_SUITE_REGISTRATION( DownloadHandlerFactoryTest );
CPPUNIT_TEST_SUITE_REGISTRATION( DownloadHandlersTest );
void DownloadHandlersTest::testGetMemoryPreDownloadHandler()
{
CPPUNIT_ASSERT(download_handlers::getMemoryPreDownloadHandler()
->canHandle(nullptr));
}
#ifdef ENABLE_METALINK
void DownloadHandlerFactoryTest::testGetMetalinkPreDownloadHandler_extension()
void DownloadHandlersTest::testGetMetalinkPreDownloadHandler_extension()
{
std::shared_ptr<DownloadContext> dctx(new DownloadContext(0, 0, "test.metalink"));
auto dctx = std::make_shared<DownloadContext>(0, 0, "test.metalink");
RequestGroup rg(GroupId::create(), option_);
rg.setDownloadContext(dctx);
std::shared_ptr<PreDownloadHandler> handler = DownloadHandlerFactory::getMetalinkPreDownloadHandler();
auto handler = download_handlers::getMetalinkPreDownloadHandler();
CPPUNIT_ASSERT(handler->canHandle(&rg));
@ -62,14 +71,14 @@ void DownloadHandlerFactoryTest::testGetMetalinkPreDownloadHandler_extension()
CPPUNIT_ASSERT(!handler->canHandle(&rg));
}
void DownloadHandlerFactoryTest::testGetMetalinkPreDownloadHandler_contentType()
void DownloadHandlersTest::testGetMetalinkPreDownloadHandler_contentType()
{
std::shared_ptr<DownloadContext> dctx(new DownloadContext(0, 0, "test"));
auto dctx = std::make_shared<DownloadContext>(0, 0, "test");
dctx->getFirstFileEntry()->setContentType("application/metalink+xml");
RequestGroup rg(GroupId::create(), option_);
rg.setDownloadContext(dctx);
std::shared_ptr<PreDownloadHandler> handler = DownloadHandlerFactory::getMetalinkPreDownloadHandler();
auto handler = download_handlers::getMetalinkPreDownloadHandler();
CPPUNIT_ASSERT(handler->canHandle(&rg));
@ -81,14 +90,14 @@ void DownloadHandlerFactoryTest::testGetMetalinkPreDownloadHandler_contentType()
#ifdef ENABLE_BITTORRENT
void DownloadHandlerFactoryTest::testGetBtPreDownloadHandler_extension()
void DownloadHandlersTest::testGetBtPreDownloadHandler_extension()
{
std::shared_ptr<DownloadContext> dctx
(new DownloadContext(0, 0, A2_TEST_DIR"/test.torrent"));
auto dctx = std::make_shared<DownloadContext>(0, 0,
A2_TEST_DIR"/test.torrent");
RequestGroup rg(GroupId::create(), option_);
rg.setDownloadContext(dctx);
std::shared_ptr<PreDownloadHandler> handler = DownloadHandlerFactory::getBtPreDownloadHandler();
auto handler = download_handlers::getBtPreDownloadHandler();
CPPUNIT_ASSERT(handler->canHandle(&rg));
@ -96,14 +105,14 @@ void DownloadHandlerFactoryTest::testGetBtPreDownloadHandler_extension()
CPPUNIT_ASSERT(!handler->canHandle(&rg));
}
void DownloadHandlerFactoryTest::testGetBtPreDownloadHandler_contentType()
void DownloadHandlersTest::testGetBtPreDownloadHandler_contentType()
{
std::shared_ptr<DownloadContext> dctx(new DownloadContext(0, 0, "test"));
auto dctx = std::make_shared<DownloadContext>(0, 0, "test");
dctx->getFirstFileEntry()->setContentType("application/x-bittorrent");
RequestGroup rg(GroupId::create(), option_);
rg.setDownloadContext(dctx);
std::shared_ptr<PreDownloadHandler> handler = DownloadHandlerFactory::getBtPreDownloadHandler();
auto handler = download_handlers::getBtPreDownloadHandler();
CPPUNIT_ASSERT(handler->canHandle(&rg));

View File

@ -42,7 +42,7 @@ aria2c_SOURCES = AllTest.cc\
ProtocolDetectorTest.cc\
ExceptionTest.cc\
FmtTest.cc\
DownloadHandlerFactoryTest.cc\
DownloadHandlersTest.cc\
SignatureTest.cc\
ServerStatManTest.cc\
FeedbackURISelectorTest.cc\

View File

@ -8,6 +8,7 @@
#include "FileEntry.h"
#include "PieceStorage.h"
#include "DiskAdaptor.h"
#include "RequestGroupCriteria.h"
namespace aria2 {