mirror of https://github.com/aria2/aria2
2007-12-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
If several protocols are available for a mirror, aria2 now use one of them. --metalink-preferred-protocol option was added to specify the preference of protocol. * src/AbstractCommand.cc * src/OptionHandlerFactory.cc * src/ServerHost.{h, cc} * src/Metalink2RequestGroup.cc * src/RequestGroup.{h, cc} * test/RequestGroupTest.cc * src/option_processing.cc * src/prefs.h * src/HttpResponseCommand.cc * src/MetalinkResource.{h, cc} * src/FtpNegotiationCommand.cc * src/MetalinkEntry.{h, cc} * src/MetalinkEntryTest.ccpull/1/head
parent
ae2555313b
commit
fca7b9d7e4
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
2007-12-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
If several protocols are available for a mirror, aria2 now use one of
|
||||||
|
them. --metalink-preferred-protocol option was added to specify the
|
||||||
|
preference of protocol.
|
||||||
|
* src/AbstractCommand.cc
|
||||||
|
* src/OptionHandlerFactory.cc
|
||||||
|
* src/ServerHost.{h, cc}
|
||||||
|
* src/Metalink2RequestGroup.cc
|
||||||
|
* src/RequestGroup.{h, cc}
|
||||||
|
* test/RequestGroupTest.cc
|
||||||
|
* src/option_processing.cc
|
||||||
|
* src/prefs.h
|
||||||
|
* src/HttpResponseCommand.cc
|
||||||
|
* src/MetalinkResource.{h, cc}
|
||||||
|
* src/FtpNegotiationCommand.cc
|
||||||
|
* src/MetalinkEntry.{h, cc}
|
||||||
|
* src/MetalinkEntryTest.cc
|
||||||
|
|
||||||
2007-12-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2007-12-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Code cleanup and added debug log.
|
Code cleanup and added debug log.
|
||||||
|
|
|
@ -160,6 +160,7 @@ bool AbstractCommand::execute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCommand::tryReserved() {
|
void AbstractCommand::tryReserved() {
|
||||||
|
_requestGroup->removeServerHost(cuid);
|
||||||
Commands commands = _requestGroup->createNextCommand(e, 1);
|
Commands commands = _requestGroup->createNextCommand(e, 1);
|
||||||
e->addCommand(commands);
|
e->addCommand(commands);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "DefaultBtProgressInfoFile.h"
|
#include "DefaultBtProgressInfoFile.h"
|
||||||
#include "RequestGroupMan.h"
|
#include "RequestGroupMan.h"
|
||||||
#include "DownloadFailureException.h"
|
#include "DownloadFailureException.h"
|
||||||
|
#include "ServerHost.h"
|
||||||
|
|
||||||
FtpNegotiationCommand::FtpNegotiationCommand(int32_t cuid,
|
FtpNegotiationCommand::FtpNegotiationCommand(int32_t cuid,
|
||||||
const RequestHandle& req,
|
const RequestHandle& req,
|
||||||
|
@ -73,6 +74,9 @@ bool FtpNegotiationCommand::executeInternal() {
|
||||||
command->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
|
command->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
|
||||||
command->setStartupIdleTime(e->option->getAsInt(PREF_STARTUP_IDLE_TIME));
|
command->setStartupIdleTime(e->option->getAsInt(PREF_STARTUP_IDLE_TIME));
|
||||||
command->setLowestDownloadSpeedLimit(e->option->getAsInt(PREF_LOWEST_SPEED_LIMIT));
|
command->setLowestDownloadSpeedLimit(e->option->getAsInt(PREF_LOWEST_SPEED_LIMIT));
|
||||||
|
if(!_requestGroup->isSingleHostMultiConnectionEnabled()) {
|
||||||
|
_requestGroup->removeURIWhoseHostnameIs(_requestGroup->searchServerHost(cuid)->getHostname());
|
||||||
|
}
|
||||||
e->commands.push_back(command);
|
e->commands.push_back(command);
|
||||||
return true;
|
return true;
|
||||||
} else if(sequence == SEQ_HEAD_OK || sequence == SEQ_DOWNLOAD_ALREADY_COMPLETED) {
|
} else if(sequence == SEQ_HEAD_OK || sequence == SEQ_DOWNLOAD_ALREADY_COMPLETED) {
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "DefaultBtProgressInfoFile.h"
|
#include "DefaultBtProgressInfoFile.h"
|
||||||
#include "RequestGroupMan.h"
|
#include "RequestGroupMan.h"
|
||||||
#include "DownloadFailureException.h"
|
#include "DownloadFailureException.h"
|
||||||
|
#include "ServerHost.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -85,6 +86,9 @@ bool HttpResponseCommand::executeInternal()
|
||||||
e->noWait = true;
|
e->noWait = true;
|
||||||
return prepareForRetry(0);
|
return prepareForRetry(0);
|
||||||
}
|
}
|
||||||
|
if(!_requestGroup->isSingleHostMultiConnectionEnabled()) {
|
||||||
|
_requestGroup->removeURIWhoseHostnameIs(_requestGroup->searchServerHost(cuid)->getHostname());
|
||||||
|
}
|
||||||
if(_requestGroup->getPieceStorage().isNull()) {
|
if(_requestGroup->getPieceStorage().isNull()) {
|
||||||
int64_t totalLength = httpResponse->getEntityLength();
|
int64_t totalLength = httpResponse->getEntityLength();
|
||||||
SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
|
SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
|
||||||
|
|
|
@ -146,7 +146,8 @@ SRCS = Socket.h\
|
||||||
BtRegistry.cc BtRegistry.h\
|
BtRegistry.cc BtRegistry.h\
|
||||||
MultiFileAllocationIterator.cc MultiFileAllocationIterator.h\
|
MultiFileAllocationIterator.cc MultiFileAllocationIterator.h\
|
||||||
PeerConnection.cc PeerConnection.h\
|
PeerConnection.cc PeerConnection.h\
|
||||||
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h
|
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
|
||||||
|
ServerHost.cc
|
||||||
# debug_new.cpp
|
# debug_new.cpp
|
||||||
|
|
||||||
if ENABLE_MESSAGE_DIGEST
|
if ENABLE_MESSAGE_DIGEST
|
||||||
|
|
|
@ -291,7 +291,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
||||||
BtRegistry.cc BtRegistry.h MultiFileAllocationIterator.cc \
|
BtRegistry.cc BtRegistry.h MultiFileAllocationIterator.cc \
|
||||||
MultiFileAllocationIterator.h PeerConnection.cc \
|
MultiFileAllocationIterator.h PeerConnection.cc \
|
||||||
PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
|
PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
|
||||||
IteratableChunkChecksumValidator.cc \
|
ServerHost.cc IteratableChunkChecksumValidator.cc \
|
||||||
IteratableChunkChecksumValidator.h \
|
IteratableChunkChecksumValidator.h \
|
||||||
IteratableChecksumValidator.cc IteratableChecksumValidator.h \
|
IteratableChecksumValidator.cc IteratableChecksumValidator.h \
|
||||||
CheckIntegrityCommand.cc CheckIntegrityCommand.h \
|
CheckIntegrityCommand.cc CheckIntegrityCommand.h \
|
||||||
|
@ -524,11 +524,11 @@ am__objects_12 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
|
||||||
DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT) \
|
DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT) \
|
||||||
Peer.$(OBJEXT) BtRegistry.$(OBJEXT) \
|
Peer.$(OBJEXT) BtRegistry.$(OBJEXT) \
|
||||||
MultiFileAllocationIterator.$(OBJEXT) PeerConnection.$(OBJEXT) \
|
MultiFileAllocationIterator.$(OBJEXT) PeerConnection.$(OBJEXT) \
|
||||||
ByteArrayDiskWriter.$(OBJEXT) $(am__objects_1) \
|
ByteArrayDiskWriter.$(OBJEXT) ServerHost.$(OBJEXT) \
|
||||||
$(am__objects_2) $(am__objects_3) $(am__objects_4) \
|
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||||
$(am__objects_5) $(am__objects_6) $(am__objects_7) \
|
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
|
||||||
$(am__objects_8) $(am__objects_9) $(am__objects_10) \
|
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
|
||||||
$(am__objects_11)
|
$(am__objects_10) $(am__objects_11)
|
||||||
am_libaria2c_a_OBJECTS = $(am__objects_12)
|
am_libaria2c_a_OBJECTS = $(am__objects_12)
|
||||||
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
||||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||||
|
@ -817,7 +817,7 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
|
||||||
BtRegistry.cc BtRegistry.h MultiFileAllocationIterator.cc \
|
BtRegistry.cc BtRegistry.h MultiFileAllocationIterator.cc \
|
||||||
MultiFileAllocationIterator.h PeerConnection.cc \
|
MultiFileAllocationIterator.h PeerConnection.cc \
|
||||||
PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
|
PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
|
||||||
$(am__append_1) $(am__append_2) $(am__append_3) \
|
ServerHost.cc $(am__append_1) $(am__append_2) $(am__append_3) \
|
||||||
$(am__append_4) $(am__append_5) $(am__append_6) \
|
$(am__append_4) $(am__append_5) $(am__append_6) \
|
||||||
$(am__append_7) $(am__append_8) $(am__append_9) \
|
$(am__append_7) $(am__append_8) $(am__append_9) \
|
||||||
$(am__append_10) $(am__append_11)
|
$(am__append_10) $(am__append_11)
|
||||||
|
@ -1075,6 +1075,7 @@ distclean-compile:
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ResourcesMetalinkParserState.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ResourcesMetalinkParserState.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SeedCheckCommand.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SeedCheckCommand.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentMan.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentMan.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerHost.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitor.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitor.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleBtMessage.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleBtMessage.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@
|
||||||
|
|
|
@ -133,6 +133,9 @@ RequestGroups Metalink2RequestGroup::createRequestGroup(MetalinkEntries entries)
|
||||||
Util::slice(locations, _option->get(PREF_METALINK_LOCATION), ',', true);
|
Util::slice(locations, _option->get(PREF_METALINK_LOCATION), ',', true);
|
||||||
entry->setLocationPreference(locations, 100);
|
entry->setLocationPreference(locations, 100);
|
||||||
}
|
}
|
||||||
|
if(_option->get(PREF_METALINK_PREFERRED_PROTOCOL) != V_NONE) {
|
||||||
|
entry->setProtocolPreference(_option->get(PREF_METALINK_PREFERRED_PROTOCOL), 100);
|
||||||
|
}
|
||||||
if(useIndex) {
|
if(useIndex) {
|
||||||
if(find(selectIndexes.begin(), selectIndexes.end(), count+1) == selectIndexes.end()) {
|
if(find(selectIndexes.begin(), selectIndexes.end(), count+1) == selectIndexes.end()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -206,6 +209,8 @@ RequestGroups Metalink2RequestGroup::createRequestGroup(MetalinkEntries entries)
|
||||||
rg->setNumConcurrentCommand(entry->maxConnections < 0 ?
|
rg->setNumConcurrentCommand(entry->maxConnections < 0 ?
|
||||||
_option->getAsInt(PREF_METALINK_SERVERS) :
|
_option->getAsInt(PREF_METALINK_SERVERS) :
|
||||||
min<int32_t>(_option->getAsInt(PREF_METALINK_SERVERS), entry->maxConnections));
|
min<int32_t>(_option->getAsInt(PREF_METALINK_SERVERS), entry->maxConnections));
|
||||||
|
// In metalink, multi connection to a single host is not allowed.
|
||||||
|
rg->setSingleHostMultiConnectionEnabled(false);
|
||||||
|
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
// Inject depenency between rg and torrentRg here if torrentRg.isNull() == false
|
// Inject depenency between rg and torrentRg here if torrentRg.isNull() == false
|
||||||
|
|
|
@ -74,6 +74,29 @@ void MetalinkEntry::setLocationPreference(const Strings& locations,
|
||||||
AddLocationPreference(locations, preferenceToAdd));
|
AddLocationPreference(locations, preferenceToAdd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AddProtocolPreference {
|
||||||
|
private:
|
||||||
|
const string& _protocol;
|
||||||
|
int32_t _preferenceToAdd;
|
||||||
|
public:
|
||||||
|
AddProtocolPreference(const string& protocol, int32_t prefToAdd):
|
||||||
|
_protocol(protocol), _preferenceToAdd(prefToAdd) {}
|
||||||
|
|
||||||
|
void operator()(const MetalinkResourceHandle& res) const
|
||||||
|
{
|
||||||
|
if(_protocol == MetalinkResource::getTypeString(res->type)) {
|
||||||
|
res->preference += _preferenceToAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void MetalinkEntry::setProtocolPreference(const string& protocol,
|
||||||
|
int32_t preferenceToAdd)
|
||||||
|
{
|
||||||
|
for_each(resources.begin(), resources.end(),
|
||||||
|
AddProtocolPreference(protocol, preferenceToAdd));
|
||||||
|
}
|
||||||
|
|
||||||
class PrefOrder {
|
class PrefOrder {
|
||||||
public:
|
public:
|
||||||
bool operator()(const MetalinkResourceHandle& res1,
|
bool operator()(const MetalinkResourceHandle& res1,
|
||||||
|
|
|
@ -96,6 +96,7 @@ public:
|
||||||
void reorderResourcesByPreference();
|
void reorderResourcesByPreference();
|
||||||
|
|
||||||
void setLocationPreference(const Strings& locations, int32_t preferenceToAdd);
|
void setLocationPreference(const Strings& locations, int32_t preferenceToAdd);
|
||||||
|
void setProtocolPreference(const string& protocol, int32_t preferenceToAdd);
|
||||||
|
|
||||||
static FileEntries toFileEntry(const MetalinkEntries& metalinkEntries);
|
static FileEntries toFileEntry(const MetalinkEntries& metalinkEntries);
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "MetalinkResource.h"
|
#include "MetalinkResource.h"
|
||||||
|
|
||||||
|
string MetalinkResource::type2String[] = {
|
||||||
|
"ftp", "http", "https", "bittorrent", "not_supported"
|
||||||
|
};
|
||||||
|
|
||||||
MetalinkResource::MetalinkResource():
|
MetalinkResource::MetalinkResource():
|
||||||
maxConnections(-1)
|
maxConnections(-1)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -40,12 +40,14 @@
|
||||||
class MetalinkResource {
|
class MetalinkResource {
|
||||||
public:
|
public:
|
||||||
enum TYPE {
|
enum TYPE {
|
||||||
TYPE_FTP,
|
TYPE_FTP = 0,
|
||||||
TYPE_HTTP,
|
TYPE_HTTP,
|
||||||
TYPE_HTTPS,
|
TYPE_HTTPS,
|
||||||
TYPE_BITTORRENT,
|
TYPE_BITTORRENT,
|
||||||
TYPE_NOT_SUPPORTED
|
TYPE_NOT_SUPPORTED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static string type2String[];
|
||||||
public:
|
public:
|
||||||
string url;
|
string url;
|
||||||
TYPE type;
|
TYPE type;
|
||||||
|
@ -66,6 +68,11 @@ public:
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const string& getTypeString(TYPE type)
|
||||||
|
{
|
||||||
|
return type2String[type];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<MetalinkResource> MetalinkResourceHandle;
|
typedef SharedHandle<MetalinkResource> MetalinkResourceHandle;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "OptionHandlerFactory.h"
|
#include "OptionHandlerFactory.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "OptionHandlerImpl.h"
|
#include "OptionHandlerImpl.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
|
||||||
OptionHandlers OptionHandlerFactory::createOptionHandlers()
|
OptionHandlers OptionHandlerFactory::createOptionHandlers()
|
||||||
{
|
{
|
||||||
|
@ -102,6 +103,11 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
|
||||||
handlers.push_back(new UnitNumberOptionHandler(PREF_NO_FILE_ALLOCATION_LIMIT, 0));
|
handlers.push_back(new UnitNumberOptionHandler(PREF_NO_FILE_ALLOCATION_LIMIT, 0));
|
||||||
handlers.push_back(new BooleanOptionHandler(PREF_ENABLE_DIRECT_IO));
|
handlers.push_back(new BooleanOptionHandler(PREF_ENABLE_DIRECT_IO));
|
||||||
handlers.push_back(new BooleanOptionHandler(PREF_ALLOW_PIECE_LENGTH_CHANGE));
|
handlers.push_back(new BooleanOptionHandler(PREF_ALLOW_PIECE_LENGTH_CHANGE));
|
||||||
|
{
|
||||||
|
const char* params[] = { V_HTTP, V_HTTPS, V_FTP, V_NONE };
|
||||||
|
handlers.push_back(new ParameterOptionHandler(PREF_METALINK_PREFERRED_PROTOCOL,
|
||||||
|
Strings(¶ms[0], ¶ms[arrayLength(params)])));
|
||||||
|
}
|
||||||
|
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include "DownloadHandlerFactory.h"
|
#include "DownloadHandlerFactory.h"
|
||||||
#include "MemoryBufferPreDownloadHandler.h"
|
#include "MemoryBufferPreDownloadHandler.h"
|
||||||
#include "DownloadHandlerConstants.h"
|
#include "DownloadHandlerConstants.h"
|
||||||
|
#include "ServerHost.h"
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
# include "CheckIntegrityCommand.h"
|
# include "CheckIntegrityCommand.h"
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
@ -97,6 +98,7 @@ RequestGroup::RequestGroup(const Option* option,
|
||||||
_preLocalFileCheckEnabled(true),
|
_preLocalFileCheckEnabled(true),
|
||||||
_haltRequested(false),
|
_haltRequested(false),
|
||||||
_forceHaltRequested(false),
|
_forceHaltRequested(false),
|
||||||
|
_singleHostMultiConnectionEnabled(true),
|
||||||
_option(option),
|
_option(option),
|
||||||
_logger(LogFactory::getInstance())
|
_logger(LogFactory::getInstance())
|
||||||
{
|
{
|
||||||
|
@ -381,18 +383,28 @@ Commands RequestGroup::createNextCommandWithAdj(DownloadEngine* e, int32_t numAd
|
||||||
Commands RequestGroup::createNextCommand(DownloadEngine* e, int32_t numCommand, const string& method)
|
Commands RequestGroup::createNextCommand(DownloadEngine* e, int32_t numCommand, const string& method)
|
||||||
{
|
{
|
||||||
Commands commands;
|
Commands commands;
|
||||||
|
Strings pendingURIs;
|
||||||
for(;!_uris.empty() && numCommand--; _uris.pop_front()) {
|
for(;!_uris.empty() && numCommand--; _uris.pop_front()) {
|
||||||
string uri = _uris.front();
|
string uri = _uris.front();
|
||||||
_spentUris.push_back(uri);
|
|
||||||
RequestHandle req = new Request();
|
RequestHandle req = new Request();
|
||||||
|
if(req->setUrl(uri)) {
|
||||||
|
ServerHostHandle sv = _singleHostMultiConnectionEnabled ? 0 : searchServerHost(req->getHost());
|
||||||
|
if(sv.isNull()) {
|
||||||
|
_spentUris.push_back(uri);
|
||||||
req->setReferer(_option->get(PREF_REFERER));
|
req->setReferer(_option->get(PREF_REFERER));
|
||||||
req->setMethod(method);
|
req->setMethod(method);
|
||||||
if(req->setUrl(uri)) {
|
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(), req, this, e);
|
||||||
commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(), req, this, e));
|
ServerHostHandle sv = new ServerHost(command->getCuid(), req->getHost());
|
||||||
|
registerServerHost(sv);
|
||||||
|
commands.push_back(command);
|
||||||
|
} else {
|
||||||
|
pendingURIs.push_front(uri);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_logger->error(MSG_UNRECOGNIZED_URI, req->getUrl().c_str());
|
_logger->error(MSG_UNRECOGNIZED_URI, req->getUrl().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
copy(pendingURIs.begin(), pendingURIs.end(), front_inserter(_uris));
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,3 +756,78 @@ DownloadResultHandle RequestGroup::createDownloadResult() const
|
||||||
DownloadResult::FINISHED :
|
DownloadResult::FINISHED :
|
||||||
DownloadResult::NOT_YET);
|
DownloadResult::NOT_YET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestGroup::registerServerHost(const ServerHostHandle& serverHost)
|
||||||
|
{
|
||||||
|
_serverHosts.push_back(serverHost);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FindServerHostByCUID
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int32_t _cuid;
|
||||||
|
public:
|
||||||
|
FindServerHostByCUID(int32_t cuid):_cuid(cuid) {}
|
||||||
|
|
||||||
|
bool operator()(const ServerHostHandle& sv) const
|
||||||
|
{
|
||||||
|
return sv->getCuid() == _cuid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerHostHandle RequestGroup::searchServerHost(int32_t cuid) const
|
||||||
|
{
|
||||||
|
ServerHosts::const_iterator itr = find_if(_serverHosts.begin(),
|
||||||
|
_serverHosts.end(),
|
||||||
|
FindServerHostByCUID(cuid));
|
||||||
|
if(itr == _serverHosts.end()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return *itr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FindServerHostByHostname
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const string& _hostname;
|
||||||
|
public:
|
||||||
|
FindServerHostByHostname(const string& hostname):_hostname(hostname) {}
|
||||||
|
|
||||||
|
bool operator()(const ServerHostHandle& sv) const
|
||||||
|
{
|
||||||
|
return sv->getHostname() == _hostname;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerHostHandle RequestGroup::searchServerHost(const string& hostname) const
|
||||||
|
{
|
||||||
|
ServerHosts::const_iterator itr = find_if(_serverHosts.begin(),
|
||||||
|
_serverHosts.end(),
|
||||||
|
FindServerHostByHostname(hostname));
|
||||||
|
if(itr == _serverHosts.end()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return *itr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestGroup::removeServerHost(int32_t cuid)
|
||||||
|
{
|
||||||
|
remove_if(_serverHosts.begin(), _serverHosts.end(), FindServerHostByCUID(cuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestGroup::removeURIWhoseHostnameIs(const string& hostname)
|
||||||
|
{
|
||||||
|
Strings newURIs;
|
||||||
|
Request req;
|
||||||
|
for(Strings::const_iterator itr = _uris.begin(); itr != _uris.end(); ++itr) {
|
||||||
|
if((*itr).find(hostname) == string::npos ||
|
||||||
|
req.setUrl(*itr) && req.getHost() != hostname) {
|
||||||
|
newURIs.push_back(*itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_logger->debug("GUID#%d - Removed %d duplicate hostname URIs",
|
||||||
|
_gid, _uris.size()-newURIs.size());
|
||||||
|
_uris = newURIs;
|
||||||
|
}
|
||||||
|
|
|
@ -71,6 +71,9 @@ class CheckIntegrityEntry;
|
||||||
typedef SharedHandle<CheckIntegrityEntry> CheckIntegrityEntryHandle;
|
typedef SharedHandle<CheckIntegrityEntry> CheckIntegrityEntryHandle;
|
||||||
class DownloadResult;
|
class DownloadResult;
|
||||||
typedef SharedHandle<DownloadResult> DownloadResultHandle;
|
typedef SharedHandle<DownloadResult> DownloadResultHandle;
|
||||||
|
class ServerHost;
|
||||||
|
typedef SharedHandle<ServerHost> ServerHostHandle;
|
||||||
|
typedef deque<ServerHostHandle> ServerHosts;
|
||||||
|
|
||||||
class RequestGroup {
|
class RequestGroup {
|
||||||
private:
|
private:
|
||||||
|
@ -103,6 +106,8 @@ private:
|
||||||
|
|
||||||
DependencyHandle _dependency;
|
DependencyHandle _dependency;
|
||||||
|
|
||||||
|
ServerHosts _serverHosts;
|
||||||
|
|
||||||
bool _fileAllocationEnabled;
|
bool _fileAllocationEnabled;
|
||||||
|
|
||||||
bool _preLocalFileCheckEnabled;
|
bool _preLocalFileCheckEnabled;
|
||||||
|
@ -111,6 +116,8 @@ private:
|
||||||
|
|
||||||
bool _forceHaltRequested;
|
bool _forceHaltRequested;
|
||||||
|
|
||||||
|
bool _singleHostMultiConnectionEnabled;
|
||||||
|
|
||||||
PreDownloadHandlers _preDownloadHandlers;
|
PreDownloadHandlers _preDownloadHandlers;
|
||||||
|
|
||||||
PostDownloadHandlers _postDownloadHandlers;
|
PostDownloadHandlers _postDownloadHandlers;
|
||||||
|
@ -310,6 +317,33 @@ public:
|
||||||
{
|
{
|
||||||
return _option;
|
return _option;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isSingleHostMultiConnectionEnabled() const
|
||||||
|
{
|
||||||
|
return _singleHostMultiConnectionEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSingleHostMultiConnectionEnabled(bool f)
|
||||||
|
{
|
||||||
|
_singleHostMultiConnectionEnabled = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers given ServerHost.
|
||||||
|
*/
|
||||||
|
void registerServerHost(const ServerHostHandle& serverHost);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ServerHost whose cuid is given cuid. If it is not found, returns
|
||||||
|
* 0.
|
||||||
|
*/
|
||||||
|
ServerHostHandle searchServerHost(int32_t cuid) const;
|
||||||
|
|
||||||
|
ServerHostHandle searchServerHost(const string& hostname) const;
|
||||||
|
|
||||||
|
void removeServerHost(int32_t cuid);
|
||||||
|
|
||||||
|
void removeURIWhoseHostnameIs(const string& hostname);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<RequestGroup> RequestGroupHandle;
|
typedef SharedHandle<RequestGroup> RequestGroupHandle;
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* <!-- 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 "ServerHost.h"
|
||||||
|
|
||||||
|
ServerHost::ServerHost(int32_t cuid, const string& hostname):
|
||||||
|
_cuid(cuid), _hostname(hostname) {}
|
||||||
|
|
||||||
|
ServerHost::~ServerHost() {}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* <!-- 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_SERVER_HOST_H_
|
||||||
|
#define _D_SERVER_HOST_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
class ServerHost {
|
||||||
|
private:
|
||||||
|
int32_t _cuid;
|
||||||
|
|
||||||
|
string _hostname;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ServerHost(int32_t cuid, const string& hostname);
|
||||||
|
|
||||||
|
~ServerHost();
|
||||||
|
|
||||||
|
int32_t getCuid() const
|
||||||
|
{
|
||||||
|
return _cuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const string& getHostname() const
|
||||||
|
{
|
||||||
|
return _hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const ServerHost& server) const
|
||||||
|
{
|
||||||
|
return this->_cuid < server._cuid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SharedHandle<ServerHost> ServerHostHandle;
|
||||||
|
|
||||||
|
#endif // _D_SERVER_HOST_H_
|
|
@ -128,6 +128,7 @@ Option* option_processing(int argc, char* const argv[])
|
||||||
op->put(PREF_SEED_RATIO, "1.0");
|
op->put(PREF_SEED_RATIO, "1.0");
|
||||||
op->put(PREF_ENABLE_DIRECT_IO, V_FALSE);
|
op->put(PREF_ENABLE_DIRECT_IO, V_FALSE);
|
||||||
op->put(PREF_ALLOW_PIECE_LENGTH_CHANGE, V_FALSE);
|
op->put(PREF_ALLOW_PIECE_LENGTH_CHANGE, V_FALSE);
|
||||||
|
op->put(PREF_METALINK_PREFERRED_PROTOCOL, V_NONE);
|
||||||
while(1) {
|
while(1) {
|
||||||
int optIndex = 0;
|
int optIndex = 0;
|
||||||
int lopt;
|
int lopt;
|
||||||
|
@ -205,6 +206,7 @@ Option* option_processing(int argc, char* const argv[])
|
||||||
{ "metalink-os", required_argument, &lopt, 102 },
|
{ "metalink-os", required_argument, &lopt, 102 },
|
||||||
{ "follow-metalink", required_argument, &lopt, 103 },
|
{ "follow-metalink", required_argument, &lopt, 103 },
|
||||||
{ "metalink-location", required_argument, &lopt, 104 },
|
{ "metalink-location", required_argument, &lopt, 104 },
|
||||||
|
{ "metalink-preferred-protocol", required_argument, &lopt, 105 },
|
||||||
#endif // ENABLE_METALINK
|
#endif // ENABLE_METALINK
|
||||||
{ "version", no_argument, NULL, 'v' },
|
{ "version", no_argument, NULL, 'v' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
@ -300,6 +302,9 @@ Option* option_processing(int argc, char* const argv[])
|
||||||
case 104:
|
case 104:
|
||||||
cmdstream << PREF_METALINK_LOCATION << "=" << optarg << "\n";
|
cmdstream << PREF_METALINK_LOCATION << "=" << optarg << "\n";
|
||||||
break;
|
break;
|
||||||
|
case 105:
|
||||||
|
cmdstream << PREF_METALINK_PREFERRED_PROTOCOL << "=" << optarg << "\n";
|
||||||
|
break;
|
||||||
case 200:
|
case 200:
|
||||||
cmdstream << PREF_LOWEST_SPEED_LIMIT << "=" << optarg << "\n";
|
cmdstream << PREF_LOWEST_SPEED_LIMIT << "=" << optarg << "\n";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -225,5 +225,10 @@
|
||||||
#define PREF_METALINK_SERVERS "metalink-servers"
|
#define PREF_METALINK_SERVERS "metalink-servers"
|
||||||
// values: true | false | mem
|
// values: true | false | mem
|
||||||
#define PREF_FOLLOW_METALINK "follow-metalink"
|
#define PREF_FOLLOW_METALINK "follow-metalink"
|
||||||
|
// values: http | https | ftp | none
|
||||||
|
#define PREF_METALINK_PREFERRED_PROTOCOL "metalink-preferred-protocol"
|
||||||
|
# define V_HTTP "http"
|
||||||
|
# define V_HTTPS "https"
|
||||||
|
# define V_FTP "ftp"
|
||||||
|
|
||||||
#endif // _D_PREFS_H_
|
#endif // _D_PREFS_H_
|
||||||
|
|
|
@ -300,6 +300,10 @@ void showUsage() {
|
||||||
cout << _(" --metalink-location=LOCATION[,...] The location of the preferred server.\n"
|
cout << _(" --metalink-location=LOCATION[,...] The location of the preferred server.\n"
|
||||||
" A comma-deliminated list of locations is\n"
|
" A comma-deliminated list of locations is\n"
|
||||||
" acceptable.") << endl;
|
" acceptable.") << endl;
|
||||||
|
cout << _(" --metalink-preferred-protocol=PROTO Specify preferred protocol. The possible\n"
|
||||||
|
" values are 'http', 'https', 'ftp' and 'none'.\n"
|
||||||
|
" Specifiy none to disable this feature.") << "\n"
|
||||||
|
<< DEFAULT_MSG << "none" << "\n";
|
||||||
cout << _(" --follow-metalink=true|false|mem If true or mem is specified, when a file\n"
|
cout << _(" --follow-metalink=true|false|mem If true or mem is specified, when a file\n"
|
||||||
" whose suffix is .metaink or content type is\n"
|
" whose suffix is .metaink or content type is\n"
|
||||||
" application/metalink+xml is downloaded, aria2\n"
|
" application/metalink+xml is downloaded, aria2\n"
|
||||||
|
|
|
@ -9,6 +9,7 @@ class MetalinkEntryTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testDropUnsupportedResource);
|
CPPUNIT_TEST(testDropUnsupportedResource);
|
||||||
CPPUNIT_TEST(testReorderResourcesByPreference);
|
CPPUNIT_TEST(testReorderResourcesByPreference);
|
||||||
CPPUNIT_TEST(testSetLocationPreference);
|
CPPUNIT_TEST(testSetLocationPreference);
|
||||||
|
CPPUNIT_TEST(testSetProtocolPreference);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ public:
|
||||||
void testDropUnsupportedResource();
|
void testDropUnsupportedResource();
|
||||||
void testReorderResourcesByPreference();
|
void testReorderResourcesByPreference();
|
||||||
void testSetLocationPreference();
|
void testSetLocationPreference();
|
||||||
|
void testSetProtocolPreference();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,3 +124,14 @@ void MetalinkEntryTest::testSetLocationPreference()
|
||||||
CPPUNIT_ASSERT_EQUAL(string("JP"), entry->resources[4]->location);
|
CPPUNIT_ASSERT_EQUAL(string("JP"), entry->resources[4]->location);
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)190, entry->resources[4]->preference);
|
CPPUNIT_ASSERT_EQUAL((int32_t)190, entry->resources[4]->preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetalinkEntryTest::testSetProtocolPreference()
|
||||||
|
{
|
||||||
|
MetalinkEntryHandle entry = createTestEntry();
|
||||||
|
entry->setProtocolPreference("http", 1);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(50, entry->resources[0]->preference); // ftp
|
||||||
|
CPPUNIT_ASSERT_EQUAL(101, entry->resources[1]->preference); // http, +1
|
||||||
|
CPPUNIT_ASSERT_EQUAL(60, entry->resources[2]->preference); // bittorrent
|
||||||
|
CPPUNIT_ASSERT_EQUAL(10, entry->resources[3]->preference); // not supported
|
||||||
|
CPPUNIT_ASSERT_EQUAL(90, entry->resources[4]->preference); // https
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "RequestGroup.h"
|
#include "RequestGroup.h"
|
||||||
#include "prefs.h"
|
#include "ServerHost.h"
|
||||||
|
#include "Option.h"
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -7,12 +8,63 @@ using namespace std;
|
||||||
class RequestGroupTest : public CppUnit::TestFixture {
|
class RequestGroupTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(RequestGroupTest);
|
CPPUNIT_TEST_SUITE(RequestGroupTest);
|
||||||
|
CPPUNIT_TEST(testRegisterSearchRemove);
|
||||||
|
CPPUNIT_TEST(testRemoveURIWhoseHostnameIs);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setUp() {}
|
void setUp() {}
|
||||||
|
|
||||||
|
void testRegisterSearchRemove();
|
||||||
|
void testRemoveURIWhoseHostnameIs();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( RequestGroupTest );
|
CPPUNIT_TEST_SUITE_REGISTRATION( RequestGroupTest );
|
||||||
|
|
||||||
|
void RequestGroupTest::testRegisterSearchRemove()
|
||||||
|
{
|
||||||
|
Option op;
|
||||||
|
RequestGroup rg(&op, Strings());
|
||||||
|
ServerHostHandle sv1 = new ServerHost(1, "localhost1");
|
||||||
|
ServerHostHandle sv2 = new ServerHost(2, "localhost2");
|
||||||
|
ServerHostHandle sv3 = new ServerHost(3, "localhost3");
|
||||||
|
|
||||||
|
rg.registerServerHost(sv3);
|
||||||
|
rg.registerServerHost(sv1);
|
||||||
|
rg.registerServerHost(sv2);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(rg.searchServerHost(0).isNull());
|
||||||
|
|
||||||
|
{
|
||||||
|
ServerHostHandle sv = rg.searchServerHost(1);
|
||||||
|
CPPUNIT_ASSERT(!sv.isNull());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(string("localhost1"), sv->getHostname());
|
||||||
|
}
|
||||||
|
|
||||||
|
rg.removeServerHost(1);
|
||||||
|
|
||||||
|
{
|
||||||
|
ServerHostHandle sv = rg.searchServerHost(1);
|
||||||
|
CPPUNIT_ASSERT(sv.isNull());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ServerHostHandle sv = rg.searchServerHost(2);
|
||||||
|
CPPUNIT_ASSERT(!sv.isNull());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(string("localhost2"), sv->getHostname());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestGroupTest::testRemoveURIWhoseHostnameIs()
|
||||||
|
{
|
||||||
|
const char* uris[] = { "http://localhost/aria2.zip",
|
||||||
|
"ftp://localhost/aria2.zip",
|
||||||
|
"http://mirror/aria2.zip" };
|
||||||
|
Option op;
|
||||||
|
RequestGroup rg(&op, Strings(&uris[0], &uris[3]));
|
||||||
|
rg.removeURIWhoseHostnameIs("localhost");
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)1, rg.getRemainingUris().size());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(string("http://mirror/aria2.zip"),
|
||||||
|
rg.getRemainingUris()[0]);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue