2008-09-25 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Use netrc for HTTP.
	Now FTP user/password is sent in Authorization header when
	--ftp-via-http-proxy=get is given.
	* src/AuthConfigFactory.cc
	* src/HttpRequest.cc
	* src/HttpRequest.h
	* src/NetrcAuthResolver.cc
	* src/NetrcAuthResolver.h
	* src/OptionHandlerFactory.cc
	* src/option_processing.cc
	* src/prefs.cc
	* src/prefs.h
	* test/AuthConfigFactoryTest.cc
	* test/HttpRequestTest.cc
	* test/NetrcAuthResolverTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2008-09-25 14:37:28 +00:00
parent 6bc233f414
commit 92d702fa53
13 changed files with 125 additions and 78 deletions

View File

@ -1,3 +1,21 @@
2008-09-25 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Use netrc for HTTP.
Now FTP user/password is sent in Authorization header when
--ftp-via-http-proxy=get is given.
* src/AuthConfigFactory.cc
* src/HttpRequest.cc
* src/HttpRequest.h
* src/NetrcAuthResolver.cc
* src/NetrcAuthResolver.h
* src/OptionHandlerFactory.cc
* src/option_processing.cc
* src/prefs.cc
* src/prefs.h
* test/AuthConfigFactoryTest.cc
* test/HttpRequestTest.cc
* test/NetrcAuthResolverTest.cc
2008-09-25 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Issue PWD command first and get working directory and use it as a prefix

View File

@ -88,11 +88,12 @@ AuthConfigFactory::createAuthConfig(const std::string& user, const std::string&
AuthResolverHandle AuthConfigFactory::createHttpAuthResolver() const
{
AbstractAuthResolverHandle resolver;
if(true || _option->getAsBool(PREF_NO_NETRC)) {
if(_option->getAsBool(PREF_NO_NETRC)) {
resolver.reset(new DefaultAuthResolver());
} else {
NetrcAuthResolverHandle authResolver(new NetrcAuthResolver());
authResolver->setNetrc(_netrc);
authResolver->ignoreDefault();
resolver = authResolver;
}
resolver->setUserDefinedAuthConfig(createAuthConfig(_option->get(PREF_HTTP_USER), _option->get(PREF_HTTP_PASSWD)));

View File

@ -52,7 +52,6 @@ namespace aria2 {
const std::string HttpRequest::USER_AGENT("aria2");
HttpRequest::HttpRequest():entityLength(0),
authEnabled(false),
proxyEnabled(false),
proxyAuthEnabled(false),
_contentEncodingEnabled(true),
@ -193,9 +192,11 @@ std::string HttpRequest::createRequest() const
if(proxyEnabled && proxyAuthEnabled) {
requestLine += getProxyAuthString();
}
if(authEnabled) {
std::string authString = AuthConfigFactorySingleton::instance()
->createAuthConfig(request)->getAuthText();
if(authString != ":") {
requestLine += "Authorization: Basic "+
Base64::encode(AuthConfigFactorySingleton::instance()->createAuthConfig(request)->getAuthText())+"\r\n";
Base64::encode(authString)+"\r\n";
}
if(getPreviousURI().size()) {
requestLine += "Referer: "+getPreviousURI()+"\r\n";
@ -274,7 +275,6 @@ void HttpRequest::addAcceptType(const std::string& type)
void HttpRequest::configure(const Option* option)
{
authEnabled = option->getAsBool(PREF_HTTP_AUTH_ENABLED);
proxyEnabled =
option->getAsBool(PREF_HTTP_PROXY_ENABLED) &&
option->get(PREF_HTTP_PROXY_METHOD) == V_GET;

View File

@ -59,8 +59,6 @@ private:
uint64_t entityLength;
bool authEnabled;
bool proxyEnabled;
bool proxyAuthEnabled;
@ -147,10 +145,8 @@ public:
/**
* Configures this object with option.
* Following values are evaluated:
* PREF_HTTP_AUTH_ENABLED, PREF_HTTP_PROXY_ENABLED,
* PREF_HTTP_PROXY_ENABLED,
* PREF_HTTP_PROXY_METHOD, PREF_HTTP_PROXY_AUTH_ENABLED,
* PREF_HTTP_USER, PREF_HTTP_PASSWD,
* PREF_HTTP_PROXY_USER, PREF_HTTP_PROXY_PASSWD
* The evaluation results are stored in instance variables.
*/
void configure(const Option* option);
@ -165,11 +161,6 @@ public:
this->proxyAuthEnabled = proxyAuthEnabled;
}
void setAuthEnabled(bool authEnabled)
{
this->authEnabled = authEnabled;
}
void enableContentEncoding();
void disableContentEncoding();

View File

@ -38,6 +38,8 @@
namespace aria2 {
NetrcAuthResolver::NetrcAuthResolver():_ignoreDefault(false) {}
AuthConfigHandle NetrcAuthResolver::resolveAuthConfig(const std::string& hostname)
{
if(_userDefinedAuthConfig.isNull()) {
@ -56,7 +58,12 @@ AuthConfigHandle NetrcAuthResolver::findNetrcAuthenticator(const std::string& ho
if(auth.isNull()) {
return _defaultAuthConfig;
} else {
return SharedHandle<AuthConfig>(new AuthConfig(auth->getLogin(), auth->getPassword()));
if(_ignoreDefault && auth->getMachine() == "") {
return _defaultAuthConfig;
} else {
return SharedHandle<AuthConfig>
(new AuthConfig(auth->getLogin(), auth->getPassword()));
}
}
}
}
@ -71,4 +78,14 @@ NetrcHandle NetrcAuthResolver::getNetrc() const
return _netrc;
}
void NetrcAuthResolver::ignoreDefault()
{
_ignoreDefault = true;
}
void NetrcAuthResolver::useDefault()
{
_ignoreDefault = false;
}
} // namespace aria2

View File

@ -45,8 +45,12 @@ class NetrcAuthResolver : public AbstractAuthResolver {
private:
SharedHandle<Netrc> _netrc;
bool _ignoreDefault;
SharedHandle<AuthConfig> findNetrcAuthenticator(const std::string& hostname) const;
public:
NetrcAuthResolver();
virtual ~NetrcAuthResolver() {}
virtual SharedHandle<AuthConfig> resolveAuthConfig(const std::string& hostname);
@ -54,6 +58,12 @@ public:
void setNetrc(const SharedHandle<Netrc>& netrc);
SharedHandle<Netrc> getNetrc() const;
// Ignores default token of netrc
void ignoreDefault();
// Uses default token of netrc
void useDefault();
};
typedef SharedHandle<NetrcAuthResolver> NetrcAuthResolverHandle;

View File

@ -612,6 +612,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
TEXT_NO_NETRC,
V_FALSE)); // TODO ommit?
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
handlers.push_back(op);
}
// BitTorrent/Metalink Options

View File

@ -524,9 +524,6 @@ Option* option_processing(int argc, char* const argv[])
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);
}

View File

@ -172,8 +172,6 @@ const std::string PREF_HTTP_PASSWD("http-passwd");
// values: basic
const std::string PREF_HTTP_AUTH_SCHEME("http-auth-scheme");
const std::string V_BASIC("basic");
// values: true | false
const std::string PREF_HTTP_AUTH_ENABLED("http-auth-enabled");
// values: string
const std::string PREF_USER_AGENT("user-agent");
// value: string that your file system recognizes as a file name.

View File

@ -176,8 +176,6 @@ extern const std::string PREF_HTTP_PASSWD;
// values: basic
extern const std::string PREF_HTTP_AUTH_SCHEME;
extern const std::string V_BASIC;
// values: true | false
extern const std::string PREF_HTTP_AUTH_ENABLED;
// values: string
extern const std::string PREF_USER_AGENT;
// value: string that your file system recognizes as a file name.

View File

@ -39,14 +39,26 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http()
CPPUNIT_ASSERT_EQUAL(std::string(":"),
factory.createAuthConfig(req)->getAuthText());
// with Netrc: disabled by default
// with Netrc
SharedHandle<Netrc> netrc(new Netrc());
netrc->addAuthenticator
(SharedHandle<Authenticator>(new Authenticator("localhost",
"localhostuser",
"localhostpass",
"localhostacct")));
netrc->addAuthenticator
(SharedHandle<Authenticator>(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount")));
factory.setNetrc(netrc);
CPPUNIT_ASSERT_EQUAL(std::string(":"),
CPPUNIT_ASSERT_EQUAL(std::string("localhostuser:localhostpass"),
factory.createAuthConfig(req)->getAuthText());
// See default token in netrc is ignored.
SharedHandle<Request> mirrorReq(new Request());
req->setUrl("http://mirror/");
CPPUNIT_ASSERT_EQUAL(std::string(":"),
factory.createAuthConfig(mirrorReq)->getAuthText());
// with Netrc + user defined
option.put(PREF_HTTP_USER, "userDefinedUser");
option.put(PREF_HTTP_PASSWD, "userDefinedPassword");
@ -57,9 +69,6 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http()
req->setUrl("http://aria2user:aria2password@localhost/download/aria2-1.0.0.tar.bz2");
CPPUNIT_ASSERT_EQUAL(std::string("userDefinedUser:userDefinedPassword"),
factory.createAuthConfig(req)->getAuthText());
// CPPUNIT_ASSERT_EQUAL(std::string("aria2user:aria2password"),
// factory.createAuthConfig(req)->getAuthText());
}
void AuthConfigFactoryTest::testCreateAuthConfigForHttpProxy()

View File

@ -29,9 +29,17 @@ class HttpRequestTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testEnableAcceptEncoding);
CPPUNIT_TEST_SUITE_END();
private:
SharedHandle<Option> _option;
public:
void setUp() {}
void setUp()
{
_option.reset(new Option());
SharedHandle<AuthConfigFactory> authConfigFactory
(new AuthConfigFactory(_option.get()));
SingletonHolder<SharedHandle<AuthConfigFactory> >::instance
(authConfigFactory);
}
void testGetStartByte();
void testGetEndByte();
@ -99,18 +107,11 @@ void HttpRequestTest::testCreateRequest()
{
SharedHandle<Piece> p;
Option option;
option.put(PREF_HTTP_AUTH_ENABLED, V_FALSE);
option.put(PREF_HTTP_PROXY_ENABLED, V_FALSE);
option.put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);
option.put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE);
option.put(PREF_HTTP_USER, "aria2user");
option.put(PREF_HTTP_PASSWD, "aria2passwd");
option.put(PREF_HTTP_PROXY_USER, "aria2proxyuser");
option.put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
SharedHandle<AuthConfigFactory> authConfigFactory(new AuthConfigFactory(&option));
SingletonHolder<SharedHandle<AuthConfigFactory> >::instance(authConfigFactory);
_option->put(PREF_HTTP_PROXY_ENABLED, V_FALSE);
_option->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);
_option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE);
_option->put(PREF_HTTP_PROXY_USER, "aria2proxyuser");
_option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
SharedHandle<Request> request(new Request());
request->supportsPersistentConnection(true);
@ -221,9 +222,10 @@ void HttpRequestTest::testCreateRequest()
httpRequest.setSegment(segment);
// enable http auth
option.put(PREF_HTTP_AUTH_ENABLED, V_TRUE);
_option->put(PREF_HTTP_USER, "aria2user");
_option->put(PREF_HTTP_PASSWD, "aria2passwd");
httpRequest.configure(&option);
httpRequest.configure(_option.get());
expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
@ -238,9 +240,9 @@ void HttpRequestTest::testCreateRequest()
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
// enable http proxy auth
option.put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
_option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
httpRequest.configure(&option);
httpRequest.configure(_option.get());
expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
@ -254,9 +256,9 @@ void HttpRequestTest::testCreateRequest()
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
option.put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
_option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
httpRequest.configure(&option);
httpRequest.configure(_option.get());
expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
@ -270,9 +272,9 @@ void HttpRequestTest::testCreateRequest()
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
option.put(PREF_HTTP_PROXY_METHOD, V_GET);
_option->put(PREF_HTTP_PROXY_METHOD, V_GET);
httpRequest.configure(&option);
httpRequest.configure(_option.get());
expectedText = "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
@ -306,9 +308,9 @@ void HttpRequestTest::testCreateRequest()
request->setPipeliningHint(false);
option.put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE);
_option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE);
httpRequest.configure(&option);
httpRequest.configure(_option.get());
expectedText = "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
@ -326,19 +328,13 @@ void HttpRequestTest::testCreateRequest()
void HttpRequestTest::testCreateRequest_ftp()
{
Option option;
option.put(PREF_HTTP_AUTH_ENABLED, V_FALSE);
option.put(PREF_HTTP_PROXY_ENABLED, V_FALSE);
option.put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);
option.put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE);
option.put(PREF_HTTP_USER, "aria2user");
option.put(PREF_HTTP_PASSWD, "aria2passwd");
option.put(PREF_HTTP_PROXY_USER, "aria2proxyuser");
option.put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
SharedHandle<AuthConfigFactory> authConfigFactory
(new AuthConfigFactory(&option));
SingletonHolder<SharedHandle<AuthConfigFactory> >::instance(authConfigFactory);
_option->put(PREF_HTTP_PROXY_ENABLED, V_FALSE);
_option->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);
_option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE);
_option->put(PREF_FTP_USER, "aria2user");
_option->put(PREF_FTP_PASSWD, "aria2passwd");
_option->put(PREF_HTTP_PROXY_USER, "aria2proxyuser");
_option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
SharedHandle<Request> request(new Request());
request->setUrl("ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2");
@ -351,7 +347,7 @@ void HttpRequestTest::testCreateRequest_ftp()
httpRequest.setRequest(request);
httpRequest.setSegment(segment);
httpRequest.configure(&option);
httpRequest.configure(_option.get());
std::string expectedText = "GET ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
@ -360,16 +356,17 @@ void HttpRequestTest::testCreateRequest_ftp()
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n"
"Connection: close\r\n"
"Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
"\r\n";
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
// How to enable HTTP proxy authorization in FTP download via HTTP proxy
option.put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
option.put(PREF_HTTP_PROXY_METHOD, V_GET);
option.put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
_option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
_option->put(PREF_HTTP_PROXY_METHOD, V_GET);
_option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
httpRequest.configure(&option);
httpRequest.configure(_option.get());
expectedText = "GET ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
@ -380,6 +377,7 @@ void HttpRequestTest::testCreateRequest_ftp()
"Connection: close\r\n"
"Proxy-Connection: close\r\n"
"Proxy-Authorization: Basic YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n"
"Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
"\r\n";
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
@ -592,12 +590,6 @@ void HttpRequestTest::testIsRangeSatisfied()
void HttpRequestTest::testUserAgent()
{
Option option;
SharedHandle<AuthConfigFactory> authConfigFactory
(new AuthConfigFactory(&option));
SingletonHolder<SharedHandle<AuthConfigFactory> >::instance(authConfigFactory);
SharedHandle<Request> request(new Request());
request->setUrl("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");

View File

@ -11,6 +11,7 @@ class NetrcAuthResolverTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(NetrcAuthResolverTest);
CPPUNIT_TEST(testResolveAuthConfig_without_userDefined);
CPPUNIT_TEST(testResolveAuthConfig_with_userDefined);
CPPUNIT_TEST(testResolveAuthConfig_ignoreDefault);
CPPUNIT_TEST_SUITE_END();
private:
SharedHandle<Netrc> _netrc;
@ -34,6 +35,7 @@ public:
void testResolveAuthConfig_without_userDefined();
void testResolveAuthConfig_with_userDefined();
void testResolveAuthConfig_ignoreDefault();
};
@ -68,4 +70,17 @@ void NetrcAuthResolverTest::testResolveAuthConfig_with_userDefined()
CPPUNIT_ASSERT_EQUAL(std::string("myname:mypasswd"), authConfig->getAuthText());
}
void NetrcAuthResolverTest::testResolveAuthConfig_ignoreDefault()
{
_resolver->ignoreDefault();
SharedHandle<AuthConfig> authConfig = _resolver->resolveAuthConfig("mirror");
CPPUNIT_ASSERT_EQUAL(std::string("foo:bar"), authConfig->getAuthText());
_resolver->useDefault();
SharedHandle<AuthConfig> defAuthConfig =
_resolver->resolveAuthConfig("mirror");
CPPUNIT_ASSERT_EQUAL(std::string("default:defaultpasswd"),
defAuthConfig->getAuthText());
}
} // namespace aria2