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

To integrate Netrc into exsiting classes:
	* src/Request.h
	(_userDefinedAuthConfig): New variable.
	(findNetrcAuthenticator): New function.
	(segment): Removed.
	(setUserDefinedAuthConfig): New function.
	(resolveHttpAuthConfigItem): New function.
	(resolveFtpAuthConfigItem): New function.
	(resolveHttpProxyAuthConfigItem): New function.
	* src/HttpRequest.h
	(authConfig): Removed.
	(proxyAuthConfig): Removed.
	(setAuthConfig): Removed.
	(setProxyAuthConfig): Removed.
	* src/UrlRequest.h
	(getHeadResult): Added a parameter: authConfigHandle
	* src/common.h
	(SingletonHolder.h): New include.
	* src/main.cc
	(Netrc.h): New include.
	(main): Removed initial values of PREF_FTP_USER, 
PREF_FTP_PASSWD.
	Added initial value of PREF_NETRC_PATH.
	Added the initialization of netrc.
	* src/AuthConfig.h: New class.
	* src/prefs.h
	(PREF_NETRC_PATH): New definition.
	* src/HttpAuthConfig.h: Removed.
	* src/Netrc.cc
	(getRequiredNextToken): New function.
	(skipMacdef): New function.
	(parse): Rewritten.
	* src/Netrc.h
	(getRequiredNextToken): New function.
	(skipMacdef): New function.
	* src/Util.h, src/Util.cc
	(getHomeDir): New function.
	* src/TrackerWatcherComand.cc
	(createRequestCommand): Use AuthConfig.
	* src/FtpConnection.cc
	(sendUser): Use Request::resolveFtpAuthConfigItem().
	(sendPass): Use Request::resolveFtpAuthConfigItem().
	* src/Request.cc
	(findNetrcAuthenticator): New function.
	(resolveHttpAuthConfigItem): New function.
	(resolveFtpAuthConfigItem): New function.
	(resolveHttpProxyAuthConfigItem): New function.
	* src/UrlRequestInfo.cc: Use AuthConfig.
	* src/HttpRequest.cc
	(createRequest): Use authConfig.
	(getProxyAuthString): Use authConfig.
	(configure): Removed PREF_HTTP_USER, PREF_HTTP_PASSWD,
	PREF_HTTP_PROXY_USER, PREF_HTTP_PROXY_PASSWD.
This commit is contained in:
Tatsuhiro Tsujikawa 2007-03-18 15:42:34 +00:00
parent 58d4dde223
commit 7ff627079f
29 changed files with 685 additions and 100 deletions

View File

@ -1,3 +1,58 @@
2007-03-19 Tatsuhiro Tsujikawa <tujikawa at valkyrie dot rednoah com>
To integrate Netrc into exsiting classes:
* src/Request.h
(_userDefinedAuthConfig): New variable.
(findNetrcAuthenticator): New function.
(segment): Removed.
(setUserDefinedAuthConfig): New function.
(resolveHttpAuthConfigItem): New function.
(resolveFtpAuthConfigItem): New function.
(resolveHttpProxyAuthConfigItem): New function.
* src/HttpRequest.h
(authConfig): Removed.
(proxyAuthConfig): Removed.
(setAuthConfig): Removed.
(setProxyAuthConfig): Removed.
* src/UrlRequest.h
(getHeadResult): Added a parameter: authConfigHandle
* src/common.h
(SingletonHolder.h): New include.
* src/main.cc
(Netrc.h): New include.
(main): Removed initial values of PREF_FTP_USER, PREF_FTP_PASSWD.
Added initial value of PREF_NETRC_PATH.
Added the initialization of netrc.
* src/AuthConfig.h: New class.
* src/prefs.h
(PREF_NETRC_PATH): New definition.
* src/HttpAuthConfig.h: Removed.
* src/Netrc.cc
(getRequiredNextToken): New function.
(skipMacdef): New function.
(parse): Rewritten.
* src/Netrc.h
(getRequiredNextToken): New function.
(skipMacdef): New function.
* src/Util.h, src/Util.cc
(getHomeDir): New function.
* src/TrackerWatcherComand.cc
(createRequestCommand): Use AuthConfig.
* src/FtpConnection.cc
(sendUser): Use Request::resolveFtpAuthConfigItem().
(sendPass): Use Request::resolveFtpAuthConfigItem().
* src/Request.cc
(findNetrcAuthenticator): New function.
(resolveHttpAuthConfigItem): New function.
(resolveFtpAuthConfigItem): New function.
(resolveHttpProxyAuthConfigItem): New function.
* src/UrlRequestInfo.cc: Use AuthConfig.
* src/HttpRequest.cc
(createRequest): Use authConfig.
(getProxyAuthString): Use authConfig.
(configure): Removed PREF_HTTP_USER, PREF_HTTP_PASSWD,
PREF_HTTP_PROXY_USER, PREF_HTTP_PROXY_PASSWD.
2007-03-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To reduce overhead to find commands whose socket is either
@ -14,8 +69,6 @@
(waitData): Call Command::setStatusActive() when command's socket is
readable or writable.
2007-03-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To handle Segment as SegmentHandle:

2
TODO
View File

@ -25,3 +25,5 @@
* Add an ability of seeding
* Continue file allocation with existing file
* Rewrite HttpConnection::receiveResponse() using {i,o}stringstream
* -c command line option to continue the download of existing file assuming
that it was downloaded from the beginning.

106
src/AuthConfig.h Normal file
View File

@ -0,0 +1,106 @@
/* <!-- 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_AUTH_CONFIG_H_
#define _D_AUTH_CONFIG_H_
#include "common.h"
#include "AuthConfigItem.h"
#include "prefs.h"
#include "Option.h"
class AuthConfig {
private:
AuthConfigItemHandle httpAuthConfigItem;
AuthConfigItemHandle ftpAuthConfigItem;
AuthConfigItemHandle httpProxyAuthConfigItem;
AuthConfigItemHandle createAuthConfigItem(const string& user, const string& password)
{
if(user.length() > 0) {
return new AuthConfigItem(user, password);
} else {
return 0;
}
}
public:
AuthConfig():httpAuthConfigItem(0),
ftpAuthConfigItem(0),
httpProxyAuthConfigItem(0) {}
AuthConfigItemHandle getHttpAuthConfigItem() const
{
return httpAuthConfigItem;
}
void setHttpAuthConfigItem(const string& user, const string& password)
{
httpAuthConfigItem = createAuthConfigItem(user, password);
}
AuthConfigItemHandle getFtpAuthConfigItem() const
{
return ftpAuthConfigItem;
}
void setFtpAuthConfigItem(const string& user, const string& password)
{
ftpAuthConfigItem = createAuthConfigItem(user, password);
}
AuthConfigItemHandle getHttpProxyAuthConfigItem() const
{
return httpProxyAuthConfigItem;
}
void setHttpProxyAuthConfigItem(const string& user, const string& password)
{
httpProxyAuthConfigItem = createAuthConfigItem(user, password);
}
void configure(const Option* op)
{
setHttpAuthConfigItem(op->get(PREF_HTTP_USER),
op->get(PREF_HTTP_PASSWD));
setFtpAuthConfigItem(op->get(PREF_FTP_USER),
op->get(PREF_FTP_PASSWD));
setHttpProxyAuthConfigItem(op->get(PREF_HTTP_PROXY_USER),
op->get(PREF_HTTP_PROXY_PASSWD));
}
};
typedef SharedHandle<AuthConfig> AuthConfigHandle;
#endif // _D_AUTH_CONFIG_H_

68
src/AuthConfigItem.h Normal file
View File

@ -0,0 +1,68 @@
/* <!-- 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_AUTH_CONFIG_ITEM_H_
#define _D_AUTH_CONFIG_ITEM_H_
#include "common.h"
class AuthConfigItem {
private:
string _authScheme;
string _user;
string _password;
public:
AuthConfigItem(const string& user, const string& password):
_user(user), _password(password) {}
string getAuthText() const
{
return _user+":"+_password;
}
const string& getUser() const
{
return _user;
}
const string& getPassword() const
{
return _password;
}
};
typedef SharedHandle<AuthConfigItem> AuthConfigItemHandle;
#endif // _D_AUTH_CONFIG_ITEM_H_

View File

@ -49,13 +49,13 @@ FtpConnection::FtpConnection(int cuid, const SocketHandle& socket,
FtpConnection::~FtpConnection() {}
void FtpConnection::sendUser() const {
string request = "USER "+option->get(PREF_FTP_USER)+"\r\n";
string request = "USER "+req->resolveFtpAuthConfigItem()->getUser()+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
socket->writeData(request);
}
void FtpConnection::sendPass() const {
string request = "PASS "+option->get(PREF_FTP_PASSWD)+"\r\n";
string request = "PASS "+req->resolveFtpAuthConfigItem()->getPassword()+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, "PASS ********");
socket->writeData(request);
}

View File

@ -107,7 +107,7 @@ string HttpRequest::createRequest() const
}
if(authEnabled) {
requestLine += "Authorization: Basic "+
Base64::encode(authConfig->getAuthText())+"\r\n";
Base64::encode(request->resolveHttpAuthConfigItem()->getAuthText())+"\r\n";
}
if(getPreviousURI().size()) {
requestLine += "Referer: "+getPreviousURI()+"\r\n";
@ -145,7 +145,7 @@ string HttpRequest::createProxyRequest() const
string HttpRequest::getProxyAuthString() const {
return "Proxy-Authorization: Basic "+
Base64::encode(proxyAuthConfig->getAuthText())+"\r\n";
Base64::encode(request->resolveHttpProxyAuthConfigItem()->getAuthText())+"\r\n";
}
void HttpRequest::configure(const Option* option)
@ -155,8 +155,4 @@ void HttpRequest::configure(const Option* option)
option->get(PREF_HTTP_PROXY_ENABLED) == V_TRUE &&
option->get(PREF_HTTP_PROXY_METHOD) == V_GET;
proxyAuthEnabled = option->get(PREF_HTTP_PROXY_AUTH_ENABLED) == V_TRUE;
authConfig = new HttpAuthConfig(option->get(PREF_HTTP_USER),
option->get(PREF_HTTP_PASSWD));
proxyAuthConfig = new HttpAuthConfig(option->get(PREF_HTTP_PROXY_USER),
option->get(PREF_HTTP_PROXY_PASSWD));
}

View File

@ -39,7 +39,6 @@
#include "Segment.h"
#include "Range.h"
#include "Request.h"
#include "HttpAuthConfig.h"
#include "Option.h"
#include <netinet/in.h>
@ -54,14 +53,10 @@ private:
bool authEnabled;
HttpAuthConfigHandle authConfig;
bool proxyEnabled;
bool proxyAuthEnabled;
HttpAuthConfigHandle proxyAuthConfig;
string userAgent;
string getHostText(const string& host, in_port_t port) const;
@ -73,10 +68,8 @@ public:
segment(0),
entityLength(0),
authEnabled(false),
authConfig(0),
proxyEnabled(false),
proxyAuthEnabled(false),
proxyAuthConfig(0),
userAgent(USER_AGENT)
{}
@ -221,16 +214,6 @@ public:
this->authEnabled = authEnabled;
}
void setAuthConfig(const HttpAuthConfigHandle& authConfig)
{
this->authConfig = authConfig;
}
void setProxyAuthConfig(const HttpAuthConfigHandle& proxyAuthConfig)
{
this->proxyAuthConfig = proxyAuthConfig;
}
void setUserAgent(const string& userAgent)
{
this->userAgent = userAgent;

View File

@ -37,6 +37,27 @@
#include "RecoverableException.h"
#include <fstream>
string Netrc::getRequiredNextToken(ifstream& f) const
{
string token;
if(f >> token) {
return token;
} else {
throw new RecoverableException("Netrc:parse error. EOF reached where a token expected.");
}
}
void Netrc::skipMacdef(ifstream& f) const
{
string line;
getline(f, line);
while(getline(f, line)) {
if(line == "\r" || line == "") {
break;
}
}
}
void Netrc::parse(const string& path)
{
authenticators.clear();
@ -46,32 +67,29 @@ void Netrc::parse(const string& path)
throw new RecoverableException("File not found: %s", path.c_str());
}
int32_t lineNum = 0;
string line;
AuthenticatorHandle authenticator = 0;
while(getline(f, line)) {
++lineNum;
if(Util::trim(line).empty()) {
continue;
}
pair<string, string> nameValuePair = Util::split(line, "\r\n\t ");
if(nameValuePair.first == "machine") {
string token;
while(f >> token) {
if(token == "machine") {
storeAuthenticator(authenticator);
authenticator = new Authenticator();
authenticator->setMachine(nameValuePair.second);
} else if(nameValuePair.first == "default") {
authenticator->setMachine(getRequiredNextToken(f));
} else if(token == "default") {
storeAuthenticator(authenticator);
authenticator = new DefaultAuthenticator();
} else {
if(authenticator.isNull()) {
throw new RecoverableException("Malformed netrc file: line %d", lineNum);
throw new RecoverableException("Netrc:parse error. %s encounterd where 'machine' or 'default' expected.");
}
if(nameValuePair.first == "login") {
authenticator->setLogin(nameValuePair.second);
} else if(nameValuePair.first == "password") {
authenticator->setPassword(nameValuePair.second);
} else if(nameValuePair.first == "account") {
authenticator->setAccount(nameValuePair.second);
if(token == "login") {
authenticator->setLogin(getRequiredNextToken(f));
} else if(token == "password") {
authenticator->setPassword(getRequiredNextToken(f));
} else if(token == "account") {
authenticator->setAccount(getRequiredNextToken(f));
} else if(token == "macdef") {
getRequiredNextToken(f);
skipMacdef(f);
}
}
}

View File

@ -127,6 +127,10 @@ private:
Authenticators authenticators;
void storeAuthenticator(const AuthenticatorHandle& authenticator);
string getRequiredNextToken(ifstream& f) const;
void skipMacdef(ifstream& f) const;
public:
Netrc() {}

View File

@ -35,12 +35,16 @@
#include "Request.h"
#include "Util.h"
#include "FeatureConfig.h"
#include "Netrc.h"
const string Request::METHOD_GET = "get";
const string Request::METHOD_HEAD = "head";
Request::Request():port(0), tryCount(0), keepAlive(true), method(METHOD_GET), isTorrent(false) {
Request::Request():port(0), tryCount(0), keepAlive(true), method(METHOD_GET),
_userDefinedAuthConfig(0),
isTorrent(false)
{
cookieBox = new CookieBox();
}
@ -55,7 +59,6 @@ bool Request::setUrl(const string& url) {
bool Request::resetUrl() {
previousUrl = referer;
segment = Segment();
return setUrl(url);
}
@ -130,3 +133,52 @@ bool Request::parseUrl(const string& url) {
file += query;
return true;
}
AuthConfigItemHandle Request::findNetrcAuthenticator() const
{
if(!NetrcSingletonHolder::instance().isNull()) {
AuthenticatorHandle auth = NetrcSingletonHolder::instance()->findAuthenticator(getHost());
if(auth.isNull()) {
return 0;
} else {
return new AuthConfigItem(auth->getLogin(), auth->getPassword());
}
} else {
return 0;
}
}
AuthConfigItemHandle Request::resolveHttpAuthConfigItem() const
{
if(!_userDefinedAuthConfig.isNull() &&
!_userDefinedAuthConfig->getHttpAuthConfigItem().isNull()) {
return _userDefinedAuthConfig->getHttpAuthConfigItem();
} else {
return findNetrcAuthenticator();
}
}
AuthConfigItemHandle Request::resolveFtpAuthConfigItem() const
{
if(!_userDefinedAuthConfig.isNull() &&
!_userDefinedAuthConfig->getFtpAuthConfigItem().isNull()) {
return _userDefinedAuthConfig->getFtpAuthConfigItem();
} else {
AuthConfigItemHandle authConfig = findNetrcAuthenticator();
if(authConfig.isNull()) {
return new AuthConfigItem("anonymous", "ARIA2USER@");
} else {
return authConfig;
}
}
}
AuthConfigItemHandle Request::resolveHttpProxyAuthConfigItem() const
{
if(!_userDefinedAuthConfig.isNull() &&
!_userDefinedAuthConfig->getHttpProxyAuthConfigItem().isNull()) {
return _userDefinedAuthConfig->getHttpProxyAuthConfigItem();
} else {
return findNetrcAuthenticator();
}
}

View File

@ -34,14 +34,9 @@
/* copyright --> */
#ifndef _D_REQUEST_H_
#define _D_REQUEST_H_
#include <string>
#include <map>
#include "CookieBox.h"
#include "Segment.h"
#include "common.h"
#include "SharedHandle.h"
using namespace std;
#include "CookieBox.h"
#include "AuthConfig.h"
#define SAFE_CHARS "abcdefghijklmnopqrstuvwxyz"\
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
@ -75,9 +70,14 @@ private:
int trackerEvent;
bool keepAlive;
string method;
AuthConfigHandle _userDefinedAuthConfig;
bool parseUrl(const string& url);
AuthConfigItemHandle findNetrcAuthenticator() const;
public:
Segment segment;
CookieBox* cookieBox;
bool isTorrent;
public:
@ -116,6 +116,17 @@ public:
this->method = method;
}
void setUserDefinedAuthConfig(const AuthConfigHandle& authConfig)
{
_userDefinedAuthConfig = authConfig;
}
AuthConfigItemHandle resolveHttpAuthConfigItem() const;
AuthConfigItemHandle resolveFtpAuthConfigItem() const;
AuthConfigItemHandle resolveHttpProxyAuthConfigItem() const;
const string& getMethod() const {
return method;
}

View File

@ -32,27 +32,30 @@
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_HTTP_AUTH_CONFIG_H_
#define _D_HTTP_AUTH_CONFIG_H_
#ifndef _D_SINGLETON_HOLDER_H_
#define _D_SINGLETON_HOLDER_H_
#include "common.h"
class HttpAuthConfig {
template<typename T>
class SingletonHolder {
private:
string authScheme;
string authUser;
string authPassword;
static T _instance;
SingletonHolder() {}
public:
~SingletonHolder() {}
HttpAuthConfig(const string& authUser, const string& authPassword):
authUser(authUser), authPassword(authPassword) {}
string getAuthText() const
static T& instance()
{
return authUser+":"+authPassword;
return _instance;
}
static void instance(T& instance)
{
_instance = instance;
}
};
typedef SharedHandle<HttpAuthConfig> HttpAuthConfigHandle;
template<typename T>
T SingletonHolder<T>::_instance = 0;
#endif // _D_HTTP_AUTH_CONFIG_H_
#endif // _D_SINGLETON_HOLDER_H_

View File

@ -81,8 +81,11 @@ Command* TrackerWatcherCommand::createCommand() {
}
Command* TrackerWatcherCommand::createRequestCommand(const string& url) {
AuthConfigHandle authConfig = new AuthConfig();
authConfig->configure(e->option);
RequestHandle req;
req->setUrl(url);
req->setUserDefinedAuthConfig(authConfig);
req->isTorrent = true;
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand(btRuntime->getNewCuid(), req, e);

View File

@ -88,15 +88,18 @@ private:
Requests* requestsPtr;
string referer;
int split;
AuthConfigHandle _userDefinedAuthConfig;
string method;
public:
CreateRequest(Requests* requestsPtr,
const string& referer,
int split,
const AuthConfigHandle& userDefinedAuthConfig,
const string& method = Request::METHOD_GET)
:requestsPtr(requestsPtr),
referer(referer),
split(split),
_userDefinedAuthConfig(userDefinedAuthConfig),
method(method) {}
void operator()(const string& url) {
@ -104,6 +107,7 @@ public:
RequestHandle req;
req->setReferer(referer);
req->setMethod(method);
req->setUserDefinedAuthConfig(_userDefinedAuthConfig);
if(req->setUrl(url)) {
requestsPtr->push_back(req);
} else {
@ -120,12 +124,13 @@ void UrlRequestInfo::printUrls(const Strings& urls) const {
}
}
HeadResultHandle UrlRequestInfo::getHeadResult() {
HeadResultHandle UrlRequestInfo::getHeadResult(const AuthConfigHandle& authConfig) {
Requests requests;
for_each(urls.begin(), urls.end(),
CreateRequest(&requests,
op->get(PREF_REFERER),
1,
authConfig,
Request::METHOD_HEAD));
if(requests.size() == 0) {
return 0;
@ -153,12 +158,17 @@ RequestInfos UrlRequestInfo::execute() {
Requests requests;
Requests reserved;
printUrls(urls);
HeadResultHandle hr = getHeadResult();
AuthConfigHandle authConfig = new AuthConfig();
authConfig->configure(op);
HeadResultHandle hr = getHeadResult(authConfig);
for_each(urls.begin(), urls.end(),
CreateRequest(&requests,
op->get(PREF_REFERER),
op->getAsInt(PREF_SPLIT)));
op->getAsInt(PREF_SPLIT),
authConfig));
logger->info("Head result: filename=%s, total length=%s",
hr->filename.c_str(), Util::ullitos(hr->totalLength, true).c_str());

View File

@ -64,7 +64,7 @@ private:
Requests& reserved,
int maxConnections) const;
void printUrls(const Strings& urls) const;
HeadResultHandle getHeadResult();
HeadResultHandle getHeadResult(const AuthConfigHandle& authConfig);
public:
UrlRequestInfo(const Strings& urls, int maxConnections, Option* op):
RequestInfo(op),

View File

@ -664,3 +664,12 @@ void Util::indexRange(int32_t& startIndex, int32_t& endIndex,
endIndex = _endIndex;
}
string Util::getHomeDir()
{
const char* p = getenv("HOME");
if(p) {
return p;
} else {
return "";
}
}

View File

@ -144,6 +144,8 @@ public:
static void indexRange(int32_t& startIndex, int32_t& endIndex,
int64_t offset,
int32_t srcLength, int32_t destLength);
static string getHomeDir();
};
#endif // _D_UTIL_H_

View File

@ -70,6 +70,7 @@ public:
};
#include "SharedHandle.h"
#include "SingletonHolder.h"
typedef deque<string> Strings;
typedef deque<int32_t> Integers;

View File

@ -48,6 +48,7 @@
#include "BitfieldManFactory.h"
#include "SimpleRandomizer.h"
#include "ConsoleFileAllocationMonitor.h"
#include "Netrc.h"
#include <deque>
#include <algorithm>
#include <time.h>
@ -342,8 +343,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_MAX_TRIES, "5");
op->put(PREF_HTTP_AUTH_SCHEME, V_BASIC);
op->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);
op->put(PREF_FTP_USER, "anonymous");
op->put(PREF_FTP_PASSWD, "ARIA2USER@");
op->put(PREF_FTP_TYPE, V_BINARY);
op->put(PREF_FTP_VIA_HTTP_PROXY, V_TUNNEL);
op->put(PREF_AUTO_SAVE_INTERVAL, "60");
@ -357,6 +356,7 @@ int main(int argc, char* argv[]) {
op->put(PREF_ALLOW_OVERWRITE, V_FALSE);
op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
op->put(PREF_CHECK_INTEGRITY, V_FALSE);
op->put(PREF_NETRC_PATH, Util::getHomeDir()+"/.netrc");
while(1) {
int optIndex = 0;
int lopt;
@ -773,6 +773,10 @@ 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));
NetrcSingletonHolder::instance(netrc);
Util::setGlobalSignalHandler(SIGPIPE, SIG_IGN, 0);
RequestInfo* firstReqInfo = 0;

View File

@ -90,6 +90,8 @@
#define PREF_REALTIME_CHUNK_CHECKSUM "realtime_chunk_checksum"
// value: true | false
#define PREF_CHECK_INTEGRITY "check_integrity"
// value: string that your file system recognizes as a file name.
#define PREF_NETRC_PATH "netrc_path"
/**
* FTP related preferences

43
test/AuthConfigTest.cc Normal file
View File

@ -0,0 +1,43 @@
#include "AuthConfig.h"
#include "Option.h"
#include "prefs.h"
#include <cppunit/extensions/HelperMacros.h>
class AuthConfigTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(AuthConfigTest);
CPPUNIT_TEST(testGet);
CPPUNIT_TEST_SUITE_END();
public:
void testGet();
};
CPPUNIT_TEST_SUITE_REGISTRATION( AuthConfigTest );
void AuthConfigTest::testGet()
{
Option option;
option.put(PREF_HTTP_USER, "httpUser");
option.put(PREF_HTTP_PASSWD, "httpPassword");
option.put(PREF_FTP_USER, "ftpUser");
option.put(PREF_FTP_PASSWD, "ftpPassword");
option.put(PREF_HTTP_PROXY_USER, "httpProxyUser");
option.put(PREF_HTTP_PROXY_PASSWD, "httpProxyPassword");
AuthConfig authConfig;
authConfig.configure(&option);
AuthConfigItemHandle httpAuth = authConfig.getHttpAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("httpUser"), httpAuth->getUser());
CPPUNIT_ASSERT_EQUAL(string("httpPassword"), httpAuth->getPassword());
AuthConfigItemHandle ftpAuth = authConfig.getFtpAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("ftpUser"), ftpAuth->getUser());
CPPUNIT_ASSERT_EQUAL(string("ftpPassword"), ftpAuth->getPassword());
AuthConfigItemHandle httpProxyAuth = authConfig.getHttpProxyAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("httpProxyUser"), httpProxyAuth->getUser());
CPPUNIT_ASSERT_EQUAL(string("httpProxyPassword"), httpProxyAuth->getPassword());
}

View File

@ -81,6 +81,9 @@ void HttpRequestTest::testCreateRequest()
{
RequestHandle request = new Request();
request->setUrl("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");
AuthConfigHandle authConfig = new AuthConfig();
request->setUserDefinedAuthConfig(authConfig);
SegmentHandle segment = new Segment();
HttpRequest httpRequest;
@ -168,6 +171,7 @@ void HttpRequestTest::testCreateRequest()
option->put(PREF_HTTP_PROXY_USER, "aria2proxyuser");
option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
authConfig->configure(option.get());
httpRequest.configure(option.get());
expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
@ -278,6 +282,8 @@ void HttpRequestTest::testCreateRequest_ftp()
{
RequestHandle request = new Request();
request->setUrl("ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2");
AuthConfigHandle authConfig = new AuthConfig();
request->setUserDefinedAuthConfig(authConfig);
SegmentHandle segment = new Segment();
HttpRequest httpRequest;
@ -296,6 +302,7 @@ void HttpRequestTest::testCreateRequest_ftp()
option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
httpRequest.configure(option.get());
authConfig->configure(option.get());
string expectedText = "GET ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"

View File

@ -1,10 +1,12 @@
TESTS = aria2c
check_PROGRAMS = $(TESTS)
aria2c_SOURCES = AllTest.cc\
HttpHeaderTest.cc\
HttpRequestTest.cc\
HttpResponseTest.cc\
NetrcTest.cc\
HttpRequestTest.cc\
AuthConfigTest.cc\
SingletonHolderTest.cc\
HttpHeaderTest.cc\
HttpResponseTest.cc\
BitfieldManTest.cc\
SharedHandleTest.cc\
RequestTest.cc\

View File

@ -57,9 +57,10 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT)
am_aria2c_OBJECTS = AllTest.$(OBJEXT) HttpHeaderTest.$(OBJEXT) \
HttpRequestTest.$(OBJEXT) HttpResponseTest.$(OBJEXT) \
NetrcTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \
am_aria2c_OBJECTS = AllTest.$(OBJEXT) NetrcTest.$(OBJEXT) \
HttpRequestTest.$(OBJEXT) AuthConfigTest.$(OBJEXT) \
SingletonHolderTest.$(OBJEXT) HttpHeaderTest.$(OBJEXT) \
HttpResponseTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \
SharedHandleTest.$(OBJEXT) RequestTest.$(OBJEXT) \
ChunkedEncodingTest.$(OBJEXT) FileTest.$(OBJEXT) \
OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) UtilTest.$(OBJEXT) \
@ -258,10 +259,12 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
TESTS = aria2c
aria2c_SOURCES = AllTest.cc\
HttpHeaderTest.cc\
HttpRequestTest.cc\
HttpResponseTest.cc\
NetrcTest.cc\
HttpRequestTest.cc\
AuthConfigTest.cc\
SingletonHolderTest.cc\
HttpHeaderTest.cc\
HttpResponseTest.cc\
BitfieldManTest.cc\
SharedHandleTest.cc\
RequestTest.cc\
@ -386,6 +389,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceListTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfigTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64Test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldManTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtAllowedFastMessageTest.Po@am__quote@
@ -439,6 +443,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShareRatioSeedCriteriaTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SharedHandleTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingletonHolderTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalcTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommandTest.Po@am__quote@

View File

@ -7,10 +7,11 @@ using namespace std;
class NetrcTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(NetrcTest);
CPPUNIT_TEST(testFindAuthenticatable);
CPPUNIT_TEST(testFindAuthenticator);
CPPUNIT_TEST(testParse);
CPPUNIT_TEST(testParse_fileNotFound);
CPPUNIT_TEST(testParse_emptyfile);
CPPUNIT_TEST(testParse_malformedNetrc);
CPPUNIT_TEST_SUITE_END();
private:
@ -18,29 +19,30 @@ public:
void setUp() {
}
void testFindAuthenticatable();
void testFindAuthenticator();
void testParse();
void testParse_fileNotFound();
void testParse_emptyfile();
void testParse_malformedNetrc();
};
CPPUNIT_TEST_SUITE_REGISTRATION( NetrcTest );
void NetrcTest::testFindAuthenticatable()
void NetrcTest::testFindAuthenticator()
{
Netrc netrc;
netrc.addAuthenticatable(new Authenticator("host1", "tujikawa", "tujikawapasswd", "tujikawaaccount"));
netrc.addAuthenticatable(new Authenticator("host2", "aria2", "aria2password", "aria2account"));
netrc.addAuthenticatable(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
netrc.addAuthenticator(new Authenticator("host1", "tujikawa", "tujikawapasswd", "tujikawaaccount"));
netrc.addAuthenticator(new Authenticator("host2", "aria2", "aria2password", "aria2account"));
netrc.addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
AuthenticatorHandle aria2auth = netrc.findAuthenticatable("host2");
AuthenticatorHandle aria2auth = netrc.findAuthenticator("host2");
CPPUNIT_ASSERT(!aria2auth.isNull());
CPPUNIT_ASSERT_EQUAL(string("aria2"), aria2auth->getLogin());
CPPUNIT_ASSERT_EQUAL(string("aria2password"), aria2auth->getPassword());
CPPUNIT_ASSERT_EQUAL(string("aria2account"), aria2auth->getAccount());
AuthenticatorHandle defaultauth = netrc.findAuthenticatable("host3");
AuthenticatorHandle defaultauth = netrc.findAuthenticator("host3");
CPPUNIT_ASSERT(!defaultauth.isNull());
CPPUNIT_ASSERT_EQUAL(string("default"), defaultauth->getLogin());
CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), defaultauth->getPassword());
@ -51,7 +53,7 @@ void NetrcTest::testParse()
{
Netrc netrc;
netrc.parse("sample.netrc");
Authenticatables::const_iterator itr = netrc.getAuthenticatables().begin();
Authenticators::const_iterator itr = netrc.getAuthenticators().begin();
AuthenticatorHandle tujikawaauth = *itr;
CPPUNIT_ASSERT(!tujikawaauth.isNull());
@ -91,5 +93,17 @@ void NetrcTest::testParse_emptyfile()
Netrc netrc;
netrc.parse("emptyfile");
CPPUNIT_ASSERT_EQUAL((size_t)0, netrc.getAuthenticatables().size());
CPPUNIT_ASSERT_EQUAL((size_t)0, netrc.getAuthenticators().size());
}
void NetrcTest::testParse_malformedNetrc()
{
Netrc netrc;
try {
netrc.parse("malformed.netrc");
CPPUNIT_FAIL("exception must be threw.");
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}

View File

@ -1,5 +1,5 @@
#include "Request.h"
#include "Netrc.h"
#include <cppunit/extensions/HelperMacros.h>
class RequestTest:public CppUnit::TestFixture {
@ -25,6 +25,12 @@ class RequestTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testSafeChar);
CPPUNIT_TEST(testInnerLink);
CPPUNIT_TEST(testMetalink);
CPPUNIT_TEST(testResolveHttpAuthConfigItem);
CPPUNIT_TEST(testResolveHttpAuthConfigItem_noCandidate);
CPPUNIT_TEST(testResolveHttpProxyAuthConfigItem);
CPPUNIT_TEST(testResolveHttpProxyAuthConfigItem_noCandidate);
CPPUNIT_TEST(testResolveFtpAuthConfigItem);
CPPUNIT_TEST(testResolveFtpAuthConfigItem_noCandidate);
CPPUNIT_TEST_SUITE_END();
public:
@ -48,6 +54,12 @@ public:
void testSafeChar();
void testInnerLink();
void testMetalink();
void testResolveHttpAuthConfigItem();
void testResolveHttpAuthConfigItem_noCandidate();
void testResolveHttpProxyAuthConfigItem();
void testResolveHttpProxyAuthConfigItem_noCandidate();
void testResolveFtpAuthConfigItem();
void testResolveFtpAuthConfigItem_noCandidate();
};
@ -293,3 +305,118 @@ void RequestTest::testMetalink() {
bool v2 = req.setUrl("http://aria.rednoah.com/download/aria.tar.bz2#!metalink3!");
CPPUNIT_ASSERT(!v2);
}
void RequestTest::testResolveHttpAuthConfigItem()
{
Request req;
req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
// with no authConfig
CPPUNIT_ASSERT(req.resolveHttpAuthConfigItem().isNull());
// with Netrc
NetrcHandle netrc = new Netrc();
netrc->addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
NetrcSingletonHolder::instance(netrc);
CPPUNIT_ASSERT(!req.resolveHttpAuthConfigItem().isNull());
AuthConfigItemHandle authConfig1 = req.resolveHttpAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("default"), authConfig1->getUser());
CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), authConfig1->getPassword());
// with Netrc + user defined
AuthConfigHandle authConfig = new AuthConfig();
authConfig->setHttpAuthConfigItem("userDefinedUser", "userDefinedPassword");
req.setUserDefinedAuthConfig(authConfig);
CPPUNIT_ASSERT(!req.resolveHttpAuthConfigItem().isNull());
AuthConfigItemHandle authConfig2 = req.resolveHttpAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("userDefinedUser"), authConfig2->getUser());
CPPUNIT_ASSERT_EQUAL(string("userDefinedPassword"), authConfig2->getPassword());
}
void RequestTest::testResolveHttpAuthConfigItem_noCandidate()
{
Request req;
req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
NetrcHandle netrc = new Netrc();
netrc->addAuthenticator(new Authenticator("localhost2", "default", "defaultpassword", "defaultaccount"));
NetrcSingletonHolder::instance(netrc);
CPPUNIT_ASSERT(req.resolveHttpAuthConfigItem().isNull());
}
void RequestTest::testResolveHttpProxyAuthConfigItem()
{
Request req;
req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
// with no authConfig
CPPUNIT_ASSERT(req.resolveHttpProxyAuthConfigItem().isNull());
// with Netrc
NetrcHandle netrc = new Netrc();
netrc->addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
NetrcSingletonHolder::instance(netrc);
CPPUNIT_ASSERT(!req.resolveHttpProxyAuthConfigItem().isNull());
AuthConfigItemHandle authConfig1 = req.resolveHttpProxyAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("default"), authConfig1->getUser());
CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), authConfig1->getPassword());
// with Netrc + user defined
AuthConfigHandle authConfig = new AuthConfig();
authConfig->setHttpProxyAuthConfigItem("userDefinedUser", "userDefinedPassword");
req.setUserDefinedAuthConfig(authConfig);
CPPUNIT_ASSERT(!req.resolveHttpProxyAuthConfigItem().isNull());
AuthConfigItemHandle authConfig2 = req.resolveHttpProxyAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("userDefinedUser"), authConfig2->getUser());
CPPUNIT_ASSERT_EQUAL(string("userDefinedPassword"), authConfig2->getPassword());
}
void RequestTest::testResolveHttpProxyAuthConfigItem_noCandidate()
{
Request req;
req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
NetrcHandle netrc = new Netrc();
netrc->addAuthenticator(new Authenticator("localhost2", "default", "defaultpassword", "defaultaccount"));
NetrcSingletonHolder::instance(netrc);
CPPUNIT_ASSERT(req.resolveHttpProxyAuthConfigItem().isNull());
}
void RequestTest::testResolveFtpAuthConfigItem()
{
Request req;
req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
// with no authConfig
CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
CPPUNIT_ASSERT_EQUAL(string("anonymous"), req.resolveFtpAuthConfigItem()->getUser());
CPPUNIT_ASSERT_EQUAL(string("ARIA2USER@"), req.resolveFtpAuthConfigItem()->getPassword());
// with Netrc
NetrcHandle netrc = new Netrc();
netrc->addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
NetrcSingletonHolder::instance(netrc);
CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
AuthConfigItemHandle authConfig1 = req.resolveFtpAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("default"), authConfig1->getUser());
CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), authConfig1->getPassword());
// with Netrc + user defined
AuthConfigHandle authConfig = new AuthConfig();
authConfig->setFtpAuthConfigItem("userDefinedUser", "userDefinedPassword");
req.setUserDefinedAuthConfig(authConfig);
CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
AuthConfigItemHandle authConfig2 = req.resolveFtpAuthConfigItem();
CPPUNIT_ASSERT_EQUAL(string("userDefinedUser"), authConfig2->getUser());
CPPUNIT_ASSERT_EQUAL(string("userDefinedPassword"), authConfig2->getPassword());
}
void RequestTest::testResolveFtpAuthConfigItem_noCandidate()
{
Request req;
req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
NetrcHandle netrc = new Netrc();
netrc->addAuthenticator(new Authenticator("localhost2", "default", "defaultpassword", "defaultaccount"));
NetrcSingletonHolder::instance(netrc);
CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
CPPUNIT_ASSERT_EQUAL(string("anonymous"), req.resolveFtpAuthConfigItem()->getUser());
CPPUNIT_ASSERT_EQUAL(string("ARIA2USER@"), req.resolveFtpAuthConfigItem()->getPassword());
}

View File

@ -0,0 +1,57 @@
#include "SingletonHolder.h"
#include "SharedHandle.h"
#include <cppunit/extensions/HelperMacros.h>
using namespace std;
class SingletonHolderTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(SingletonHolderTest);
CPPUNIT_TEST(testInstance);
CPPUNIT_TEST_SUITE_END();
private:
public:
void setUp() {
}
void testInstance();
};
CPPUNIT_TEST_SUITE_REGISTRATION( SingletonHolderTest );
class M {
private:
string _greeting;
public:
M(const string& greeting):_greeting(greeting) {}
const string& greeting() const { return _greeting; }
void greeting(const string& greeting) {
_greeting = greeting;
}
};
typedef SharedHandle<M> MHandle;
typedef SharedHandle<int> IntHandle;
void SingletonHolderTest::testInstance()
{
MHandle m = new M("Hello world.");
SingletonHolder<MHandle>::instance(m);
cerr << SingletonHolder<MHandle>::instance()->greeting() << endl;
SingletonHolder<MHandle>::instance()->greeting("Yes, it worked!");
cerr << SingletonHolder<MHandle>::instance()->greeting() << endl;
IntHandle i = new int(100);
SingletonHolder<IntHandle>::instance(i);
cerr << SingletonHolder<IntHandle>::instance() << endl;
cerr << SingletonHolder<MHandle>::instance()->greeting() << endl;
}

4
test/malformed.netrc Normal file
View File

@ -0,0 +1,4 @@
machine host2
login aria2
password aria2password
account

View File

@ -2,13 +2,12 @@ machine host1
login tujikawa
password tujikawapassword
account tujikawaaccount
macdef init
cd /home/aria2 machine
machine host2
login aria2
password aria2password
account aria2account
default
login anonymous
password ARIA2@USER
account ARIA2@ACCT
default login anonymous password ARIA2@USER account ARIA2@ACCT