mirror of https://github.com/aria2/aria2
2009-01-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Applied exit-status patch from Pascal Rigaux at Mandriva. aria2 now returns last error encountered in the HTTP/FTP downloads as a exit status value. If all downloads finished successfully, aria2 returns 0. The error code is defined in src/DownloadResult.h. The error occurred in the download currently in progress is not reported as a last error. If no error has encountered but there are in progress or waiting downloads, aria2 returns 7. * src/AbstractCommand.cc * src/DlAbortEx.h * src/DlRetryEx.h * src/DownloadCommand.cc * src/DownloadFailureException.h * src/DownloadResult.h * src/FtpNegotiationCommand.cc * src/HttpSkipResponseCommand.cc * src/Makefile.am * src/MultiUrlRequestInfo.cc * src/MultiUrlRequestInfo.h * src/RecoverableException.h * src/RequestGroup.cc * src/RequestGroup.h * src/RequestGroupMan.cc * src/RequestGroupMan.h * src/URIResult.cc * src/URIResult.h * src/main.cc * src/option_processing.cc * test/RequestGroupTest.ccpull/1/head
parent
0a4f43d0ed
commit
8a9d921465
32
ChangeLog
32
ChangeLog
|
@ -1,3 +1,35 @@
|
|||
2009-01-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Applied exit-status patch from Pascal Rigaux at Mandriva. aria2
|
||||
now returns last error encountered in the HTTP/FTP downloads as a
|
||||
exit status value. If all downloads finished successfully, aria2
|
||||
returns 0. The error code is defined in src/DownloadResult.h.
|
||||
The error occurred in the download currently in progress is not
|
||||
reported as a last error. If no error has encountered but there
|
||||
are in progress or waiting downloads, aria2 returns 7.
|
||||
|
||||
* src/AbstractCommand.cc
|
||||
* src/DlAbortEx.h
|
||||
* src/DlRetryEx.h
|
||||
* src/DownloadCommand.cc
|
||||
* src/DownloadFailureException.h
|
||||
* src/DownloadResult.h
|
||||
* src/FtpNegotiationCommand.cc
|
||||
* src/HttpSkipResponseCommand.cc
|
||||
* src/Makefile.am
|
||||
* src/MultiUrlRequestInfo.cc
|
||||
* src/MultiUrlRequestInfo.h
|
||||
* src/RecoverableException.h
|
||||
* src/RequestGroup.cc
|
||||
* src/RequestGroup.h
|
||||
* src/RequestGroupMan.cc
|
||||
* src/RequestGroupMan.h
|
||||
* src/URIResult.cc
|
||||
* src/URIResult.h
|
||||
* src/main.cc
|
||||
* src/option_processing.cc
|
||||
* test/RequestGroupTest.cc
|
||||
|
||||
2009-01-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Applied AdaptiveURISelector patch from Aurelien Lefebvre. This
|
||||
|
|
|
@ -149,13 +149,14 @@ bool AbstractCommand::execute() {
|
|||
req->getProtocol());
|
||||
ss->setError();
|
||||
|
||||
throw DlRetryEx(EX_TIME_OUT);
|
||||
throw DlRetryEx(EX_TIME_OUT, DownloadResult::TIME_OUT);
|
||||
}
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
} catch(DlAbortEx& err) {
|
||||
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid, req->getUrl().c_str());
|
||||
_requestGroup->addURIResult(req->getUrl(), err.getCode());
|
||||
onAbort();
|
||||
req->resetUrl();
|
||||
tryReserved();
|
||||
|
@ -174,6 +175,7 @@ bool AbstractCommand::execute() {
|
|||
if(isAbort) {
|
||||
logger->info(MSG_MAX_TRY, cuid, req->getTryCount());
|
||||
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid, req->getUrl().c_str());
|
||||
_requestGroup->addURIResult(req->getUrl(), err.getCode());
|
||||
tryReserved();
|
||||
return true;
|
||||
} else {
|
||||
|
@ -181,6 +183,7 @@ bool AbstractCommand::execute() {
|
|||
}
|
||||
} catch(DownloadFailureException& err) {
|
||||
logger->error(EX_EXCEPTION_CAUGHT, err);
|
||||
_requestGroup->addURIResult(req->getUrl(), err.getCode());
|
||||
_requestGroup->setHaltRequested(true);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
DlAbortEx(const std::string& msg,
|
||||
const Exception& cause):RecoverableException(msg, cause) {}
|
||||
DlAbortEx(const RecoverableException& e):RecoverableException(e) {}
|
||||
DlAbortEx(const std::string& msg, DownloadResult::RESULT code):
|
||||
RecoverableException(msg, code) {}
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
DlRetryEx(const std::string& msg,
|
||||
const Exception& cause):RecoverableException(msg, cause) {}
|
||||
DlRetryEx(const DlRetryEx& e):RecoverableException(e) {}
|
||||
DlRetryEx(const std::string& msg, DownloadResult::RESULT code):
|
||||
RecoverableException(msg, code) {}
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -243,7 +243,7 @@ void DownloadCommand::checkLowestDownloadSpeed() const
|
|||
throw DlAbortEx(StringFormat(EX_TOO_SLOW_DOWNLOAD_SPEED,
|
||||
nowSpeed,
|
||||
lowestDownloadSpeedLimit,
|
||||
req->getHost().c_str()).str());
|
||||
req->getHost().c_str()).str(), DownloadResult::TOO_SLOW_DOWNLOAD_SPEED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,8 +52,12 @@ protected:
|
|||
public:
|
||||
DownloadFailureException(const std::string& msg):RecoverableException(msg) {}
|
||||
DownloadFailureException(const std::string& msg,
|
||||
const Exception& cause):RecoverableException(msg, cause) {}
|
||||
DownloadFailureException(const DownloadFailureException& e):RecoverableException(e) {}
|
||||
const Exception& cause):
|
||||
RecoverableException(msg, cause) {}
|
||||
DownloadFailureException(const DownloadFailureException& e):
|
||||
RecoverableException(e) {}
|
||||
DownloadFailureException(const std::string& msg, DownloadResult::RESULT code):
|
||||
RecoverableException(msg, code) {}
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -36,18 +36,28 @@
|
|||
#define _D_DOWNLOAD_RESULT_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "SharedHandle.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "SharedHandle.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class DownloadResult
|
||||
{
|
||||
public:
|
||||
// RESULT is used as an exit status code.
|
||||
enum RESULT {
|
||||
FINISHED,
|
||||
NOT_YET,
|
||||
FINISHED = 0,
|
||||
UNKNOWN_ERROR = 1,
|
||||
TIME_OUT = 2,
|
||||
RESOURCE_NOT_FOUND = 3,
|
||||
MAX_FILE_NOT_FOUND = 4,
|
||||
TOO_SLOW_DOWNLOAD_SPEED = 5,
|
||||
NETWORK_PROBLEM = 6,
|
||||
IN_PROGRESS = 7,
|
||||
};
|
||||
|
||||
int32_t gid;
|
||||
|
|
|
@ -261,7 +261,10 @@ bool FtpNegotiationCommand::recvCwd() {
|
|||
if(status != 250) {
|
||||
poolConnection();
|
||||
_requestGroup->increaseAndValidateFileNotFoundCount();
|
||||
throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
|
||||
if (status == 550)
|
||||
throw DlAbortEx(MSG_RESOURCE_NOT_FOUND, DownloadResult::RESOURCE_NOT_FOUND);
|
||||
else
|
||||
throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
|
||||
}
|
||||
if(e->option->getAsBool(PREF_REMOTE_TIME)) {
|
||||
sequence = SEQ_SEND_MDTM;
|
||||
|
@ -544,7 +547,10 @@ bool FtpNegotiationCommand::recvRetr() {
|
|||
}
|
||||
if(status != 150 && status != 125) {
|
||||
_requestGroup->increaseAndValidateFileNotFoundCount();
|
||||
throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
|
||||
if (status == 550)
|
||||
throw DlAbortEx(MSG_RESOURCE_NOT_FOUND, DownloadResult::RESOURCE_NOT_FOUND);
|
||||
else
|
||||
throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
|
||||
}
|
||||
if(e->option->getAsBool(PREF_FTP_PASV)) {
|
||||
sequence = SEQ_NEGOTIATION_COMPLETED;
|
||||
|
|
|
@ -160,7 +160,8 @@ bool HttpSkipResponseCommand::processResponse()
|
|||
if(_httpResponse->getResponseStatus() == HttpHeader::S401) {
|
||||
throw DlAbortEx(EX_AUTH_FAILED);
|
||||
}else if(_httpResponse->getResponseStatus() == HttpHeader::S404) {
|
||||
throw DlAbortEx(MSG_RESOURCE_NOT_FOUND);
|
||||
throw DlAbortEx(MSG_RESOURCE_NOT_FOUND,
|
||||
DownloadResult::RESOURCE_NOT_FOUND);
|
||||
} else {
|
||||
throw DlAbortEx(StringFormat(EX_BAD_STATUS, Util::parseUInt(_httpResponse->getResponseStatus())).str());
|
||||
}
|
||||
|
|
|
@ -188,14 +188,15 @@ SRCS = Socket.h\
|
|||
ServerStat.cc ServerStat.h\
|
||||
ServerStatMan.cc ServerStatMan.h\
|
||||
URISelector.h\
|
||||
AdaptiveURISelector.cc AdaptiveURISelector.h\
|
||||
AdaptiveURISelector.cc AdaptiveURISelector.h\
|
||||
InOrderURISelector.cc InOrderURISelector.h\
|
||||
ServerStatURISelector.cc ServerStatURISelector.h\
|
||||
NsCookieParser.cc NsCookieParser.h\
|
||||
CookieStorage.cc CookieStorage.h\
|
||||
SocketBuffer.cc SocketBuffer.h\
|
||||
OptionHandlerException.cc OptionHandlerException.h\
|
||||
bencode.cc bencode.h
|
||||
bencode.cc bencode.h\
|
||||
URIResult.cc URIResult.h
|
||||
|
||||
if ENABLE_SSL
|
||||
SRCS += TLSContext.h
|
||||
|
|
|
@ -411,10 +411,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
|||
ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \
|
||||
CookieStorage.cc CookieStorage.h SocketBuffer.cc \
|
||||
SocketBuffer.h OptionHandlerException.cc \
|
||||
OptionHandlerException.h bencode.cc bencode.h TLSContext.h \
|
||||
LibgnutlsTLSContext.cc LibgnutlsTLSContext.h \
|
||||
LibsslTLSContext.cc LibsslTLSContext.h GZipDecoder.cc \
|
||||
GZipDecoder.h Sqlite3MozCookieParser.cc \
|
||||
OptionHandlerException.h bencode.cc bencode.h URIResult.cc \
|
||||
URIResult.h TLSContext.h LibgnutlsTLSContext.cc \
|
||||
LibgnutlsTLSContext.h LibsslTLSContext.cc LibsslTLSContext.h \
|
||||
GZipDecoder.cc GZipDecoder.h Sqlite3MozCookieParser.cc \
|
||||
Sqlite3MozCookieParser.h AsyncNameResolver.cc \
|
||||
AsyncNameResolver.h IteratableChunkChecksumValidator.cc \
|
||||
IteratableChunkChecksumValidator.h \
|
||||
|
@ -802,13 +802,14 @@ am__objects_21 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
|
|||
InOrderURISelector.$(OBJEXT) ServerStatURISelector.$(OBJEXT) \
|
||||
NsCookieParser.$(OBJEXT) CookieStorage.$(OBJEXT) \
|
||||
SocketBuffer.$(OBJEXT) OptionHandlerException.$(OBJEXT) \
|
||||
bencode.$(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__objects_12) $(am__objects_13) $(am__objects_14) \
|
||||
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
|
||||
$(am__objects_18) $(am__objects_19) $(am__objects_20)
|
||||
bencode.$(OBJEXT) URIResult.$(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__objects_12) $(am__objects_13) \
|
||||
$(am__objects_14) $(am__objects_15) $(am__objects_16) \
|
||||
$(am__objects_17) $(am__objects_18) $(am__objects_19) \
|
||||
$(am__objects_20)
|
||||
am_libaria2c_a_OBJECTS = $(am__objects_21)
|
||||
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
|
@ -1133,14 +1134,14 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
|
|||
ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \
|
||||
CookieStorage.cc CookieStorage.h SocketBuffer.cc \
|
||||
SocketBuffer.h OptionHandlerException.cc \
|
||||
OptionHandlerException.h bencode.cc bencode.h $(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) $(am__append_12) $(am__append_13) \
|
||||
$(am__append_14) $(am__append_15) $(am__append_16) \
|
||||
$(am__append_17) $(am__append_18) $(am__append_19) \
|
||||
$(am__append_20)
|
||||
OptionHandlerException.h bencode.cc bencode.h URIResult.cc \
|
||||
URIResult.h $(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) $(am__append_12) \
|
||||
$(am__append_13) $(am__append_14) $(am__append_15) \
|
||||
$(am__append_16) $(am__append_17) $(am__append_18) \
|
||||
$(am__append_19) $(am__append_20)
|
||||
noinst_LIBRARIES = libaria2c.a
|
||||
libaria2c_a_SOURCES = $(SRCS)
|
||||
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
||||
|
@ -1499,6 +1500,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimedHaltCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransferStat.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URIResult.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URLMetalinkParserState.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnknownLengthPieceStorage.Po@am__quote@
|
||||
|
|
|
@ -99,9 +99,9 @@ void MultiUrlRequestInfo::printMessageForContinue()
|
|||
<< "\n";
|
||||
}
|
||||
|
||||
int MultiUrlRequestInfo::execute()
|
||||
DownloadResult::RESULT MultiUrlRequestInfo::execute()
|
||||
{
|
||||
int returnValue = 1;
|
||||
DownloadResult::RESULT returnValue = DownloadResult::FINISHED;
|
||||
try {
|
||||
DownloadEngineHandle e =
|
||||
DownloadEngineFactory().newDownloadEngine(_option, _requestGroups);
|
||||
|
@ -190,10 +190,14 @@ int MultiUrlRequestInfo::execute()
|
|||
_summaryOut << std::flush;
|
||||
|
||||
RequestGroupMan::DownloadStat s = e->_requestGroupMan->getDownloadStat();
|
||||
if(s.allCompleted()) {
|
||||
returnValue = 0;
|
||||
} else {
|
||||
if(!s.allCompleted()) {
|
||||
printMessageForContinue();
|
||||
if(s.getLastErrorResult() == DownloadResult::FINISHED &&
|
||||
s.getInProgress() > 0) {
|
||||
returnValue = DownloadResult::IN_PROGRESS;
|
||||
} else {
|
||||
returnValue = s.getLastErrorResult();
|
||||
}
|
||||
}
|
||||
} catch(RecoverableException& e) {
|
||||
_logger->error(EX_EXCEPTION_CAUGHT, e);
|
||||
|
|
|
@ -36,10 +36,13 @@
|
|||
#define _D_MULTI_URL_REQUEST_INFO_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "SharedHandle.h"
|
||||
|
||||
#include <deque>
|
||||
#include <iosfwd>
|
||||
|
||||
#include "SharedHandle.h"
|
||||
#include "DownloadResult.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class RequestGroup;
|
||||
|
@ -71,9 +74,10 @@ public:
|
|||
virtual ~MultiUrlRequestInfo();
|
||||
|
||||
/**
|
||||
* Returns 0 if all downloads have completed, otherwise returns 1.
|
||||
* Returns FINISHED if all downloads have completed, otherwise returns the
|
||||
* last download result.
|
||||
*/
|
||||
int execute();
|
||||
DownloadResult::RESULT execute();
|
||||
};
|
||||
|
||||
typedef SharedHandle<MultiUrlRequestInfo> MultiUrlRequestInfoHandle;
|
||||
|
|
|
@ -35,10 +35,14 @@
|
|||
#ifndef _D_RECOVERABLE_EXCEPTION_H_
|
||||
#define _D_RECOVERABLE_EXCEPTION_H_
|
||||
#include "Exception.h"
|
||||
#include "DownloadResult.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class RecoverableException:public Exception {
|
||||
private:
|
||||
DownloadResult::RESULT _code;
|
||||
|
||||
protected:
|
||||
virtual SharedHandle<Exception> copy() const
|
||||
{
|
||||
|
@ -46,10 +50,22 @@ protected:
|
|||
return e;
|
||||
}
|
||||
public:
|
||||
RecoverableException(const std::string& msg):Exception(msg) {}
|
||||
RecoverableException(const std::string& msg,
|
||||
const Exception& cause):Exception(msg, cause) {}
|
||||
RecoverableException(const RecoverableException& e):Exception(e) {}
|
||||
RecoverableException(const std::string& msg):
|
||||
Exception(msg),
|
||||
_code(DownloadResult::UNKNOWN_ERROR) {}
|
||||
|
||||
RecoverableException(const std::string& msg, const Exception& cause):
|
||||
Exception(msg, cause),
|
||||
_code(DownloadResult::UNKNOWN_ERROR) {}
|
||||
|
||||
RecoverableException(const RecoverableException& e):
|
||||
Exception(e),
|
||||
_code(DownloadResult::UNKNOWN_ERROR) {}
|
||||
|
||||
RecoverableException(const std::string& msg, DownloadResult::RESULT result):
|
||||
Exception(msg), _code(result) {}
|
||||
|
||||
DownloadResult::RESULT getCode() const { return _code; }
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -64,7 +64,6 @@
|
|||
#include "RequestGroupMan.h"
|
||||
#include "DefaultBtProgressInfoFile.h"
|
||||
#include "DefaultPieceStorage.h"
|
||||
#include "DownloadResult.h"
|
||||
#include "DownloadHandlerFactory.h"
|
||||
#include "MemoryBufferPreDownloadHandler.h"
|
||||
#include "DownloadHandlerConstants.h"
|
||||
|
@ -171,6 +170,19 @@ bool RequestGroup::allDownloadFinished() const
|
|||
}
|
||||
}
|
||||
|
||||
DownloadResult::RESULT RequestGroup::downloadResult() const
|
||||
{
|
||||
if (downloadFinished())
|
||||
return DownloadResult::FINISHED;
|
||||
else {
|
||||
if (_uriResults.empty()) {
|
||||
return DownloadResult::UNKNOWN_ERROR;
|
||||
} else {
|
||||
return _uriResults.back().getResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RequestGroup::closeFile()
|
||||
{
|
||||
if(!_pieceStorage.isNull()) {
|
||||
|
@ -902,9 +914,7 @@ DownloadResultHandle RequestGroup::createDownloadResult() const
|
|||
uris.size(),
|
||||
sessionDownloadLength,
|
||||
_downloadContext->calculateSessionTime(),
|
||||
downloadFinished()?
|
||||
DownloadResult::FINISHED :
|
||||
DownloadResult::NOT_YET));
|
||||
downloadResult()));
|
||||
}
|
||||
|
||||
void RequestGroup::registerServerHost(const ServerHostHandle& serverHost)
|
||||
|
@ -1073,7 +1083,8 @@ void RequestGroup::increaseAndValidateFileNotFoundCount()
|
|||
if(maxCount > 0 && _fileNotFoundCount >= maxCount &&
|
||||
_segmentMan->calculateSessionDownloadLength() == 0) {
|
||||
throw DownloadFailureException
|
||||
(StringFormat("Reached max-file-not-found count=%u", maxCount).str());
|
||||
(StringFormat("Reached max-file-not-found count=%u", maxCount).str(),
|
||||
DownloadResult::MAX_FILE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1097,4 +1108,14 @@ void RequestGroup::tuneDownloadCommand(DownloadCommand* command)
|
|||
_uriSelector->tuneDownloadCommand(_uris, command);
|
||||
}
|
||||
|
||||
void RequestGroup::addURIResult(std::string uri, DownloadResult::RESULT result)
|
||||
{
|
||||
_uriResults.push_back(URIResult(uri, result));
|
||||
}
|
||||
|
||||
const std::deque<URIResult>& RequestGroup::getURIResults() const
|
||||
{
|
||||
return _uriResults;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include "TransferStat.h"
|
||||
#include "TimeA2.h"
|
||||
#include "Request.h"
|
||||
#include "DownloadResult.h"
|
||||
#include "URIResult.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -112,6 +114,10 @@ private:
|
|||
|
||||
bool _forceHaltRequested;
|
||||
|
||||
// URIResult is stored in the ascending order of the time when its result is
|
||||
// available.
|
||||
std::deque<URIResult> _uriResults;
|
||||
|
||||
bool _singleHostMultiConnectionEnabled;
|
||||
|
||||
std::deque<SharedHandle<PreDownloadHandler> > _preDownloadHandlers;
|
||||
|
@ -154,6 +160,12 @@ private:
|
|||
|
||||
bool tryAutoFileRenaming();
|
||||
|
||||
// Returns the result code of this RequestGroup.
|
||||
// If the download finished, then returns DownloadResult::FINISHED.
|
||||
// If the download didn't finish and error result is available in _uriResults,
|
||||
// then last result code is returned.
|
||||
// Otherwise returns DownloadResult::UNKNOWN_ERROR.
|
||||
DownloadResult::RESULT downloadResult() const;
|
||||
public:
|
||||
RequestGroup(const Option* option, const std::deque<std::string>& uris);
|
||||
|
||||
|
@ -311,6 +323,10 @@ public:
|
|||
return _forceHaltRequested;
|
||||
}
|
||||
|
||||
void addURIResult(std::string uri, DownloadResult::RESULT result);
|
||||
|
||||
const std::deque<URIResult>& getURIResults() const;
|
||||
|
||||
void dependsOn(const SharedHandle<Dependency>& dep);
|
||||
|
||||
bool isDependencyResolved();
|
||||
|
|
|
@ -377,16 +377,17 @@ void RequestGroupMan::closeFile()
|
|||
|
||||
RequestGroupMan::DownloadStat RequestGroupMan::getDownloadStat() const
|
||||
{
|
||||
DownloadStat stat;
|
||||
size_t finished = 0;
|
||||
size_t error = 0;
|
||||
size_t inprogress = 0;
|
||||
DownloadResult::RESULT lastError = DownloadResult::FINISHED;
|
||||
for(std::deque<SharedHandle<DownloadResult> >::const_iterator itr = _downloadResults.begin();
|
||||
itr != _downloadResults.end(); ++itr) {
|
||||
if((*itr)->result == DownloadResult::FINISHED) {
|
||||
++finished;
|
||||
} else {
|
||||
++error;
|
||||
lastError = (*itr)->result;
|
||||
}
|
||||
}
|
||||
for(RequestGroups::const_iterator itr = _requestGroups.begin();
|
||||
|
@ -398,11 +399,8 @@ RequestGroupMan::DownloadStat RequestGroupMan::getDownloadStat() const
|
|||
++inprogress;
|
||||
}
|
||||
}
|
||||
stat.setCompleted(finished);
|
||||
stat.setError(error);
|
||||
stat.setInProgress(inprogress);
|
||||
stat.setWaiting(_reservedGroups.size());
|
||||
return stat;
|
||||
return DownloadStat(finished, error, inprogress, _reservedGroups.size(),
|
||||
lastError);
|
||||
}
|
||||
|
||||
void RequestGroupMan::showDownloadResults(std::ostream& o) const
|
||||
|
|
|
@ -36,12 +36,15 @@
|
|||
#define _D_REQUEST_GROUP_MAN_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "SharedHandle.h"
|
||||
#include "TransferStat.h"
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <iosfwd>
|
||||
|
||||
#include "SharedHandle.h"
|
||||
#include "DownloadResult.h"
|
||||
#include "TransferStat.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
class DownloadEngine;
|
||||
|
@ -117,18 +120,34 @@ public:
|
|||
size_t _error;
|
||||
size_t _inProgress;
|
||||
size_t _waiting;
|
||||
DownloadResult::RESULT _lastErrorResult;
|
||||
public:
|
||||
DownloadStat():_completed(0), _error(0), _inProgress(0), _waiting(0) {}
|
||||
DownloadStat(size_t completed,
|
||||
size_t error,
|
||||
size_t inProgress,
|
||||
size_t waiting,
|
||||
DownloadResult::RESULT lastErrorResult =
|
||||
DownloadResult::FINISHED):
|
||||
_completed(completed),
|
||||
_error(error),
|
||||
_inProgress(inProgress),
|
||||
_waiting(waiting),
|
||||
_lastErrorResult(lastErrorResult) {}
|
||||
|
||||
void setCompleted(size_t c) { _completed = c; }
|
||||
void setError(size_t c) { _error = c; }
|
||||
void setInProgress(size_t c) { _inProgress = c; }
|
||||
void setWaiting(size_t c) { _waiting = c; }
|
||||
DownloadResult::RESULT getLastErrorResult() const
|
||||
{
|
||||
return _lastErrorResult;
|
||||
}
|
||||
|
||||
bool allCompleted() const
|
||||
{
|
||||
return _error == 0 && _inProgress == 0 && _waiting == 0;
|
||||
}
|
||||
|
||||
size_t getInProgress() const
|
||||
{
|
||||
return _inProgress;
|
||||
}
|
||||
};
|
||||
|
||||
DownloadStat getDownloadStat() const;
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/* <!-- 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 "URIResult.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
URIResult::URIResult(const std::string& uri, DownloadResult::RESULT result):
|
||||
_uri(uri), _result(result) {}
|
||||
|
||||
const std::string& URIResult::getURI() const
|
||||
{
|
||||
return _uri;
|
||||
}
|
||||
|
||||
DownloadResult::RESULT URIResult::getResult() const
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
|
@ -0,0 +1,62 @@
|
|||
/* <!-- 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_URI_RESULT_H_
|
||||
#define _D_URI_RESULT_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "DownloadResult.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
// This class stores URI and its result code as a consequence of the download.
|
||||
class URIResult {
|
||||
private:
|
||||
std::string _uri;
|
||||
|
||||
DownloadResult::RESULT _result;
|
||||
public:
|
||||
URIResult(const std::string& uri, DownloadResult::RESULT result);
|
||||
|
||||
const std::string& getURI() const;
|
||||
|
||||
DownloadResult::RESULT getResult() const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
||||
#endif // _D_URI_RESULT_H_
|
20
src/main.cc
20
src/main.cc
|
@ -157,7 +157,7 @@ static void showFiles(const std::deque<std::string>& uris, const Option* op)
|
|||
|
||||
extern Option* option_processing(int argc, char* const argv[]);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
DownloadResult::RESULT main(int argc, char* argv[])
|
||||
{
|
||||
Option* op = option_processing(argc, argv);
|
||||
std::deque<std::string> args(argv+optind, argv+argc);
|
||||
|
@ -175,7 +175,7 @@ int main(int argc, char* argv[])
|
|||
if(op->getAsBool(PREF_QUIET)) {
|
||||
LogFactory::setConsoleOutput(false);
|
||||
}
|
||||
int32_t exitStatus = EXIT_SUCCESS;
|
||||
DownloadResult::RESULT exitStatus = DownloadResult::FINISHED;
|
||||
try {
|
||||
Logger* logger = LogFactory::getInstance();
|
||||
logger->info("<<--- --- --- ---");
|
||||
|
@ -191,13 +191,12 @@ int main(int argc, char* argv[])
|
|||
#ifdef SIGPIPE
|
||||
Util::setGlobalSignalHandler(SIGPIPE, SIG_IGN, 0);
|
||||
#endif
|
||||
int32_t returnValue = 0;
|
||||
std::deque<SharedHandle<RequestGroup> > requestGroups;
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
if(!op->blank(PREF_TORRENT_FILE)) {
|
||||
if(op->get(PREF_SHOW_FILES) == V_TRUE) {
|
||||
showTorrentFile(op->get(PREF_TORRENT_FILE));
|
||||
return EXIT_SUCCESS;
|
||||
return exitStatus;
|
||||
} else {
|
||||
createRequestGroupForBitTorrent(requestGroups, op, args);
|
||||
}
|
||||
|
@ -208,7 +207,7 @@ int main(int argc, char* argv[])
|
|||
if(!op->blank(PREF_METALINK_FILE)) {
|
||||
if(op->get(PREF_SHOW_FILES) == V_TRUE) {
|
||||
showMetalinkFile(op->get(PREF_METALINK_FILE), op);
|
||||
return EXIT_SUCCESS;
|
||||
return exitStatus;
|
||||
} else {
|
||||
createRequestGroupForMetalink(requestGroups, op);
|
||||
}
|
||||
|
@ -228,15 +227,12 @@ int main(int argc, char* argv[])
|
|||
if(requestGroups.empty()) {
|
||||
std::cout << MSG_NO_FILES_TO_DOWNLOAD << std::endl;
|
||||
} else {
|
||||
returnValue = MultiUrlRequestInfo(requestGroups, op, getStatCalc(op),
|
||||
getSummaryOut(op)).execute();
|
||||
}
|
||||
if(returnValue == 1) {
|
||||
exitStatus = EXIT_FAILURE;
|
||||
exitStatus = MultiUrlRequestInfo(requestGroups, op, getStatCalc(op),
|
||||
getSummaryOut(op)).execute();
|
||||
}
|
||||
} catch(Exception& ex) {
|
||||
std::cerr << EX_EXCEPTION_CAUGHT << "\n" << ex.stackTrace() << std::endl;
|
||||
exitStatus = EXIT_FAILURE;
|
||||
exitStatus = DownloadResult::UNKNOWN_ERROR;
|
||||
}
|
||||
delete op;
|
||||
LogFactory::release();
|
||||
|
@ -248,7 +244,7 @@ int main(int argc, char* argv[])
|
|||
int main(int argc, char* argv[]) {
|
||||
aria2::Platform platform;
|
||||
|
||||
int r = aria2::main(argc, argv);
|
||||
aria2::DownloadResult::RESULT r = aria2::main(argc, argv);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "File.h"
|
||||
#include "StringFormat.h"
|
||||
#include "OptionHandlerException.h"
|
||||
#include "DownloadResult.h"
|
||||
|
||||
extern char* optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
@ -107,7 +108,7 @@ Option* option_processing(int argc, char* const argv[])
|
|||
oparser.parseDefaultValues(op);
|
||||
} catch(Exception& e) {
|
||||
std::cerr << e.stackTrace();
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
|
@ -254,12 +255,12 @@ Option* option_processing(int argc, char* const argv[])
|
|||
std::cout << "--http-proxy-user was deprecated. See --http-proxy,"
|
||||
<< " --https-proxy, --ftp-proxy, --all-proxy options."
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
case 5:
|
||||
std::cout << "--http-proxy-passwd was deprecated. See --http-proxy,"
|
||||
<< " --https-proxy, --ftp-proxy, --all-proxy options."
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
case 6:
|
||||
cmdstream << PREF_HTTP_AUTH_SCHEME << "=" << optarg << "\n";
|
||||
break;
|
||||
|
@ -282,12 +283,12 @@ Option* option_processing(int argc, char* const argv[])
|
|||
std::cout << "--ftp-via-http-proxy was deprecated."
|
||||
<< " Use --http-proxy-method option instead."
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
case 14:
|
||||
std::cout << "--http-proxy-method was deprecated."
|
||||
<< " Use --proxy-method option instead."
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
case 15:
|
||||
cmdstream << PREF_LISTEN_PORT << "=" << optarg << "\n";
|
||||
break;
|
||||
|
@ -553,7 +554,7 @@ Option* option_processing(int argc, char* const argv[])
|
|||
break;
|
||||
case 'v':
|
||||
showVersion();
|
||||
exit(EXIT_SUCCESS);
|
||||
exit(DownloadResult::FINISHED);
|
||||
case 'h':
|
||||
{
|
||||
std::string category;
|
||||
|
@ -563,11 +564,11 @@ Option* option_processing(int argc, char* const argv[])
|
|||
category = optarg;
|
||||
}
|
||||
showUsage(category, oparser);
|
||||
exit(EXIT_SUCCESS);
|
||||
exit(DownloadResult::FINISHED);
|
||||
}
|
||||
default:
|
||||
showUsage(TAG_HELP, oparser);
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,18 +589,18 @@ Option* option_processing(int argc, char* const argv[])
|
|||
<< "Usage:" << "\n"
|
||||
<< oparser.findByName(e.getOptionName())->getDescription()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
} catch(Exception& e) {
|
||||
std::cerr << "Parse error in " << cfname << "\n"
|
||||
<< e.stackTrace() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
}
|
||||
} else if(!ucfname.empty()) {
|
||||
std::cerr << StringFormat("Configuration file %s is not found.",
|
||||
cfname.c_str())
|
||||
<< "\n";
|
||||
showUsage(TAG_HELP, oparser);
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
||||
// Override configuration with environment variables.
|
||||
|
@ -616,11 +617,11 @@ Option* option_processing(int argc, char* const argv[])
|
|||
<< "Usage:" << "\n"
|
||||
<< oparser.findByName(e.getOptionName())->getDescription()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
} catch(Exception& e) {
|
||||
std::cerr << e.stackTrace() << std::endl;
|
||||
showUsage(TAG_HELP, oparser);
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
||||
if(
|
||||
|
@ -634,14 +635,14 @@ Option* option_processing(int argc, char* const argv[])
|
|||
if(optind == argc) {
|
||||
std::cerr << MSG_URI_REQUIRED << std::endl;
|
||||
showUsage(TAG_HELP, oparser);
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_DAEMON
|
||||
if(op->getAsBool(PREF_DAEMON)) {
|
||||
if(daemon(1, 1) < 0) {
|
||||
perror(MSG_DAEMON_FAILED);
|
||||
exit(EXIT_FAILURE);
|
||||
exit(DownloadResult::UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_DAEMON
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Option.h"
|
||||
#include "SingleFileDownloadContext.h"
|
||||
#include "FileEntry.h"
|
||||
#include "PieceStorage.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -15,6 +16,7 @@ class RequestGroupTest : public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testRegisterSearchRemove);
|
||||
CPPUNIT_TEST(testRemoveURIWhoseHostnameIs);
|
||||
CPPUNIT_TEST(testGetFilePath);
|
||||
CPPUNIT_TEST(testCreateDownloadResult);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
|
@ -24,6 +26,7 @@ public:
|
|||
void testRegisterSearchRemove();
|
||||
void testRemoveURIWhoseHostnameIs();
|
||||
void testGetFilePath();
|
||||
void testCreateDownloadResult();
|
||||
};
|
||||
|
||||
|
||||
|
@ -93,4 +96,47 @@ void RequestGroupTest::testGetFilePath()
|
|||
CPPUNIT_ASSERT_EQUAL(std::string("[MEMORY]myfile"), group.getFilePath());
|
||||
}
|
||||
|
||||
void RequestGroupTest::testCreateDownloadResult()
|
||||
{
|
||||
SharedHandle<SingleFileDownloadContext> ctx
|
||||
(new SingleFileDownloadContext(1024, 1024*1024, "myfile"));
|
||||
ctx->setDir("/tmp");
|
||||
Option op;
|
||||
std::deque<std::string> uris;
|
||||
uris.push_back("http://first/file");
|
||||
uris.push_back("http://second/file");
|
||||
|
||||
RequestGroup group(&op, uris);
|
||||
group.setDownloadContext(ctx);
|
||||
group.initPieceStorage();
|
||||
{
|
||||
SharedHandle<DownloadResult> result = group.createDownloadResult();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("/tmp/myfile"), result->filePath);
|
||||
CPPUNIT_ASSERT_EQUAL((uint64_t)1024*1024, result->totalLength);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("http://first/file"), result->uri);
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, result->numUri);
|
||||
CPPUNIT_ASSERT_EQUAL((uint64_t)0, result->sessionDownloadLength);
|
||||
CPPUNIT_ASSERT_EQUAL((time_t)0, result->sessionTime);
|
||||
// result is UNKNOWN_ERROR if download has not completed and no specific
|
||||
// error has been reported
|
||||
CPPUNIT_ASSERT_EQUAL(DownloadResult::UNKNOWN_ERROR, result->result);
|
||||
}
|
||||
{
|
||||
group.addURIResult("http://first/file", DownloadResult::TIME_OUT);
|
||||
group.addURIResult("http://second/file",DownloadResult::RESOURCE_NOT_FOUND);
|
||||
|
||||
SharedHandle<DownloadResult> result = group.createDownloadResult();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(DownloadResult::RESOURCE_NOT_FOUND, result->result);
|
||||
}
|
||||
{
|
||||
group.getPieceStorage()->markAllPiecesDone();
|
||||
|
||||
SharedHandle<DownloadResult> result = group.createDownloadResult();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(DownloadResult::FINISHED, result->result);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
Loading…
Reference in New Issue