Ver Fonte

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
Tatsuhiro Tsujikawa há 17 anos atrás
pai
commit
92d702fa53

+ 18 - 0
ChangeLog

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

+ 2 - 1
src/AuthConfigFactory.cc

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

+ 4 - 4
src/HttpRequest.cc

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

+ 1 - 10
src/HttpRequest.h

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

+ 18 - 1
src/NetrcAuthResolver.cc

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

+ 10 - 0
src/NetrcAuthResolver.h

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

+ 1 - 0
src/OptionHandlerFactory.cc

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

+ 0 - 3
src/option_processing.cc

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

+ 0 - 2
src/prefs.cc

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

+ 0 - 2
src/prefs.h

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

+ 15 - 6
test/AuthConfigFactoryTest.cc

@@ -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");
@@ -56,10 +68,7 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http()
   // username and password in URI: disabled by default.
   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());
+		       factory.createAuthConfig(req)->getAuthText());  
 }
 
 void AuthConfigFactoryTest::testCreateAuthConfigForHttpProxy()

+ 41 - 49
test/HttpRequestTest.cc

@@ -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);
-  
-  httpRequest.configure(&option);
+  _option->put(PREF_HTTP_USER, "aria2user");
+  _option->put(PREF_HTTP_PASSWD, "aria2passwd");
+
+  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");
 

+ 15 - 0
test/NetrcAuthResolverTest.cc

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