2007-03-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

To the ability to read options from a config file:
	* src/main.cc: Command-line parameter validation is delegated to
	OptionHandler class.
	* src/OptionHandlerFactory.h, src/OptionHandlerFactory.cc: New 
class.
	* src/Option.h, src/Option.cc (clear): New function.
	* src/OptionParser.h, src/OptionParser.cc: New class.
	* src/OptionHandler.h: New class.
	* src/NameMatchOptionHandler.h: New class.
	* src/OptionHandlerImpl.h: New classes.
	* src/prefs.h: '_' -> '-'
	(FTP_PASV_ENABLED): Renamed to FTP_PASV.
	(FTP_PASV): New definition.
	* src/Util.h, src/Util.cc (getRealSize): New function.
	
	To disable netrc support if .netrc file does not have correct
	permissions:
	* src/File.h, src/File.cc (mode): New function.

	To prevent confidential information to be logged:
	* src/HttpConnection.h, src/HttpConnection.cc
	(eraseConfidentialInfo): New function.
	(sendRequest): Call eraseConfidentialInfo().
	(sendProxyRequest): Call eraseConfidentialInfo().
	* src/main.cc: Validate permissions of .netrc file.
	
	To add --user-agent command-line option:
	* src/main.cc: Added new command line option: --user-agent
	* src/prefs.h (PREF_USER_AGENT): New definition.
	* src/HttpRequestCommand.cc (executeInternal): Set user-agent 
option
	parameter to HttpRequest object.
	
	Marged the patches from Dan Fandrich.
pull/1/head
Tatsuhiro Tsujikawa 2007-03-26 12:16:57 +00:00
parent 228ed66f73
commit 9b73454b07
34 changed files with 1320 additions and 335 deletions

View File

@ -1,3 +1,38 @@
2007-03-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To the ability to read options from a config file:
* src/main.cc: Command-line parameter validation is delegated to
OptionHandler class.
* src/OptionHandlerFactory.h, src/OptionHandlerFactory.cc: New class.
* src/Option.h, src/Option.cc (clear): New function.
* src/OptionParser.h, src/OptionParser.cc: New class.
* src/OptionHandler.h: New class.
* src/NameMatchOptionHandler.h: New class.
* src/OptionHandlerImpl.h: New classes.
* src/prefs.h: '_' -> '-'
(FTP_PASV_ENABLED): Renamed to FTP_PASV.
(FTP_PASV): New definition.
* src/Util.h, src/Util.cc (getRealSize): New function.
To disable netrc support if .netrc file does not have correct
permissions:
* src/File.h, src/File.cc (mode): New function.
To prevent confidential information to be logged:
* src/HttpConnection.h, src/HttpConnection.cc
(eraseConfidentialInfo): New function.
(sendRequest): Call eraseConfidentialInfo().
(sendProxyRequest): Call eraseConfidentialInfo().
* src/main.cc: Validate permissions of .netrc file.
To add --user-agent command-line option:
* src/main.cc: Added new command line option: --user-agent
* src/prefs.h (PREF_USER_AGENT): New definition.
* src/HttpRequestCommand.cc (executeInternal): Set user-agent option
parameter to HttpRequest object.
Marged the patches from Dan Fandrich.
2007-03-25 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Use filename and size from Metalink file instead of sending HEAD

7
TODO
View File

@ -22,9 +22,4 @@
* Add --bt-timeout command line option.
* Fix DefaultBtProgressInfoFile.cc: save(), load()
* remove blockIndex
* Add an ability of seeding
* Rewrite HttpConnection::receiveResponse() using {i,o}stringstream
* Add usage message for -c command line option
* Netrc, mode 600, enabled in ftp, http, all
* preallocate file in MultiDiskAdaptor
* Add seed mode.

View File

@ -106,7 +106,7 @@ void ChunkChecksumValidator::validate(BitfieldMan* bitfieldMan,
fileAllocationMonitor->showProgress();
Time cp;
for(int32_t i = 0; i < x; ++i) {
(this->*f)(bitfieldMan, i, checksums.at(i), checksumLength, checksumLength);
(this->*f)(bitfieldMan, i, checksums[i], checksumLength, checksumLength);
if(cp.elapsedInMillis(500)) {
fileAllocationMonitor->setCurrentValue(i*checksumLength);
fileAllocationMonitor->showProgress();
@ -114,7 +114,7 @@ void ChunkChecksumValidator::validate(BitfieldMan* bitfieldMan,
}
}
if(r) {
(this->*f)(bitfieldMan, x, checksums.at(x), r, checksumLength);
(this->*f)(bitfieldMan, x, checksums[x], r, checksumLength);
}
fileAllocationMonitor->setCurrentValue(bitfieldMan->getTotalLength());
fileAllocationMonitor->showProgress();

View File

@ -121,7 +121,7 @@ void DefaultBtContext::extractFileEntries(Dictionary* infoDic,
const MetaList& paths = pathList->getList();
string path;
for(int32_t i = 0; i < (int32_t)paths.size()-1; i++) {
Data* subpath = (Data*)paths.at(i);
Data* subpath = (Data*)paths[i];
path += subpath->toString()+"/";
}
// TODO use dynamic_cast
@ -212,7 +212,7 @@ string DefaultBtContext::getPieceHash(int32_t index) const {
if(index < 0 || numPieces <= index) {
return "";
}
return pieceHashes.at(index);
return pieceHashes[index];
}
int64_t DefaultBtContext::getTotalLength() const {

View File

@ -313,8 +313,8 @@ void DefaultPieceStorage::setFileFilter(const Integers& fileIndexes) {
const FileEntries& entries = diskAdaptor->getFileEntries();
for(int i = 0; i < (int)entries.size(); i++) {
if(find(fileIndexes.begin(), fileIndexes.end(), i+1) != fileIndexes.end()) {
logger->debug("index=%d is %s", i+1, entries.at(i)->getPath().c_str());
filePaths.push_back(entries.at(i)->getPath());
logger->debug("index=%d is %s", i+1, entries[i]->getPath().c_str());
filePaths.push_back(entries[i]->getPath());
}
}
setFileFilter(filePaths);

View File

@ -65,7 +65,7 @@ bool DiskAdaptor::addDownloadEntry(int index) {
if(fileEntries.size() <= (unsigned int)index) {
return false;
}
fileEntries.at(index)->setRequested(true);
fileEntries[index]->setRequested(true);
return true;
}

View File

@ -77,7 +77,7 @@ bool File::remove() {
}
}
long long int File::size() {
int64_t File::size() {
struct stat fstat;
if(fillStat(fstat) < 0) {
return 0;
@ -111,3 +111,12 @@ bool File::mkdirs() {
}
return true;
}
mode_t File::mode()
{
struct stat fstat;
if(fillStat(fstat) < 0) {
return 0;
}
return fstat.st_mode;
}

View File

@ -36,7 +36,9 @@
#define _D_FILE_H_
#include "common.h"
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace std;
@ -81,7 +83,9 @@ public:
*/
bool mkdirs();
long long int size();
int64_t size();
mode_t mode();
};
#endif // _D_FILE_H_

View File

@ -209,7 +209,7 @@ bool FtpNegotiationCommand::recvSize() {
} else if(e->segmentMan->totalSize != size) {
throw new DlAbortEx(EX_SIZE_MISMATCH, e->segmentMan->totalSize, size);
}
if(e->option->get(PREF_FTP_PASV_ENABLED) == V_TRUE) {
if(e->option->get(PREF_FTP_PASV) == V_TRUE) {
sequence = SEQ_SEND_PASV;
} else {
sequence = SEQ_SEND_PORT;
@ -303,7 +303,7 @@ bool FtpNegotiationCommand::recvRetr() {
if(status != 150 && status != 125) {
throw new DlRetryEx(EX_BAD_STATUS, status);
}
if(e->option->get(PREF_FTP_PASV_ENABLED) != V_TRUE) {
if(e->option->get(PREF_FTP_PASV) != V_TRUE) {
assert(serverSocket->getSockfd() != -1);
dataSocket = serverSocket->acceptConnection();
}

View File

@ -39,6 +39,7 @@
#include "message.h"
#include "prefs.h"
#include "LogFactory.h"
#include <sstream>
HttpConnection::HttpConnection(int cuid,
const SocketHandle& socket,
@ -47,10 +48,27 @@ HttpConnection::HttpConnection(int cuid,
logger = LogFactory::getInstance();
}
string HttpConnection::eraseConfidentialInfo(const string& request)
{
istringstream istr(request);
ostringstream ostr;
string line;
while(getline(istr, line)) {
if(Util::startsWith(line, "Authorization: Basic")) {
ostr << "Authorization: Basic ********\n";
} else if(Util::startsWith(line, "Proxy-Authorization: Basic")) {
ostr << "Proxy-Authorization: Basic ********\n";
} else {
ostr << line << "\n";
}
}
return ostr.str();
}
void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
{
string request = httpRequest->createRequest();
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
socket->writeData(request.c_str(), request.size());
outstandingHttpRequests.push_back(httpRequest);
}
@ -58,7 +76,7 @@ void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
{
string request = httpRequest->createProxyRequest();
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
socket->writeData(request.c_str(), request.size());
outstandingHttpRequests.push_back(httpRequest);
}

View File

@ -60,6 +60,7 @@ private:
HttpRequests outstandingHttpRequests;
int findEndOfHeader(const char* buf, const char* substr, int bufLength) const;
string eraseConfidentialInfo(const string& request);
public:
HttpConnection(int cuid,
const SocketHandle& socket,

View File

@ -57,6 +57,7 @@ bool HttpRequestCommand::executeInternal() {
req->setKeepAlive(false);
}
HttpRequestHandle httpRequest = new HttpRequest();
httpRequest->setUserAgent(e->option->get(PREF_USER_AGENT));
httpRequest->setRequest(req);
httpRequest->setSegment(segment);
httpRequest->setEntityLength(e->segmentMan->totalSize);

View File

@ -78,7 +78,9 @@ SRCS = Socket.h\
NetrcAuthResolver.cc NetrcAuthResolver.h\
RequestFactory.cc RequestFactory.h\
DefaultFileAllocator.cc DefaultFileAllocator.h\
GlowFileAllocator.cc GlowFileAllocator.h
GlowFileAllocator.cc GlowFileAllocator.h\
OptionParser.cc OptionParser.h\
OptionHandlerFactory.cc OptionHandlerFactory.h
# debug_new.cpp
if ENABLE_ASYNC_DNS

View File

@ -222,12 +222,14 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
DefaultAuthResolver.h NetrcAuthResolver.cc NetrcAuthResolver.h \
RequestFactory.cc RequestFactory.h DefaultFileAllocator.cc \
DefaultFileAllocator.h GlowFileAllocator.cc \
GlowFileAllocator.h NameResolver.cc NameResolver.h MetaEntry.h \
Data.cc Data.h Dictionary.cc Dictionary.h List.cc List.h \
MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
ShaVisitor.cc ShaVisitor.h PeerConnection.cc PeerConnection.h \
PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
GlowFileAllocator.h OptionParser.cc OptionParser.h \
OptionHandlerFactory.cc OptionHandlerFactory.h NameResolver.cc \
NameResolver.h MetaEntry.h Data.cc Data.h Dictionary.cc \
Dictionary.h List.cc List.h MetaFileUtil.cc MetaFileUtil.h \
MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h \
PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \
PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \
PeerInitiateConnectionCommand.cc \
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
PeerInteractionCommand.h Peer.cc Peer.h \
TorrentDownloadEngine.cc TorrentDownloadEngine.h \
@ -393,6 +395,7 @@ am__objects_4 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
AuthConfig.$(OBJEXT) DefaultAuthResolver.$(OBJEXT) \
NetrcAuthResolver.$(OBJEXT) RequestFactory.$(OBJEXT) \
DefaultFileAllocator.$(OBJEXT) GlowFileAllocator.$(OBJEXT) \
OptionParser.$(OBJEXT) OptionHandlerFactory.$(OBJEXT) \
$(am__objects_1) $(am__objects_2) $(am__objects_3)
am_libaria2c_a_OBJECTS = $(am__objects_4)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
@ -608,8 +611,9 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
DefaultAuthResolver.h NetrcAuthResolver.cc NetrcAuthResolver.h \
RequestFactory.cc RequestFactory.h DefaultFileAllocator.cc \
DefaultFileAllocator.h GlowFileAllocator.cc \
GlowFileAllocator.h $(am__append_1) $(am__append_2) \
$(am__append_3)
GlowFileAllocator.h OptionParser.cc OptionParser.h \
OptionHandlerFactory.cc OptionHandlerFactory.h $(am__append_1) \
$(am__append_2) $(am__append_3)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@ -793,6 +797,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Netrc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetrcAuthResolver.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Option.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionHandlerFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionParser.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Peer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerAbstractCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerChokeCommand.Po@am__quote@

View File

@ -0,0 +1,56 @@
/* <!-- 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_NAME_MATCH_OPTION_HANDLER_H_
#define _D_NAME_MATCH_OPTION_HANDLER_H_
#include "OptionHandler.h"
class NameMatchOptionHandler : public OptionHandler {
protected:
string _optName;
public:
NameMatchOptionHandler(const string& optName):_optName(optName) {}
virtual ~NameMatchOptionHandler() {}
virtual bool canHandle(const string& optName)
{
return strcasecmp(_optName.c_str(), optName.c_str()) == 0;
}
};
typedef SharedHandle<NameMatchOptionHandler> NameMatchOptionHandlerHandle;
#endif // _D_NAME_MATCH_OPTION_HANDLER_H_

View File

@ -91,3 +91,8 @@ double Option::getAsDouble(const string& name) const {
return strtod(value.c_str(), 0);
}
}
void Option::clear()
{
table.clear();
}

View File

@ -55,6 +55,8 @@ public:
long long int getAsLLInt(const string& name) const;
bool getAsBool(const string& name) const;
double getAsDouble(const string& name) const;
void clear();
};
#endif // _D_OPTION_H_

51
src/OptionHandler.h Normal file
View File

@ -0,0 +1,51 @@
/* <!-- 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_OPTION_HANDLER_H_
#define _D_OPTION_HANDLER_H_
#include "common.h"
#include "Option.h"
class OptionHandler {
public:
virtual ~OptionHandler() {}
virtual bool canHandle(const string& optName) = 0;
virtual void parseArg(Option* option, const string& arg) = 0;
};
typedef SharedHandle<OptionHandler> OptionHandlerHandle;
typedef deque<OptionHandlerHandle> OptionHandlers;
#endif // _D_OPTION_HANDLER_H_

View File

@ -0,0 +1,94 @@
/* <!-- 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 "OptionHandlerFactory.h"
#include "prefs.h"
#include "OptionHandlerImpl.h"
OptionHandlers OptionHandlerFactory::createOptionHandlers()
{
OptionHandlers handlers;
handlers.push_back(new HttpProxyOptionHandler(PREF_HTTP_PROXY));
handlers.push_back(new DefaultOptionHandler(PREF_HTTP_USER));
handlers.push_back(new DefaultOptionHandler(PREF_HTTP_PASSWD));
handlers.push_back(new DefaultOptionHandler(PREF_HTTP_PROXY_USER));
handlers.push_back(new DefaultOptionHandler(PREF_HTTP_PROXY_PASSWD));
handlers.push_back(new ParameterOptionHandler(PREF_HTTP_AUTH_SCHEME, V_BASIC));
handlers.push_back(new DefaultOptionHandler(PREF_REFERER));
handlers.push_back(new NumberOptionHandler(PREF_RETRY_WAIT, 0, 60));
handlers.push_back(new DefaultOptionHandler(PREF_FTP_USER));
handlers.push_back(new DefaultOptionHandler(PREF_FTP_PASSWD));
handlers.push_back(new ParameterOptionHandler(PREF_FTP_TYPE, V_BINARY, V_ASCII));
handlers.push_back(new ParameterOptionHandler(PREF_FTP_VIA_HTTP_PROXY,
V_GET, V_TUNNEL));
handlers.push_back(new UnitNumberOptionHandler(PREF_MIN_SEGMENT_SIZE, 1024));
handlers.push_back(new ParameterOptionHandler(PREF_HTTP_PROXY_METHOD,
V_GET, V_TUNNEL));
handlers.push_back(new NumberOptionHandler(PREF_LISTEN_PORT, 1024, UINT16_MAX));
handlers.push_back(new BooleanOptionHandler(PREF_FOLLOW_TORRENT));
handlers.push_back(new BooleanOptionHandler(PREF_NO_PREALLOCATION));
handlers.push_back(new BooleanOptionHandler(PREF_DIRECT_FILE_MAPPING));
handlers.push_back(new DefaultOptionHandler(PREF_SELECT_FILE));
handlers.push_back(new NumberOptionHandler(PREF_SEED_TIME, 0));
handlers.push_back(new FloatNumberOptionHandler(PREF_SEED_RATIO, 0.0));
handlers.push_back(new UnitNumberOptionHandler(PREF_MAX_UPLOAD_LIMIT, 0));
handlers.push_back(new DefaultOptionHandler(PREF_METALINK_VERSION));
handlers.push_back(new DefaultOptionHandler(PREF_METALINK_LANGUAGE));
handlers.push_back(new DefaultOptionHandler(PREF_METALINK_OS));
handlers.push_back(new BooleanOptionHandler(PREF_FOLLOW_METALINK));
handlers.push_back(new DefaultOptionHandler(PREF_METALINK_LOCATION));
handlers.push_back(new UnitNumberOptionHandler(PREF_LOWEST_SPEED_LIMIT, 0));
handlers.push_back(new UnitNumberOptionHandler(PREF_MAX_DOWNLOAD_LIMIT, 0));
handlers.push_back(new BooleanOptionHandler(PREF_ALLOW_OVERWRITE));
handlers.push_back(new BooleanOptionHandler(PREF_CHECK_INTEGRITY));
handlers.push_back(new BooleanOptionHandler(PREF_REALTIME_CHUNK_CHECKSUM));
handlers.push_back(new BooleanOptionHandler(PREF_DAEMON));
handlers.push_back(new DefaultOptionHandler(PREF_DIR));
handlers.push_back(new DefaultOptionHandler(PREF_OUT));
handlers.push_back(new LogOptionHandler(PREF_LOG));
handlers.push_back(new NumberOptionHandler(PREF_SPLIT, 1, 5));
handlers.push_back(new NumberOptionHandler(PREF_TIMEOUT, 1, 600));
handlers.push_back(new NumberOptionHandler(PREF_MAX_TRIES, 0));
handlers.push_back(new BooleanOptionHandler(PREF_FTP_PASV));
handlers.push_back(new BooleanOptionHandler(PREF_SHOW_FILES));
handlers.push_back(new DefaultOptionHandler(PREF_TORRENT_FILE));
handlers.push_back(new DefaultOptionHandler(PREF_METALINK_FILE));
handlers.push_back(new NumberOptionHandler(PREF_METALINK_SERVERS, 1));
handlers.push_back(new ParameterOptionHandler(PREF_FILE_ALLOCATION,
V_NONE, V_PREALLOC));
handlers.push_back(new BooleanOptionHandler(PREF_CONTINUE));
handlers.push_back(new DefaultOptionHandler(PREF_USER_AGENT));
return handlers;
}

View File

@ -0,0 +1,46 @@
/* <!-- 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_OPTION_HANDLER_FACTORY_H_
#define _D_OPTION_HANDLER_FACTORY_H_
#include "common.h"
#include "OptionHandler.h"
class OptionHandlerFactory {
public:
static OptionHandlers createOptionHandlers();
};
#endif // _D_OPTION_HANDLER_FACTORY_H_

249
src/OptionHandlerImpl.h Normal file
View File

@ -0,0 +1,249 @@
/* <!-- 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_OPTION_HANDLER_IMPL_H_
#define _D_OPTION_HANDLER_IMPL_H_
#include "OptionHandler.h"
#include "NameMatchOptionHandler.h"
#include "Util.h"
#include "FatalException.h"
#include "prefs.h"
#include <netinet/in.h>
class NullOptionHandler : public OptionHandler {
public:
virtual ~NullOptionHandler() {}
virtual bool canHandle(const string& optName) { return true; }
virtual void parseArg(Option* option, const string& arg) {}
};
class BooleanOptionHandler : public NameMatchOptionHandler {
public:
BooleanOptionHandler(const string& optName):NameMatchOptionHandler(optName) {}
virtual ~BooleanOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
if(optarg == "true") {
option->put(_optName, V_TRUE);
} else if(optarg == "false") {
option->put(_optName, V_FALSE);
} else {
string msg = _optName+" "+_("must be either 'true' or 'false'.");
throw new FatalException(msg.c_str());
}
}
};
class NumberOptionHandler : public NameMatchOptionHandler {
private:
int64_t _min;
int64_t _max;
public:
NumberOptionHandler(const string& optName, int64_t min = -1, int64_t max = -1):NameMatchOptionHandler(optName), _min(min), _max(max) {}
virtual ~NumberOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
int64_t num = strtoll(optarg.c_str(), 0, 10);
parseArg(option, num);
}
void parseArg(Option* option, int64_t number)
{
if((_min == -1 || _min <= number) && (_max == -1 || number <= _max)) {
option->put(_optName, Util::llitos(number));
} else {
string msg = _optName+" ";
if(_min == -1 && _max != -1) {
msg += _("must be smaller than or equal to %lld.");
throw new FatalException(msg.c_str(), _max);
} else if(_min != -1 && _max != -1) {
msg += _("must be between %lld and %lld.");
throw new FatalException(msg.c_str(), _min, _max);
} else if(_min != -1 && _max == -1) {
msg += _("must be greater than or equal to %lld.");
throw new FatalException(msg.c_str(), _min);
} else {
msg += _("must be a number.");
throw new FatalException(msg.c_str());
}
}
}
};
class UnitNumberOptionHandler : public NumberOptionHandler {
public:
UnitNumberOptionHandler(const string& optName, int64_t min = -1, int64_t max = -1):NumberOptionHandler(optName, min, max) {}
virtual ~UnitNumberOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
int64_t num = Util::getRealSize(optarg);
NumberOptionHandler::parseArg(option, num);
}
};
class FloatNumberOptionHandler : public NameMatchOptionHandler {
private:
double _min;
double _max;
public:
FloatNumberOptionHandler(const string& optName, double min = -1, double max = -1):NameMatchOptionHandler(optName), _min(min), _max(max) {}
virtual ~FloatNumberOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
double number = strtod(optarg.c_str(), 0);
if((_min < 0 || _min <= number) && (_max < 0 || number <= _max)) {
option->put(_optName, optarg);
} else {
string msg = _optName+" ";
if(_min < 0 && _max >= 0) {
msg += _("must be smaller than or equal to %.1f.");
throw new FatalException(msg.c_str(), _max);
} else if(_min >= 0 && _max >= 0) {
msg += _("must be between %.1f and %.1f.");
throw new FatalException(msg.c_str(), _min, _max);
} else if(_min >= 0 && _max < 0) {
msg += _("must be greater than or equal to %.1f.");
throw new FatalException(msg.c_str(), _min);
} else {
msg += _("must be a number.");
throw new FatalException(msg.c_str());
}
}
}
};
class DefaultOptionHandler : public NameMatchOptionHandler {
public:
DefaultOptionHandler(const string& optName):NameMatchOptionHandler(optName) {}
virtual ~DefaultOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
option->put(_optName, optarg);
}
};
class ParameterOptionHandler : public NameMatchOptionHandler {
private:
Strings _validParamValues;
public:
ParameterOptionHandler(const string& optName, const Strings& validParamValues):
NameMatchOptionHandler(optName), _validParamValues(validParamValues) {}
ParameterOptionHandler(const string& optName, const string& validParamValue):
NameMatchOptionHandler(optName)
{
_validParamValues.push_back(validParamValue);
}
ParameterOptionHandler(const string& optName,
const string& validParamValue1,
const string& validParamValue2):
NameMatchOptionHandler(optName)
{
_validParamValues.push_back(validParamValue1);
_validParamValues.push_back(validParamValue2);
}
virtual ~ParameterOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
Strings::const_iterator itr = find(_validParamValues.begin(), _validParamValues.end(), optarg);
if(itr == _validParamValues.end()) {
string msg = _optName+" "+_("must be one of the following:");
if(_validParamValues.size() == 0) {
msg += "''";
} else {
for(Strings::const_iterator itr = _validParamValues.begin();
itr != _validParamValues.end(); ++itr) {
msg += "'"+*itr+"' ";
}
}
throw new FatalException(msg.c_str());
} else {
option->put(_optName, optarg);
}
}
};
class HttpProxyOptionHandler : public NameMatchOptionHandler {
public:
HttpProxyOptionHandler(const string& optName):NameMatchOptionHandler(optName) {}
virtual ~HttpProxyOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
pair<string, string> proxy = Util::split(optarg, ":");
in_port_t port = strtol(proxy.second.c_str(), 0, 10);
if(proxy.first.empty() || proxy.second.empty() ||
port <= 0) {
throw new FatalException(_("unrecognized proxy format"));
}
option->put(PREF_HTTP_PROXY, optarg);
option->put(PREF_HTTP_PROXY_HOST, proxy.first);
option->put(PREF_HTTP_PROXY_PORT, Util::itos(port));
option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
}
};
class LogOptionHandler : public NameMatchOptionHandler {
public:
LogOptionHandler(const string& optName):NameMatchOptionHandler(optName) {}
virtual ~LogOptionHandler() {}
virtual void parseArg(Option* option, const string& optarg)
{
if("-" == optarg) {
option->put(PREF_STDOUT_LOG, V_TRUE);
} else {
option->put(PREF_LOG, optarg);
}
}
};
#endif // _D_OPTION_HANDLER_IMPL_H_

63
src/OptionParser.cc Normal file
View File

@ -0,0 +1,63 @@
/* <!-- 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 "OptionParser.h"
#include "Util.h"
#include "OptionHandlerImpl.h"
void OptionParser::parse(Option* option, istream& is)
{
string line;
int32_t linenum = 0;
while(getline(is, line)) {
++linenum;
if(Util::startsWith(line, "#")) {
continue;
}
pair<string, string> nv = Util::split(line, "=");
OptionHandlerHandle handler = getOptionHandlerByName(nv.first);
handler->parseArg(option, nv.second);
}
}
OptionHandlerHandle OptionParser::getOptionHandlerByName(const string& optName)
{
for(OptionHandlers::iterator itr = _optionHandlers.begin();
itr != _optionHandlers.end(); ++itr) {
if((*itr)->canHandle(optName)) {
return *itr;
}
}
return new NullOptionHandler();
}

61
src/OptionParser.h Normal file
View File

@ -0,0 +1,61 @@
/* <!-- 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_OPTION_PARSER_H_
#define _D_OPTION_PARSER_H_
#include "common.h"
#include "Option.h"
#include "OptionHandler.h"
#include <istream>
class OptionParser {
private:
OptionHandlers _optionHandlers;
public:
~OptionParser() {}
OptionHandlerHandle getOptionHandlerByName(const string& optName);
void parse(Option* option, istream& ios);
void setOptionHandlers(const OptionHandlers& optionHandlers)
{
_optionHandlers = optionHandlers;
}
};
typedef SharedHandle<OptionParser> OptionParserHandle;
#endif // _D_OPTION_PARSER_H_

View File

@ -531,7 +531,7 @@ void SegmentMan::tryChunkChecksumValidation(const SegmentHandle& segment)
int32_t dataLength =
offset+chunkHashLength <= totalSize ? chunkHashLength : totalSize-offset;
string actualChecksum = diskWriter->messageDigest(offset, dataLength, digestAlgo);
string expectedChecksum = pieceHashes.at(index);
string expectedChecksum = pieceHashes[index];
if(expectedChecksum == actualChecksum) {
logger->info("Good chunk checksum.");
} else {

View File

@ -673,3 +673,21 @@ string Util::getHomeDir()
return "";
}
}
int64_t Util::getRealSize(const string& sizeWithUnit)
{
string::size_type p = sizeWithUnit.find_first_of("KM");
string size;
int mult = 1;
if(p == string::npos) {
size = sizeWithUnit;
} else {
if(sizeWithUnit[p] == 'K') {
mult = 1024;
} else if(sizeWithUnit[p] == 'M') {
mult = 1024*1024;
}
size = sizeWithUnit.substr(0, p);
}
return strtoll(size.c_str(), 0, 10)*mult;
}

View File

@ -146,6 +146,8 @@ public:
int32_t srcLength, int32_t destLength);
static string getHomeDir();
static int64_t getRealSize(const string& sizeWithUnit);
};
#endif // _D_UTIL_H_

View File

@ -39,9 +39,12 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <string>
#include <deque>
#include <algorithm>

View File

@ -44,6 +44,10 @@
#include "ConsoleFileAllocationMonitor.h"
#include "Netrc.h"
#include "RequestFactory.h"
#include "OptionParser.h"
#include "OptionHandlerFactory.h"
#include "FatalException.h"
#include "File.h"
#include <deque>
#include <algorithm>
#include <time.h>
@ -51,6 +55,8 @@
#include <unistd.h>
#include <libgen.h>
#include <utility>
#include <fstream>
#include <sstream>
extern char* optarg;
extern int optind, opterr, optopt;
#include <getopt.h>
@ -195,6 +201,7 @@ void showUsage() {
" which download files from the beginning.\n"
" Currently this option is applicable to http(s)/\n"
" ftp downloads.") << endl;
cout << _(" -U, --user-agent=USER_AGENT Set user agent for http(s) downloads.") << endl;
#ifdef ENABLE_BITTORRENT
cout << _(" -T, --torrent-file=TORRENT_FILE The file path to .torrent file.") << endl;
cout << _(" --follow-torrent=true|false Setting this option to false prevents aria2 to\n"
@ -286,21 +293,6 @@ void showUsage() {
cout << endl;
}
long long int getRealSize(char* optarg) {
string::size_type p = string(optarg).find_first_of("KM");
int mult = 1;
if(p != string::npos) {
if(optarg[p] == 'K') {
mult = 1024;
} else if(optarg[p] == 'M') {
mult = 1024*1024;
}
optarg[p] = '\0';
}
long long int size = strtoll(optarg, NULL, 10)*mult;
return size;
}
int main(int argc, char* argv[]) {
#ifdef ENABLE_NLS
setlocale (LC_CTYPE, "");
@ -308,7 +300,7 @@ int main(int argc, char* argv[]) {
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif // ENABLE_NLS
stringstream cmdstream;
int c;
Option* op = new Option();
op->put(PREF_STDOUT_LOG, V_FALSE);
@ -359,6 +351,7 @@ int main(int argc, char* argv[]) {
op->put(PREF_CHECK_INTEGRITY, V_FALSE);
op->put(PREF_NETRC_PATH, Util::getHomeDir()+"/.netrc");
op->put(PREF_CONTINUE, V_FALSE);
op->put(PREF_USER_AGENT, "aria2");
while(1) {
int optIndex = 0;
int lopt;
@ -391,7 +384,8 @@ int main(int argc, char* argv[]) {
{ "allow-overwrite", required_argument, &lopt, 202 },
{ "check-integrity", required_argument, &lopt, 203 },
{ "realtime-chunk-checksum", required_argument, &lopt, 204 },
{ "continue", no_argument, NULL, 'c' },
{ "continue", no_argument, 0, 'c' },
{ "user-agent", required_argument, 0, 'U' },
#ifdef ENABLE_BITTORRENT
{ "torrent-file", required_argument, NULL, 'T' },
{ "listen-port", required_argument, &lopt, 15 },
@ -426,307 +420,149 @@ int main(int argc, char* argv[]) {
switch(c) {
case 0:{
switch(lopt) {
case 1: {
pair<string, string> proxy;
Util::split(proxy, optarg, ':');
int port = (int)strtol(proxy.second.c_str(), NULL, 10);
if(proxy.first.empty() || proxy.second.empty() ||
!(0 < port && port <= 65535)) {
cerr << _("unrecognized proxy format") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_HTTP_PROXY_HOST, proxy.first);
op->put(PREF_HTTP_PROXY_PORT, Util::itos(port));
op->put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
case 1:
cmdstream << PREF_HTTP_PROXY << "=" << optarg << "\n";
break;
}
case 2:
op->put(PREF_HTTP_USER, optarg);
op->put(PREF_HTTP_AUTH_ENABLED, V_TRUE);
cmdstream << PREF_HTTP_USER << "=" << optarg << "\n";
break;
case 3:
op->put(PREF_HTTP_PASSWD, optarg);
cmdstream << PREF_HTTP_PASSWD << "=" << optarg << "\n";
break;
case 4:
op->put(PREF_HTTP_PROXY_USER, optarg);
op->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
cmdstream << PREF_HTTP_PROXY_USER << "=" << optarg << "\n";
break;
case 5:
op->put(PREF_HTTP_PROXY_PASSWD, optarg);
cmdstream << PREF_HTTP_PROXY_PASSWD << "=" << optarg << "\n";
break;
case 6:
if(string(V_BASIC) == optarg) {
op->put(PREF_HTTP_AUTH_SCHEME, V_BASIC);
} else {
cerr << _("Currently, supported authentication scheme is basic.") << endl;
}
cmdstream << PREF_HTTP_AUTH_SCHEME << "=" << optarg << "\n";
break;
case 7:
op->put(PREF_REFERER, optarg);
cmdstream << PREF_REFERER << "=" << optarg << "\n";
break;
case 8: {
int wait = (int)strtol(optarg, NULL, 10);
if(!(0 <= wait && wait <= 60)) {
cerr << _("retry-wait must be between 0 and 60.") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_RETRY_WAIT, Util::itos(wait));
case 8:
cmdstream << PREF_RETRY_WAIT << "=" << optarg << "\n";
break;
}
case 9:
op->put(PREF_FTP_USER, optarg);
cmdstream << PREF_FTP_USER << "=" << optarg << "\n";
break;
case 10:
op->put(PREF_FTP_PASSWD, optarg);
cmdstream << PREF_FTP_PASSWD << "=" << optarg << "\n";
break;
case 11:
if(string(optarg) == V_BINARY || string(optarg) == V_ASCII) {
op->put(PREF_FTP_TYPE, optarg);
} else {
cerr << _("ftp-type must be either 'binary' or 'ascii'.") << endl;
exit(EXIT_FAILURE);
}
cmdstream << PREF_FTP_TYPE << "=" << optarg << "\n";
break;
case 12:
if(string(optarg) == V_GET || string(optarg) == V_TUNNEL) {
op->put(PREF_FTP_VIA_HTTP_PROXY, optarg);
} else {
cerr << _("ftp-via-http-proxy must be either 'get' or 'tunnel'.") << endl;
exit(EXIT_FAILURE);
}
cmdstream << PREF_FTP_VIA_HTTP_PROXY << "=" << optarg << "\n";
break;
case 13: {
long long int size = getRealSize(optarg);
if(size < 1024) {
cerr << _("min-segment-size invalid") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_MIN_SEGMENT_SIZE, Util::llitos(size));
case 13:
cmdstream << PREF_MIN_SEGMENT_SIZE << "=" << optarg << "\n";
break;
}
case 14:
if(string(optarg) == V_GET || string(optarg) == V_TUNNEL) {
op->put(PREF_HTTP_PROXY_METHOD, optarg);
} else {
cerr << _("http-proxy-method must be either 'get' or 'tunnel'.") << endl;
exit(EXIT_FAILURE);
}
cmdstream << PREF_HTTP_PROXY_METHOD << "=" << optarg << "\n";
break;
case 15: {
int listenPort = (int)strtol(optarg, NULL, 10);
if(!(1024 <= listenPort && listenPort <= 65535)) {
cerr << _("listen-port must be between 1024 and 65535.") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_LISTEN_PORT, Util::itos(listenPort));
case 15:
cmdstream << PREF_LISTEN_PORT << "=" << optarg << "\n";
break;
}
case 16:
if(string(optarg) == "true") {
op->put(PREF_FOLLOW_TORRENT, V_TRUE);
} else if(string(optarg) == "false") {
op->put(PREF_FOLLOW_TORRENT, V_FALSE);
} else {
cerr << _("follow-torrent must be either 'true' or 'false'.") << endl;
exit(EXIT_FAILURE);
}
cmdstream << PREF_FOLLOW_TORRENT << "=" << optarg << "\n";
break;
case 18:
op->put(PREF_NO_PREALLOCATION, V_TRUE);
cmdstream << PREF_NO_PREALLOCATION << "=" << V_TRUE << "\n";
break;
case 19:
if(string(optarg) == "true") {
op->put(PREF_DIRECT_FILE_MAPPING, V_TRUE);
} else if(string(optarg) == "false") {
op->put(PREF_DIRECT_FILE_MAPPING, V_FALSE);
} else {
cerr << _("direct-file-mapping must be either 'true' or 'false'.") << endl;
exit(EXIT_FAILURE);
}
cmdstream << PREF_DIRECT_FILE_MAPPING << "=" << optarg << "\n";
break;
case 21:
op->put(PREF_SELECT_FILE, optarg);
cmdstream << PREF_SELECT_FILE << "=" << optarg << "\n";
break;
case 22: {
int seedTime = (int)strtol(optarg, NULL, 10);
if(seedTime < 0) {
cerr << _("seed-time must be greater than or equal to 0.") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_SEED_TIME, Util::itos(seedTime));
case 22:
cmdstream << PREF_SEED_TIME << "=" << optarg << "\n";
break;
}
case 23: {
double ratio = (int)strtod(optarg, NULL);
if(ratio < 0.0) {
cerr << _("seed-ratio must be greater than or equal to 0.0.") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_SEED_RATIO, optarg);
case 23:
cmdstream << PREF_SEED_RATIO << "=" << optarg << "\n";
break;
}
case 24: {
int limit = getRealSize(optarg);
if(limit < 0) {
cerr << _("max-upload-limit must be greater than or equal to 0") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_MAX_UPLOAD_LIMIT, Util::itos(limit));
case 24:
cmdstream << PREF_MAX_UPLOAD_LIMIT << "=" << optarg << "\n";
break;
}
case 100:
op->put(PREF_METALINK_VERSION, optarg);
cmdstream << PREF_METALINK_VERSION << "=" << optarg << "\n";
break;
case 101:
op->put(PREF_METALINK_LANGUAGE, optarg);
cmdstream << PREF_METALINK_LANGUAGE << "=" << optarg << "\n";
break;
case 102:
op->put(PREF_METALINK_OS, optarg);
cmdstream << PREF_METALINK_OS << "=" << optarg << "\n";
break;
case 103:
if(string(optarg) == "true") {
op->put(PREF_FOLLOW_METALINK, V_TRUE);
} else if(string(optarg) == "false") {
op->put(PREF_FOLLOW_METALINK, V_FALSE);
} else {
cerr << _("follow-metalink must be either 'true' or 'false'.") << endl;
exit(EXIT_FAILURE);
}
cmdstream << PREF_FOLLOW_METALINK << "=" << optarg << "\n";
break;
case 104:
op->put(PREF_METALINK_LOCATION, optarg);
cmdstream << PREF_METALINK_LOCATION << "=" << optarg << "\n";
break;
case 200: {
int limit = getRealSize(optarg);
if(limit < 0) {
cerr << _("lowest-speed-limit must be greater than or equal to 0") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_LOWEST_SPEED_LIMIT, Util::itos(limit));
case 200:
cmdstream << PREF_LOWEST_SPEED_LIMIT << "=" << optarg << "\n";
break;
}
case 201: {
int limit = getRealSize(optarg);
if(limit < 0) {
cerr << _("max-download-limit must be greater than or equal to 0") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_MAX_DOWNLOAD_LIMIT, Util::itos(limit));
case 201:
cmdstream << PREF_MAX_DOWNLOAD_LIMIT << "=" << optarg << "\n";
break;
}
case 202: {
if(string(optarg) == "true") {
op->put(PREF_ALLOW_OVERWRITE, V_TRUE);
} else if(string(optarg) == "false") {
op->put(PREF_ALLOW_OVERWRITE, V_FALSE);
} else {
cerr << _("allow-overwrite must be either 'true' or 'false'.") << endl;
exit(EXIT_FAILURE);
}
case 202:
cmdstream << PREF_ALLOW_OVERWRITE << "=" << optarg << "\n";
break;
}
case 203: {
if(string(optarg) == "true") {
op->put(PREF_CHECK_INTEGRITY, V_TRUE);
} else if(string(optarg) == "false") {
op->put(PREF_CHECK_INTEGRITY, V_FALSE);
} else {
cerr << _("check-integrity must be be either 'true' or 'false'.") << endl;
exit(EXIT_FAILURE);
}
case 203:
cmdstream << PREF_CHECK_INTEGRITY << "=" << optarg << "\n";
break;
}
case 204: {
if(string(optarg) == "true") {
op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
} else if(string(optarg) == "false") {
op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_FALSE);
} else {
cerr << _("realtime-chunk-checksum must be either 'true' or 'false'.") << endl;
exit(EXIT_FAILURE);
}
case 204:
cmdstream << PREF_REALTIME_CHUNK_CHECKSUM << "=" << optarg << "\n";
break;
}
}
break;
}
case 'D':
op->put(PREF_DAEMON, V_TRUE);
cmdstream << PREF_DAEMON << "=" << V_TRUE << "\n";
break;
case 'd':
op->put(PREF_DIR, optarg);
cmdstream << PREF_DIR << "=" << optarg << "\n";
break;
case 'o':
op->put(PREF_OUT, optarg);
cmdstream << PREF_OUT << "=" << optarg << "\n";
break;
case 'l':
if(strcmp("-", optarg) == 0) {
op->put(PREF_STDOUT_LOG, V_TRUE);
} else {
op->put(PREF_LOG, optarg);
}
cmdstream << PREF_LOG << "=" << optarg << "\n";
break;
case 's': {
int split = (int)strtol(optarg, NULL, 10);
if(!(1 <= split && split <= 5)) {
cerr << _("split must be between 1 and 5.") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_SPLIT, Util::itos(split));
case 's':
cmdstream << PREF_SPLIT << "=" << optarg << "\n";
break;
}
case 't': {
int timeout = (int)strtol(optarg, NULL, 10);
if(1 <= timeout && timeout <= 600) {
op->put(PREF_TIMEOUT, Util::itos(timeout));
} else {
cerr << _("timeout must be between 1 and 600") << endl;
exit(EXIT_FAILURE);
}
case 't':
cmdstream << PREF_TIMEOUT << "=" << optarg << "\n";
break;
}
case 'm': {
int retries = (int)strtol(optarg, NULL, 10);
if(retries < 0) {
cerr << _("max-tries invalid") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_MAX_TRIES, Util::itos(retries));
case 'm':
cmdstream << PREF_MAX_TRIES << "=" << optarg << "\n";
break;
}
case 'p':
op->put(PREF_FTP_PASV_ENABLED, V_TRUE);
cmdstream << PREF_FTP_PASV << "=" << V_TRUE << "\n";
break;
case 'S':
op->put(PREF_SHOW_FILES, V_TRUE);
cmdstream << PREF_SHOW_FILES << "=" << V_TRUE << "\n";
break;
case 'T':
op->put(PREF_TORRENT_FILE, optarg);
cmdstream << PREF_TORRENT_FILE << "=" << optarg << "\n";
break;
case 'M':
op->put(PREF_METALINK_FILE, optarg);
cmdstream << PREF_METALINK_FILE << "=" << optarg << "\n";
break;
case 'C': {
int metalinkServers = (int)strtol(optarg, NULL, 10);
if(metalinkServers <= 0) {
cerr << _("metalink-servers must be greater than 0.") << endl;
exit(EXIT_FAILURE);
}
op->put(PREF_METALINK_SERVERS, Util::itos(metalinkServers));
case 'C':
cmdstream << PREF_METALINK_SERVERS << "=" << optarg << "\n";
break;
}
case 'a': {
string value = string(optarg);
if(value == V_NONE || value == V_PREALLOC) {
op->put(PREF_FILE_ALLOCATION, value);
} else {
cerr << _("file-allocation must be either 'none' or 'prealloc'.") << endl;
exit(EXIT_FAILURE);
}
case 'a':
cmdstream << PREF_FILE_ALLOCATION << "=" << optarg << "\n";
break;
}
case 'c':
op->put(PREF_CONTINUE, V_TRUE);
cmdstream << PREF_CONTINUE << "=" << V_TRUE << "\n";
break;
case 'U':
cmdstream << PREF_USER_AGENT << "=" << optarg << "\n";
break;
case 'v':
showVersion();
@ -738,6 +574,34 @@ int main(int argc, char* argv[]) {
exit(EXIT_FAILURE);
}
}
{
OptionParser oparser;
oparser.setOptionHandlers(OptionHandlerFactory::createOptionHandlers());
string cfname = Util::getHomeDir()+"/.aria2/aria2.conf";
ifstream cfstream(cfname.c_str());
try {
oparser.parse(op, cfstream);
} catch(Exception* e) {
cerr << "Parse error in " << cfname << endl;
cerr << e->getMsg() << endl;
delete e;
exit(EXIT_FAILURE);
}
try {
oparser.parse(op, cmdstream);
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
exit(EXIT_FAILURE);
}
}
if(op->defined(PREF_HTTP_USER)) {
op->put(PREF_HTTP_AUTH_ENABLED, V_TRUE);
}
if(op->defined(PREF_HTTP_PROXY_USER)) {
op->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
}
if(!op->defined(PREF_TORRENT_FILE) && !op->defined(PREF_METALINK_FILE)) {
if(optind == argc) {
cerr << _("specify at least one URL") << endl;
@ -779,9 +643,16 @@ int main(int argc, char* argv[]) {
logger->info("%s %s", PACKAGE, PACKAGE_VERSION);
logger->info("Logging started.");
NetrcHandle netrc = new Netrc();
netrc->parse(op->get(PREF_NETRC_PATH));
NetrcHandle netrc = 0;
File netrccf(op->get(PREF_NETRC_PATH));
mode_t mode = netrccf.mode();
if(mode&(S_IRWXG|S_IRWXO)) {
logger->notice(".netrc file %s does not have correct permissions. It should be 600. netrc support disabled.",
op->get(PREF_NETRC_PATH).c_str());
} else {
netrc = new Netrc();
netrc->parse(op->get(PREF_NETRC_PATH));
}
RequestFactoryHandle requestFactory = new RequestFactory();
requestFactory->setOption(op);
requestFactory->setNetrc(netrc);

View File

@ -79,7 +79,24 @@ public:
{
digestFree();
}
#ifdef HAVE_LIBSSL
#if defined(HAVE_OLD_LIBSSL)
void digestInit() {EVP_DigestInit(&ctx, algo);}
void digestReset() {EVP_DigestInit(&ctx, algo);}
void digestUpdate(const void* data, int length) {EVP_DigestUpdate(&ctx, data, length);}
void digestFinal(unsigned char* md) {
int len;
EVP_DigestFinal(&ctx, md, (unsigned int*)&len);
}
void digestFree() {/*empty*/}
int digestLength() const {
return digestLength(algo);
}
static int digestLength(DigestAlgo algo) {
return EVP_MD_size(algo);
}
#elif defined(HAVE_LIBSSL)
void digestInit() {
EVP_MD_CTX_init(&ctx);
digestReset();
@ -103,9 +120,8 @@ public:
static int digestLength(DigestAlgo algo) {
return EVP_MD_size(algo);
}
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
#elif defined(HAVE_LIBGCRYPT)
void digestInit() {
gcry_md_open(&ctx, algo, 0);
}

View File

@ -48,19 +48,19 @@
* General preferences
*/
// values: 1*digit
#define PREF_RETRY_WAIT "retry_wait"
#define PREF_RETRY_WAIT "retry-wait"
// values: 1*digit
#define PREF_TIMEOUT "timeout"
// values: 1*digit
#define PREF_DNS_TIMEOUT "dns_timeout"
#define PREF_DNS_TIMEOUT "dns-timeout"
// values: 1*digit
#define PREF_MAX_TRIES "max_tries"
#define PREF_MAX_TRIES "max-tries"
// values: 1*digit
#define PREF_MIN_SEGMENT_SIZE "min_segment_size"
#define PREF_MIN_SEGMENT_SIZE "min-segment-size"
// values: 1*digit
#define PREF_AUTO_SAVE_INTERVAL "auto_save_interval"
#define PREF_AUTO_SAVE_INTERVAL "auto-save-interval"
// values: true | false
#define PREF_STDOUT_LOG "stdout_log"
#define PREF_STDOUT_LOG "stdout-log"
// values: a string that your file system recognizes as a file name.
#define PREF_LOG "log"
// values: a string that your file system recognizes as a directory.
@ -74,120 +74,123 @@
// value: a string
#define PREF_REFERER "referer"
// value: 1*digit
#define PREF_LOWEST_SPEED_LIMIT "lowest_speed_limit"
#define PREF_LOWEST_SPEED_LIMIT "lowest-speed-limit"
// value: 1*digit
#define PREF_SEGMENT_SIZE "segment_size"
#define PREF_SEGMENT_SIZE "segment-size"
// value: 1*digit
#define PREF_MAX_DOWNLOAD_LIMIT "max_download_limit"
#define PREF_MAX_DOWNLOAD_LIMIT "max-download-limit"
// value: 1*digit
#define PREF_STARTUP_IDLE_TIME "startup_idle_time"
#define PREF_STARTUP_IDLE_TIME "startup-idle-time"
// value: prealloc | none
#define PREF_FILE_ALLOCATION "file_allocation"
#define PREF_FILE_ALLOCATION "file-allocation"
# define V_PREALLOC "prealloc"
// value: true | false
#define PREF_ALLOW_OVERWRITE "allow_overwrite"
#define PREF_ALLOW_OVERWRITE "allow-overwrite"
// value: true | false
#define PREF_REALTIME_CHUNK_CHECKSUM "realtime_chunk_checksum"
#define PREF_REALTIME_CHUNK_CHECKSUM "realtime-chunk-checksum"
// value: true | false
#define PREF_CHECK_INTEGRITY "check_integrity"
#define PREF_CHECK_INTEGRITY "check-integrity"
// value: string that your file system recognizes as a file name.
#define PREF_NETRC_PATH "netrc_path"
#define PREF_NETRC_PATH "netrc-path"
// value:
#define PREF_CONTINUE "continue"
/**
* FTP related preferences
*/
#define PREF_FTP_USER "ftp_user"
#define PREF_FTP_PASSWD "ftp_passwd"
#define PREF_FTP_USER "ftp-user"
#define PREF_FTP_PASSWD "ftp-passwd"
// values: binary | ascii
#define PREF_FTP_TYPE "ftp_type"
#define PREF_FTP_TYPE "ftp-type"
# define V_BINARY "binary"
# define V_ASCII "ascii"
// values: get | tunnel
#define PREF_FTP_VIA_HTTP_PROXY "ftp_via_http_proxy"
#define PREF_FTP_VIA_HTTP_PROXY "ftp-via-http-proxy"
# define V_GET "get"
# define V_TUNNEL "tunnel"
// values: true | false
#define PREF_FTP_PASV_ENABLED "ftp_pasv_enabled"
#define PREF_FTP_PASV "ftp-pasv"
/**
* HTTP related preferences
*/
#define PREF_HTTP_USER "http_user"
#define PREF_HTTP_PASSWD "http_passwd"
#define PREF_HTTP_USER "http-user"
#define PREF_HTTP_PASSWD "http-passwd"
// values: basic
#define PREF_HTTP_AUTH_SCHEME "http_auth_scheme"
#define PREF_HTTP_AUTH_SCHEME "http-auth-scheme"
# define V_BASIC "basic"
// values: true | false
#define PREF_HTTP_AUTH_ENABLED "http_auth_enabled"
#define PREF_HTTP_AUTH_ENABLED "http-auth-enabled"
// values: true | false
#define PREF_HTTP_KEEP_ALIVE "http_keep_alive"
#define PREF_HTTP_KEEP_ALIVE "http-keep-alive"
// values: string
#define PREF_USER_AGENT "user-agent"
/**
* HTTP proxy related preferences
*/
#define PREF_HTTP_PROXY_USER "http_proxy_user"
#define PREF_HTTP_PROXY_PASSWD "http_proxy_passwd"
#define PREF_HTTP_PROXY_HOST "http_proxy_host"
#define PREF_HTTP_PROXY_PORT "http_proxy_port"
#define PREF_HTTP_PROXY "http-proxy"
#define PREF_HTTP_PROXY_USER "http-proxy-user"
#define PREF_HTTP_PROXY_PASSWD "http-proxy-passwd"
#define PREF_HTTP_PROXY_HOST "http-proxy-host"
#define PREF_HTTP_PROXY_PORT "http-proxy-port"
// values: get | tunnel
#define PREF_HTTP_PROXY_METHOD "http_proxy_method"
#define PREF_HTTP_PROXY_METHOD "http-proxy-method"
// values: true | false
#define PREF_HTTP_PROXY_ENABLED "http_proxy_enabled"
#define PREF_HTTP_PROXY_ENABLED "http-proxy-enabled"
// values: true | false
#define PREF_HTTP_PROXY_AUTH_ENABLED "http_proxy_auth_enabled"
#define PREF_HTTP_PROXY_AUTH_ENABLED "http-proxy-auth-enabled"
/**
* BitTorrent related preferences
*/
// values: 1*digit
#define PREF_PEER_CONNECTION_TIMEOUT "peer_connection_timeout"
#define PREF_PEER_CONNECTION_TIMEOUT "peer-connection-timeout"
// values: 1*digit
#define PREF_BT_TIMEOUT "bt_timeout"
#define PREF_BT_TIMEOUT "bt-timeout"
// values: 1*digit
#define PREF_BT_REQUEST_TIMEOUT "bt_request_timeout"
#define PREF_BT_REQUEST_TIMEOUT "bt-request-timeout"
// values: true | false
#define PREF_SHOW_FILES "show_files"
#define PREF_SHOW_FILES "show-files"
// values: true | false
#define PREF_NO_PREALLOCATION "no_preallocation"
#define PREF_NO_PREALLOCATION "no-preallocation"
// values: true | false
#define PREF_DIRECT_FILE_MAPPING "direct_file_mapping"
#define PREF_DIRECT_FILE_MAPPING "direct-file-mapping"
// values: 1*digit
#define PREF_MAX_UPLOAD_LIMIT "max_upload_limit"
#define PREF_MAX_UPLOAD_LIMIT "max-upload-limit"
// values: a string that your file system recognizes as a file name.
#define PREF_TORRENT_FILE "torrent_file"
#define PREF_TORRENT_FILE "torrent-file"
// values: 1*digit
#define PREF_LISTEN_PORT "listen_port"
#define PREF_LISTEN_PORT "listen-port"
// values: true | false
#define PREF_FOLLOW_TORRENT "follow_torrent"
#define PREF_FOLLOW_TORRENT "follow-torrent"
// values: 1*digit *( (,|-) 1*digit)
#define PREF_SELECT_FILE "select_file"
#define PREF_SELECT_FILE "select-file"
// values: 1*digit
#define PREF_SEED_TIME "seed_time"
#define PREF_SEED_TIME "seed-time"
// values: 1*digit ['.' [ 1*digit ] ]
#define PREF_SEED_RATIO "seed_ratio"
#define PREF_SEED_RATIO "seed-ratio"
// values: 1*digit
#define PREF_TRACKER_MAX_TRIES "tracker_max_tries"
#define PREF_TRACKER_MAX_TRIES "tracker-max-tries"
// values: 1*digit
#define PREF_BT_KEEP_ALIVE_INTERVAL "bt_keep_alive_interval"
#define PREF_BT_KEEP_ALIVE_INTERVAL "bt-keep-alive-interval"
/**
* Metalink related preferences
*/
// values: a string that your file system recognizes as a file name.
#define PREF_METALINK_FILE "metalink_file"
#define PREF_METALINK_FILE "metalink-file"
// values: a string
#define PREF_METALINK_VERSION "metalink_version"
#define PREF_METALINK_VERSION "metalink-version"
// values: a string
#define PREF_METALINK_LANGUAGE "metalink_language"
#define PREF_METALINK_LANGUAGE "metalink-language"
// values: a string
#define PREF_METALINK_OS "metalink_os"
#define PREF_METALINK_OS "metalink-os"
// values: a string
#define PREF_METALINK_LOCATION "metalink_location"
#define PREF_METALINK_LOCATION "metalink-location"
// values: 1*digit
#define PREF_METALINK_SERVERS "metalink_servers"
#define PREF_METALINK_SERVERS "metalink-servers"
// values: true | false
#define PREF_FOLLOW_METALINK "follow_metalink"
#define PREF_FOLLOW_METALINK "follow-metalink"
#endif // _D_PREFS_H_

View File

@ -1,6 +1,8 @@
TESTS = aria2c
check_PROGRAMS = $(TESTS)
aria2c_SOURCES = AllTest.cc\
UtilTest.cc\
OptionHandlerTest.cc\
SegmentManTest.cc\
BitfieldManTest.cc\
GlowFileAllocatorTest.cc\
@ -15,7 +17,6 @@ aria2c_SOURCES = AllTest.cc\
FileTest.cc\
OptionTest.cc\
Base64Test.cc\
UtilTest.cc\
CookieBoxTest.cc\
DataTest.cc\
DictionaryTest.cc\

View File

@ -57,14 +57,15 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT)
am_aria2c_OBJECTS = AllTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \
am_aria2c_OBJECTS = AllTest.$(OBJEXT) UtilTest.$(OBJEXT) \
OptionHandlerTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \
BitfieldManTest.$(OBJEXT) GlowFileAllocatorTest.$(OBJEXT) \
RequestTest.$(OBJEXT) HttpRequestTest.$(OBJEXT) \
NetrcTest.$(OBJEXT) SingletonHolderTest.$(OBJEXT) \
HttpHeaderTest.$(OBJEXT) HttpResponseTest.$(OBJEXT) \
SharedHandleTest.$(OBJEXT) ChunkedEncodingTest.$(OBJEXT) \
FileTest.$(OBJEXT) OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) \
UtilTest.$(OBJEXT) CookieBoxTest.$(OBJEXT) DataTest.$(OBJEXT) \
CookieBoxTest.$(OBJEXT) DataTest.$(OBJEXT) \
DictionaryTest.$(OBJEXT) ListTest.$(OBJEXT) \
MetaFileUtilTest.$(OBJEXT) ShaVisitorTest.$(OBJEXT) \
PeerMessageUtilTest.$(OBJEXT) DefaultDiskWriterTest.$(OBJEXT) \
@ -259,6 +260,8 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
TESTS = aria2c
aria2c_SOURCES = AllTest.cc\
UtilTest.cc\
OptionHandlerTest.cc\
SegmentManTest.cc\
BitfieldManTest.cc\
GlowFileAllocatorTest.cc\
@ -273,7 +276,6 @@ aria2c_SOURCES = AllTest.cc\
FileTest.cc\
OptionTest.cc\
Base64Test.cc\
UtilTest.cc\
CookieBoxTest.cc\
DataTest.cc\
DictionaryTest.cc\
@ -435,6 +437,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkerTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskAdaptorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetrcTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionHandlerTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtilTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerTest.Po@am__quote@

360
test/OptionHandlerTest.cc Normal file
View File

@ -0,0 +1,360 @@
#include "OptionHandlerImpl.h"
#include "prefs.h"
#include "Exception.h"
#include <cppunit/extensions/HelperMacros.h>
class OptionHandlerTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(OptionHandlerTest);
CPPUNIT_TEST(testNullOptionHandler);
CPPUNIT_TEST(testBooleanOptionHandler);
CPPUNIT_TEST(testNumberOptionHandler);
CPPUNIT_TEST(testNumberOptionHandler_min);
CPPUNIT_TEST(testNumberOptionHandler_max);
CPPUNIT_TEST(testNumberOptionHandler_min_max);
CPPUNIT_TEST(testUnitNumberOptionHandler);
CPPUNIT_TEST(testParameterOptionHandler_1argInit);
CPPUNIT_TEST(testParameterOptionHandler_2argsInit);
CPPUNIT_TEST(testParameterOptionHandler_listInit);
CPPUNIT_TEST(testDefaultOptionHandler);
CPPUNIT_TEST(testFloatNumberOptionHandler);
CPPUNIT_TEST(testFloatNumberOptionHandler_min);
CPPUNIT_TEST(testFloatNumberOptionHandler_max);
CPPUNIT_TEST(testFloatNumberOptionHandler_min_max);
CPPUNIT_TEST(testLogOptionHandler);
CPPUNIT_TEST(testHttpProxyOptionHandler);
CPPUNIT_TEST_SUITE_END();
public:
void testNullOptionHandler();
void testBooleanOptionHandler();
void testNumberOptionHandler();
void testNumberOptionHandler_min();
void testNumberOptionHandler_max();
void testNumberOptionHandler_min_max();
void testUnitNumberOptionHandler();
void testParameterOptionHandler_1argInit();
void testParameterOptionHandler_2argsInit();
void testParameterOptionHandler_listInit();
void testDefaultOptionHandler();
void testFloatNumberOptionHandler();
void testFloatNumberOptionHandler_min();
void testFloatNumberOptionHandler_max();
void testFloatNumberOptionHandler_min_max();
void testLogOptionHandler();
void testHttpProxyOptionHandler();
};
CPPUNIT_TEST_SUITE_REGISTRATION( OptionHandlerTest );
void OptionHandlerTest::testNullOptionHandler()
{
NullOptionHandler handler;
CPPUNIT_ASSERT(handler.canHandle("foo"));
handler.parseArg(0, "bar");
}
void OptionHandlerTest::testBooleanOptionHandler()
{
BooleanOptionHandler handler("foo");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, V_TRUE);
CPPUNIT_ASSERT_EQUAL(string(V_TRUE), option.get("foo"));
handler.parseArg(&option, V_FALSE);
CPPUNIT_ASSERT_EQUAL(string(V_FALSE), option.get("foo"));
try {
handler.parseArg(&option, "hello");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testNumberOptionHandler()
{
NumberOptionHandler handler("foo");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "0");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
}
void OptionHandlerTest::testNumberOptionHandler_min()
{
NumberOptionHandler handler("foo", 1);
Option option;
handler.parseArg(&option, "1");
CPPUNIT_ASSERT_EQUAL(string("1"), option.get("foo"));
try {
handler.parseArg(&option, "0");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testNumberOptionHandler_max()
{
NumberOptionHandler handler("foo", -1, 100);
Option option;
handler.parseArg(&option, "100");
CPPUNIT_ASSERT_EQUAL(string("100"), option.get("foo"));
try {
handler.parseArg(&option, "101");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testNumberOptionHandler_min_max()
{
NumberOptionHandler handler("foo", 1, 100);
Option option;
handler.parseArg(&option, "1");
CPPUNIT_ASSERT_EQUAL(string("1"), option.get("foo"));
handler.parseArg(&option, "100");
CPPUNIT_ASSERT_EQUAL(string("100"), option.get("foo"));
try {
handler.parseArg(&option, "0");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "101");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testUnitNumberOptionHandler()
{
UnitNumberOptionHandler handler("foo");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "4294967296");
CPPUNIT_ASSERT_EQUAL(string("4294967296"), option.get("foo"));
handler.parseArg(&option, "4096M");
CPPUNIT_ASSERT_EQUAL(string("4294967296"), option.get("foo"));
handler.parseArg(&option, "4096K");
CPPUNIT_ASSERT_EQUAL(string("4194304"), option.get("foo"));
handler.parseArg(&option, "K");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
handler.parseArg(&option, "M");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
handler.parseArg(&option, "");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo"));
}
void OptionHandlerTest::testParameterOptionHandler_1argInit()
{
ParameterOptionHandler handler("foo", "value1");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "value1");
CPPUNIT_ASSERT_EQUAL(string("value1"), option.get("foo"));
try {
handler.parseArg(&option, "value3");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testParameterOptionHandler_2argsInit()
{
ParameterOptionHandler handler("foo", "value1", "value2");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "value1");
CPPUNIT_ASSERT_EQUAL(string("value1"), option.get("foo"));
handler.parseArg(&option, "value2");
CPPUNIT_ASSERT_EQUAL(string("value2"), option.get("foo"));
try {
handler.parseArg(&option, "value3");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testParameterOptionHandler_listInit()
{
Strings validValues;
validValues.push_back("value1");
validValues.push_back("value2");
ParameterOptionHandler handler("foo", validValues);
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "value1");
CPPUNIT_ASSERT_EQUAL(string("value1"), option.get("foo"));
handler.parseArg(&option, "value2");
CPPUNIT_ASSERT_EQUAL(string("value2"), option.get("foo"));
try {
handler.parseArg(&option, "value3");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testDefaultOptionHandler()
{
DefaultOptionHandler handler("foo");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "bar");
CPPUNIT_ASSERT_EQUAL(string("bar"), option.get("foo"));
handler.parseArg(&option, "");
CPPUNIT_ASSERT_EQUAL(string(""), option.get("foo"));
}
void OptionHandlerTest::testFloatNumberOptionHandler()
{
FloatNumberOptionHandler handler("foo");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "1.0");
CPPUNIT_ASSERT_EQUAL(string("1.0"), option.get("foo"));
}
void OptionHandlerTest::testFloatNumberOptionHandler_min()
{
FloatNumberOptionHandler handler("foo", 0.0);
Option option;
handler.parseArg(&option, "0.0");
CPPUNIT_ASSERT_EQUAL(string("0.0"), option.get("foo"));
try {
handler.parseArg(&option, "-0.1");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testFloatNumberOptionHandler_max()
{
FloatNumberOptionHandler handler("foo", -1, 10.0);
Option option;
handler.parseArg(&option, "10.0");
CPPUNIT_ASSERT_EQUAL(string("10.0"), option.get("foo"));
try {
handler.parseArg(&option, "10.1");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
{
FloatNumberOptionHandler handler("foo", 0.0, 10.0);
Option option;
handler.parseArg(&option, "0.0");
CPPUNIT_ASSERT_EQUAL(string("0.0"), option.get("foo"));
handler.parseArg(&option, "10.0");
CPPUNIT_ASSERT_EQUAL(string("10.0"), option.get("foo"));
try {
handler.parseArg(&option, "-0.1");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "10.1");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}
void OptionHandlerTest::testLogOptionHandler()
{
LogOptionHandler handler("foo");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "/tmp/log.txt");
CPPUNIT_ASSERT_EQUAL(string("/tmp/log.txt"), option.get(PREF_LOG));
CPPUNIT_ASSERT_EQUAL(string(""), option.get(PREF_STDOUT_LOG));
option.clear();
handler.parseArg(&option, "-");
CPPUNIT_ASSERT_EQUAL(string(""), option.get(PREF_LOG));
CPPUNIT_ASSERT_EQUAL(string(V_TRUE), option.get(PREF_STDOUT_LOG));
}
void OptionHandlerTest::testHttpProxyOptionHandler()
{
HttpProxyOptionHandler handler("foo");
CPPUNIT_ASSERT(handler.canHandle("foo"));
CPPUNIT_ASSERT(!handler.canHandle("foobar"));
Option option;
handler.parseArg(&option, "bar:80");
CPPUNIT_ASSERT_EQUAL(string("bar:80"), option.get(PREF_HTTP_PROXY));
CPPUNIT_ASSERT_EQUAL(string("bar"), option.get(PREF_HTTP_PROXY_HOST));
CPPUNIT_ASSERT_EQUAL(string("80"), option.get(PREF_HTTP_PROXY_PORT));
CPPUNIT_ASSERT_EQUAL(string(V_TRUE), option.get(PREF_HTTP_PROXY_ENABLED));
try {
handler.parseArg(&option, "bar");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "bar:");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, ":");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, ":80");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
try {
handler.parseArg(&option, "foo:bar");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}

View File

@ -22,6 +22,7 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testToLower);
CPPUNIT_TEST(testUrldecode);
CPPUNIT_TEST(testCountBit);
CPPUNIT_TEST(testGetRealSize);
CPPUNIT_TEST_SUITE_END();
private:
@ -44,6 +45,7 @@ public:
void testToLower();
void testUrldecode();
void testCountBit();
void testGetRealSize();
};
@ -289,3 +291,11 @@ void UtilTest::testCountBit() {
CPPUNIT_ASSERT_EQUAL(32, Util::countBit(UINT32_MAX));
CPPUNIT_ASSERT_EQUAL(8, Util::countBit(255));
}
void UtilTest::testGetRealSize()
{
CPPUNIT_ASSERT_EQUAL((int64_t)4294967296LL, Util::getRealSize("4096M"));
CPPUNIT_ASSERT_EQUAL((int64_t)1024, Util::getRealSize("1K"));
CPPUNIT_ASSERT_EQUAL((int64_t)0, Util::getRealSize(""));
CPPUNIT_ASSERT_EQUAL((int64_t)0, Util::getRealSize("foo"));
}