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>
|
||||
|
||||
Code cleanup and added debug log.
|
||||
|
|
|
@ -160,6 +160,7 @@ bool AbstractCommand::execute() {
|
|||
}
|
||||
|
||||
void AbstractCommand::tryReserved() {
|
||||
_requestGroup->removeServerHost(cuid);
|
||||
Commands commands = _requestGroup->createNextCommand(e, 1);
|
||||
e->addCommand(commands);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "DefaultBtProgressInfoFile.h"
|
||||
#include "RequestGroupMan.h"
|
||||
#include "DownloadFailureException.h"
|
||||
#include "ServerHost.h"
|
||||
|
||||
FtpNegotiationCommand::FtpNegotiationCommand(int32_t cuid,
|
||||
const RequestHandle& req,
|
||||
|
@ -73,6 +74,9 @@ bool FtpNegotiationCommand::executeInternal() {
|
|||
command->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
|
||||
command->setStartupIdleTime(e->option->getAsInt(PREF_STARTUP_IDLE_TIME));
|
||||
command->setLowestDownloadSpeedLimit(e->option->getAsInt(PREF_LOWEST_SPEED_LIMIT));
|
||||
if(!_requestGroup->isSingleHostMultiConnectionEnabled()) {
|
||||
_requestGroup->removeURIWhoseHostnameIs(_requestGroup->searchServerHost(cuid)->getHostname());
|
||||
}
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
} else if(sequence == SEQ_HEAD_OK || sequence == SEQ_DOWNLOAD_ALREADY_COMPLETED) {
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "DefaultBtProgressInfoFile.h"
|
||||
#include "RequestGroupMan.h"
|
||||
#include "DownloadFailureException.h"
|
||||
#include "ServerHost.h"
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -85,6 +86,9 @@ bool HttpResponseCommand::executeInternal()
|
|||
e->noWait = true;
|
||||
return prepareForRetry(0);
|
||||
}
|
||||
if(!_requestGroup->isSingleHostMultiConnectionEnabled()) {
|
||||
_requestGroup->removeURIWhoseHostnameIs(_requestGroup->searchServerHost(cuid)->getHostname());
|
||||
}
|
||||
if(_requestGroup->getPieceStorage().isNull()) {
|
||||
int64_t totalLength = httpResponse->getEntityLength();
|
||||
SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
|
||||
|
|
|
@ -146,7 +146,8 @@ SRCS = Socket.h\
|
|||
BtRegistry.cc BtRegistry.h\
|
||||
MultiFileAllocationIterator.cc MultiFileAllocationIterator.h\
|
||||
PeerConnection.cc PeerConnection.h\
|
||||
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h
|
||||
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
|
||||
ServerHost.cc
|
||||
# debug_new.cpp
|
||||
|
||||
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 \
|
||||
MultiFileAllocationIterator.h PeerConnection.cc \
|
||||
PeerConnection.h ByteArrayDiskWriter.cc ByteArrayDiskWriter.h \
|
||||
IteratableChunkChecksumValidator.cc \
|
||||
ServerHost.cc IteratableChunkChecksumValidator.cc \
|
||||
IteratableChunkChecksumValidator.h \
|
||||
IteratableChecksumValidator.cc IteratableChecksumValidator.h \
|
||||
CheckIntegrityCommand.cc CheckIntegrityCommand.h \
|
||||
|
@ -524,11 +524,11 @@ am__objects_12 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
|
|||
DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT) \
|
||||
Peer.$(OBJEXT) BtRegistry.$(OBJEXT) \
|
||||
MultiFileAllocationIterator.$(OBJEXT) PeerConnection.$(OBJEXT) \
|
||||
ByteArrayDiskWriter.$(OBJEXT) $(am__objects_1) \
|
||||
$(am__objects_2) $(am__objects_3) $(am__objects_4) \
|
||||
$(am__objects_5) $(am__objects_6) $(am__objects_7) \
|
||||
$(am__objects_8) $(am__objects_9) $(am__objects_10) \
|
||||
$(am__objects_11)
|
||||
ByteArrayDiskWriter.$(OBJEXT) ServerHost.$(OBJEXT) \
|
||||
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
|
||||
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
|
||||
$(am__objects_10) $(am__objects_11)
|
||||
am_libaria2c_a_OBJECTS = $(am__objects_12)
|
||||
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
||||
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 \
|
||||
MultiFileAllocationIterator.h PeerConnection.cc \
|
||||
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_7) $(am__append_8) $(am__append_9) \
|
||||
$(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)/SeedCheckCommand.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)/SimpleBtMessage.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);
|
||||
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(find(selectIndexes.begin(), selectIndexes.end(), count+1) == selectIndexes.end()) {
|
||||
continue;
|
||||
|
@ -206,6 +209,8 @@ RequestGroups Metalink2RequestGroup::createRequestGroup(MetalinkEntries entries)
|
|||
rg->setNumConcurrentCommand(entry->maxConnections < 0 ?
|
||||
_option->getAsInt(PREF_METALINK_SERVERS) :
|
||||
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
|
||||
// Inject depenency between rg and torrentRg here if torrentRg.isNull() == false
|
||||
|
|
|
@ -74,6 +74,29 @@ void MetalinkEntry::setLocationPreference(const Strings& locations,
|
|||
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 {
|
||||
public:
|
||||
bool operator()(const MetalinkResourceHandle& res1,
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
void reorderResourcesByPreference();
|
||||
|
||||
void setLocationPreference(const Strings& locations, int32_t preferenceToAdd);
|
||||
void setProtocolPreference(const string& protocol, int32_t preferenceToAdd);
|
||||
|
||||
static FileEntries toFileEntry(const MetalinkEntries& metalinkEntries);
|
||||
};
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
/* copyright --> */
|
||||
#include "MetalinkResource.h"
|
||||
|
||||
string MetalinkResource::type2String[] = {
|
||||
"ftp", "http", "https", "bittorrent", "not_supported"
|
||||
};
|
||||
|
||||
MetalinkResource::MetalinkResource():
|
||||
maxConnections(-1)
|
||||
{}
|
||||
|
|
|
@ -40,12 +40,14 @@
|
|||
class MetalinkResource {
|
||||
public:
|
||||
enum TYPE {
|
||||
TYPE_FTP,
|
||||
TYPE_FTP = 0,
|
||||
TYPE_HTTP,
|
||||
TYPE_HTTPS,
|
||||
TYPE_BITTORRENT,
|
||||
TYPE_NOT_SUPPORTED
|
||||
};
|
||||
|
||||
static string type2String[];
|
||||
public:
|
||||
string url;
|
||||
TYPE type;
|
||||
|
@ -66,6 +68,11 @@ public:
|
|||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
static const string& getTypeString(TYPE type)
|
||||
{
|
||||
return type2String[type];
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<MetalinkResource> MetalinkResourceHandle;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "OptionHandlerFactory.h"
|
||||
#include "prefs.h"
|
||||
#include "OptionHandlerImpl.h"
|
||||
#include "a2functional.h"
|
||||
|
||||
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 BooleanOptionHandler(PREF_ENABLE_DIRECT_IO));
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "DownloadHandlerFactory.h"
|
||||
#include "MemoryBufferPreDownloadHandler.h"
|
||||
#include "DownloadHandlerConstants.h"
|
||||
#include "ServerHost.h"
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
# include "CheckIntegrityCommand.h"
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
|
@ -97,6 +98,7 @@ RequestGroup::RequestGroup(const Option* option,
|
|||
_preLocalFileCheckEnabled(true),
|
||||
_haltRequested(false),
|
||||
_forceHaltRequested(false),
|
||||
_singleHostMultiConnectionEnabled(true),
|
||||
_option(option),
|
||||
_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 commands;
|
||||
Strings pendingURIs;
|
||||
for(;!_uris.empty() && numCommand--; _uris.pop_front()) {
|
||||
string uri = _uris.front();
|
||||
_spentUris.push_back(uri);
|
||||
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->setMethod(method);
|
||||
if(req->setUrl(uri)) {
|
||||
commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(), req, this, e));
|
||||
Command* command = 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 {
|
||||
_logger->error(MSG_UNRECOGNIZED_URI, req->getUrl().c_str());
|
||||
}
|
||||
}
|
||||
copy(pendingURIs.begin(), pendingURIs.end(), front_inserter(_uris));
|
||||
return commands;
|
||||
}
|
||||
|
||||
|
@ -744,3 +756,78 @@ DownloadResultHandle RequestGroup::createDownloadResult() const
|
|||
DownloadResult::FINISHED :
|
||||
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;
|
||||
class DownloadResult;
|
||||
typedef SharedHandle<DownloadResult> DownloadResultHandle;
|
||||
class ServerHost;
|
||||
typedef SharedHandle<ServerHost> ServerHostHandle;
|
||||
typedef deque<ServerHostHandle> ServerHosts;
|
||||
|
||||
class RequestGroup {
|
||||
private:
|
||||
|
@ -103,6 +106,8 @@ private:
|
|||
|
||||
DependencyHandle _dependency;
|
||||
|
||||
ServerHosts _serverHosts;
|
||||
|
||||
bool _fileAllocationEnabled;
|
||||
|
||||
bool _preLocalFileCheckEnabled;
|
||||
|
@ -111,6 +116,8 @@ private:
|
|||
|
||||
bool _forceHaltRequested;
|
||||
|
||||
bool _singleHostMultiConnectionEnabled;
|
||||
|
||||
PreDownloadHandlers _preDownloadHandlers;
|
||||
|
||||
PostDownloadHandlers _postDownloadHandlers;
|
||||
|
@ -310,6 +317,33 @@ public:
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -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_ENABLE_DIRECT_IO, V_FALSE);
|
||||
op->put(PREF_ALLOW_PIECE_LENGTH_CHANGE, V_FALSE);
|
||||
op->put(PREF_METALINK_PREFERRED_PROTOCOL, V_NONE);
|
||||
while(1) {
|
||||
int optIndex = 0;
|
||||
int lopt;
|
||||
|
@ -205,6 +206,7 @@ Option* option_processing(int argc, char* const argv[])
|
|||
{ "metalink-os", required_argument, &lopt, 102 },
|
||||
{ "follow-metalink", required_argument, &lopt, 103 },
|
||||
{ "metalink-location", required_argument, &lopt, 104 },
|
||||
{ "metalink-preferred-protocol", required_argument, &lopt, 105 },
|
||||
#endif // ENABLE_METALINK
|
||||
{ "version", no_argument, NULL, 'v' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
|
@ -300,6 +302,9 @@ Option* option_processing(int argc, char* const argv[])
|
|||
case 104:
|
||||
cmdstream << PREF_METALINK_LOCATION << "=" << optarg << "\n";
|
||||
break;
|
||||
case 105:
|
||||
cmdstream << PREF_METALINK_PREFERRED_PROTOCOL << "=" << optarg << "\n";
|
||||
break;
|
||||
case 200:
|
||||
cmdstream << PREF_LOWEST_SPEED_LIMIT << "=" << optarg << "\n";
|
||||
break;
|
||||
|
|
|
@ -225,5 +225,10 @@
|
|||
#define PREF_METALINK_SERVERS "metalink-servers"
|
||||
// values: true | false | mem
|
||||
#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_
|
||||
|
|
|
@ -300,6 +300,10 @@ void showUsage() {
|
|||
cout << _(" --metalink-location=LOCATION[,...] The location of the preferred server.\n"
|
||||
" A comma-deliminated list of locations is\n"
|
||||
" 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"
|
||||
" whose suffix is .metaink or content type is\n"
|
||||
" application/metalink+xml is downloaded, aria2\n"
|
||||
|
|
|
@ -9,6 +9,7 @@ class MetalinkEntryTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testDropUnsupportedResource);
|
||||
CPPUNIT_TEST(testReorderResourcesByPreference);
|
||||
CPPUNIT_TEST(testSetLocationPreference);
|
||||
CPPUNIT_TEST(testSetProtocolPreference);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
|
@ -21,6 +22,7 @@ public:
|
|||
void testDropUnsupportedResource();
|
||||
void testReorderResourcesByPreference();
|
||||
void testSetLocationPreference();
|
||||
void testSetProtocolPreference();
|
||||
};
|
||||
|
||||
|
||||
|
@ -122,3 +124,14 @@ void MetalinkEntryTest::testSetLocationPreference()
|
|||
CPPUNIT_ASSERT_EQUAL(string("JP"), entry->resources[4]->location);
|
||||
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 "prefs.h"
|
||||
#include "ServerHost.h"
|
||||
#include "Option.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
@ -7,12 +8,63 @@ using namespace std;
|
|||
class RequestGroupTest : public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(RequestGroupTest);
|
||||
CPPUNIT_TEST(testRegisterSearchRemove);
|
||||
CPPUNIT_TEST(testRemoveURIWhoseHostnameIs);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {}
|
||||
|
||||
void testRegisterSearchRemove();
|
||||
void testRemoveURIWhoseHostnameIs();
|
||||
};
|
||||
|
||||
|
||||
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