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
pull/1/head
Tatsuhiro Tsujikawa 2009-01-12 12:27:34 +00:00
parent 0a4f43d0ed
commit 8a9d921465
23 changed files with 386 additions and 88 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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());
}

View File

@ -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

View File

@ -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@

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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;

52
src/URIResult.cc Normal file
View File

@ -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

62
src/URIResult.h Normal file
View File

@ -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_

View File

@ -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;
}

View File

@ -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

View File

@ -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