Procházet zdrojové kódy

2008-11-04 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Deprecated --http-proxy-user and --http-proxy-passwd options.
	Added --https-proxy, --ftp-proxy and --all-proxy options.
	Above 3 options and --http-proxy option can handle proxy in URL
	format like: http://user:passwd@host:port.
	If a proxy requires user/password, they must be specified in a
	URL.
	Deprecated --ftp-via-http-proxy option. Use --http-proxy-method
	option instead.
	* src/AbstractCommand.cc
	* src/AbstractCommand.h
	* src/AbstractProxyRequestCommand.cc
	* src/AbstractProxyRequestCommand.h
	* src/AuthConfigFactory.cc
	* src/AuthConfigFactory.h
	* src/FtpFinishDownloadCommand.cc
	* src/FtpInitiateConnectionCommand.cc
	* src/FtpInitiateConnectionCommand.h
	* src/FtpNegotiationCommand.cc
	* src/FtpTunnelRequestCommand.cc
	* src/FtpTunnelRequestCommand.h
	* src/HttpDownloadCommand.cc
	* src/HttpInitiateConnectionCommand.cc
	* src/HttpInitiateConnectionCommand.h
	* src/HttpProxyRequestCommand.cc
	* src/HttpProxyRequestCommand.h
	* src/HttpRequest.cc
	* src/HttpRequest.h
	* src/HttpRequestCommand.cc
	* src/HttpRequestCommand.h
	* src/HttpSkipResponseCommand.cc
	* src/InitiateConnectionCommand.cc
	* src/InitiateConnectionCommand.h
	* src/OptionHandlerFactory.cc
	* src/OptionHandlerImpl.h
	* src/Request.cc
	* src/option_processing.cc
	* src/prefs.cc
	* src/prefs.h
	* src/usage_text.h
	* test/AuthConfigFactoryTest.cc
	* test/HttpRequestTest.cc
	* test/OptionHandlerTest.cc
Tatsuhiro Tsujikawa před 17 roky
rodič
revize
c7fb678e6e

+ 44 - 0
ChangeLog

@@ -1,3 +1,47 @@
+2008-11-04  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Deprecated --http-proxy-user and --http-proxy-passwd options.
+	Added --https-proxy, --ftp-proxy and --all-proxy options.
+	Above 3 options and --http-proxy option can handle proxy in URL format
+	like: http://user:passwd@host:port.
+	If a proxy requires user/password, they must be specified in a URL.
+	Deprecated --ftp-via-http-proxy option. Use --http-proxy-method option
+	instead.
+	* src/AbstractCommand.cc
+	* src/AbstractCommand.h
+	* src/AbstractProxyRequestCommand.cc
+	* src/AbstractProxyRequestCommand.h
+	* src/AuthConfigFactory.cc
+	* src/AuthConfigFactory.h
+	* src/FtpFinishDownloadCommand.cc
+	* src/FtpInitiateConnectionCommand.cc
+	* src/FtpInitiateConnectionCommand.h
+	* src/FtpNegotiationCommand.cc
+	* src/FtpTunnelRequestCommand.cc
+	* src/FtpTunnelRequestCommand.h
+	* src/HttpDownloadCommand.cc
+	* src/HttpInitiateConnectionCommand.cc
+	* src/HttpInitiateConnectionCommand.h
+	* src/HttpProxyRequestCommand.cc
+	* src/HttpProxyRequestCommand.h
+	* src/HttpRequest.cc
+	* src/HttpRequest.h
+	* src/HttpRequestCommand.cc
+	* src/HttpRequestCommand.h
+	* src/HttpSkipResponseCommand.cc
+	* src/InitiateConnectionCommand.cc
+	* src/InitiateConnectionCommand.h
+	* src/OptionHandlerFactory.cc
+	* src/OptionHandlerImpl.h
+	* src/Request.cc
+	* src/option_processing.cc
+	* src/prefs.cc
+	* src/prefs.h
+	* src/usage_text.h
+	* test/AuthConfigFactoryTest.cc
+	* test/HttpRequestTest.cc
+	* test/OptionHandlerTest.cc
+
 2008-11-03  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Execute choking algorithm when unchoked and interested peer is

+ 70 - 10
src/AbstractCommand.cc

@@ -57,6 +57,7 @@
 #include "StringFormat.h"
 #include "ServerStat.h"
 #include "RequestGroupMan.h"
+#include "A2STR.h"
 
 namespace aria2 {
 
@@ -291,17 +292,76 @@ void AbstractCommand::setWriteCheckSocketIf
   }
 }
 
-static bool isProxyGETRequest(const std::string& protocol, const Option* option)
+static const std::string& getProxyStringFor(const std::string& proxyPref,
+					    const Option* option)
+{
+  if(option->defined(proxyPref)) {
+    return option->get(proxyPref);
+  } else {
+    return option->get(PREF_ALL_PROXY);
+  }
+}
+
+static bool isProxyUsed(const std::string& proxyPref,
+			const Option* option)
+{
+  std::string proxy = getProxyStringFor(proxyPref, option);
+  if(proxy.empty()) {
+    return false;
+  } else {
+    return Request().setUrl(proxy);
+  }
+}
+
+static bool isProxyRequest(const std::string& protocol, const Option* option)
 {
   return
-    // For HTTP/HTTPS
-    ((protocol == Request::PROTO_HTTP || protocol == Request::PROTO_HTTPS) &&
-     (option->getAsBool(PREF_HTTP_PROXY_ENABLED) &&
-      option->get(PREF_HTTP_PROXY_METHOD) == V_GET)) ||
-    // For FTP
-    (protocol == Request::PROTO_FTP &&
-     (option->getAsBool(PREF_HTTP_PROXY_ENABLED) &&
-      option->get(PREF_FTP_VIA_HTTP_PROXY) == V_GET));
+    (protocol == Request::PROTO_HTTP && isProxyUsed(PREF_HTTP_PROXY, option)) ||
+    (protocol == Request::PROTO_HTTPS && isProxyUsed(PREF_HTTPS_PROXY,option))||
+    (protocol == Request::PROTO_FTP && isProxyUsed(PREF_FTP_PROXY, option));
+}
+
+static bool isProxyGETRequest(const std::string& protocol, const Option* option)
+{
+  if(option->get(PREF_HTTP_PROXY_METHOD) != V_GET) {
+    return false;
+  }
+  return isProxyRequest(protocol, option);
+}
+
+bool AbstractCommand::isProxyDefined() const
+{
+  return isProxyRequest(req->getProtocol(), e->option);
+}
+
+static const std::string& getProxyString(const SharedHandle<Request>& req,
+					 const Option* option)
+{
+  if(req->getProtocol() == Request::PROTO_HTTP) {
+    return getProxyStringFor(PREF_HTTP_PROXY, option);
+  } else if(req->getProtocol() == Request::PROTO_HTTPS) {
+    return getProxyStringFor(PREF_HTTPS_PROXY, option);
+  } else if(req->getProtocol() == Request::PROTO_FTP) {
+    return getProxyStringFor(PREF_FTP_PROXY, option);
+  } else {
+    return A2STR::NIL;
+  }
+}
+
+SharedHandle<Request> AbstractCommand::createProxyRequest() const
+{
+  SharedHandle<Request> proxyRequest;
+  std::string proxy = getProxyString(req, e->option);
+  if(!proxy.empty()) {
+    proxyRequest.reset(new Request());
+    if(proxyRequest->setUrl(proxy)) {
+      logger->debug("CUID#%d - Using proxy", cuid);      
+    } else {
+      logger->debug("CUID#%d - Failed to parse proxy string", cuid);
+      proxyRequest.reset();
+    }
+  }
+  return proxyRequest;
 }
 
 #ifdef ENABLE_ASYNC_DNS
@@ -325,7 +385,7 @@ bool AbstractCommand::asyncResolveHostname()
   case AsyncNameResolver::STATUS_SUCCESS:
     return true;
   case AsyncNameResolver::STATUS_ERROR:
-    if(!isProxyGETRequest(req->getProtocol(), e->option)) {
+    if(!isProxyRequest(req->getProtocol(), e->option)) {
       e->_requestGroupMan->getOrCreateServerStat
 	(req->getHost(), req->getProtocol())->setError();
     }

+ 12 - 0
src/AbstractCommand.h

@@ -100,6 +100,18 @@ protected:
   void prepareForNextAction(Command* nextCommand = 0);
 
   void checkIfConnectionEstablished(const SharedHandle<SocketCore>& socket);
+
+  /*
+   * Returns true if proxy for the procol indicated by Request::getProtocol()
+   * is defined. Otherwise, returns false.
+   */
+  bool isProxyDefined() const;
+
+  /*
+   * Creates Request object for proxy URI and returns it.
+   * If no valid proxy is defined, then returns SharedHandle<Request>().
+   */
+  SharedHandle<Request> createProxyRequest() const;
 private:
   bool checkSocketIsReadable;
   bool checkSocketIsWritable;

+ 12 - 9
src/AbstractProxyRequestCommand.cc

@@ -47,13 +47,17 @@
 
 namespace aria2 {
 
-AbstractProxyRequestCommand::AbstractProxyRequestCommand(int cuid,
-							 const RequestHandle& req,
-							 RequestGroup* requestGroup,
-							 DownloadEngine* e,
-							 const SocketHandle& s)
-  :AbstractCommand(cuid, req, requestGroup, e, s),
-   httpConnection(new HttpConnection(cuid, s, e->option))
+AbstractProxyRequestCommand::AbstractProxyRequestCommand
+(int cuid,
+ const RequestHandle& req,
+ RequestGroup* requestGroup,
+ DownloadEngine* e,
+ const SharedHandle<Request>& proxyRequest,
+ const SocketHandle& s)
+  :
+  AbstractCommand(cuid, req, requestGroup, e, s),
+  _proxyRequest(proxyRequest),
+  httpConnection(new HttpConnection(cuid, s, e->option))
 {
   setTimeout(e->option->getAsInt(PREF_CONNECT_TIMEOUT));
   disableReadCheckSocket();
@@ -69,8 +73,7 @@ bool AbstractProxyRequestCommand::executeInternal() {
     httpRequest->setUserAgent(e->option->get(PREF_USER_AGENT));
     httpRequest->setRequest(req);
     httpRequest->setAuthConfigFactory(e->getAuthConfigFactory());
-
-    httpRequest->configure(e->option);
+    httpRequest->setProxyRequest(_proxyRequest);
 
     httpConnection->sendProxyRequest(httpRequest);
   } else {

+ 4 - 0
src/AbstractProxyRequestCommand.h

@@ -44,6 +44,8 @@ class SocketCore;
 
 class AbstractProxyRequestCommand : public AbstractCommand {
 protected:
+  SharedHandle<Request> _proxyRequest;
+
   SharedHandle<HttpConnection> httpConnection;
 
   virtual bool executeInternal();
@@ -52,7 +54,9 @@ public:
 			      const SharedHandle<Request>& req,
 			      RequestGroup* requestGroup,
 			      DownloadEngine* e,
+			      const SharedHandle<Request>& proxyRequest,
 			      const SharedHandle<SocketCore>& s);
+
   virtual ~AbstractProxyRequestCommand();
 
   virtual Command* getNextCommand() = 0;

+ 0 - 20
src/AuthConfigFactory.cc

@@ -69,12 +69,6 @@ AuthConfigFactory::createAuthConfig(const RequestHandle& request) const
   }
 }
 
-AuthConfigHandle
-AuthConfigFactory::createAuthConfigForHttpProxy(const RequestHandle& request) const
-{
-  return createHttpProxyAuthResolver()->resolveAuthConfig(request->getHost());
-}
-
 AuthConfigHandle
 AuthConfigFactory::createAuthConfig(const std::string& user, const std::string& password) const
 {
@@ -118,20 +112,6 @@ AuthResolverHandle AuthConfigFactory::createFtpAuthResolver() const
   return resolver;
 }
 
-AuthResolverHandle AuthConfigFactory::createHttpProxyAuthResolver() const
-{
-  AbstractAuthResolverHandle resolver;
-  if(true || _option->getAsBool(PREF_NO_NETRC)) {
-    resolver.reset(new DefaultAuthResolver());
-  } else {
-    NetrcAuthResolverHandle authResolver(new NetrcAuthResolver());
-    authResolver->setNetrc(_netrc);
-    resolver = authResolver;
-  }
-  resolver->setUserDefinedAuthConfig(createAuthConfig(_option->get(PREF_HTTP_PROXY_USER), _option->get(PREF_HTTP_PROXY_PASSWD)));
-  return resolver;
-}
-
 void AuthConfigFactory::setNetrc(const NetrcHandle& netrc)
 {
   _netrc = netrc;

+ 0 - 5
src/AuthConfigFactory.h

@@ -61,8 +61,6 @@ private:
 
   SharedHandle<AuthResolver> createHttpAuthResolver() const;
   
-  SharedHandle<AuthResolver> createHttpProxyAuthResolver() const;
-  
   SharedHandle<AuthResolver> createFtpAuthResolver() const;
 
 public:
@@ -74,9 +72,6 @@ public:
   SharedHandle<AuthConfig> createAuthConfig
   (const SharedHandle<Request>& request) const;
 
-  SharedHandle<AuthConfig> createAuthConfigForHttpProxy
-  (const SharedHandle<Request>& request) const;
-
   void setNetrc(const SharedHandle<Netrc>& netrc);
 
   static const std::string ANONYMOUS;

+ 4 - 3
src/FtpFinishDownloadCommand.cc

@@ -33,6 +33,9 @@
  */
 /* copyright --> */
 #include "FtpFinishDownloadCommand.h"
+
+#include <map>
+
 #include "Request.h"
 #include "DownloadEngine.h"
 #include "prefs.h"
@@ -44,7 +47,6 @@
 #include "SocketCore.h"
 #include "RequestGroup.h"
 #include "Logger.h"
-#include <map>
 
 namespace aria2 {
 
@@ -82,8 +84,7 @@ bool FtpFinishDownloadCommand::execute()
     if(status != 226) {
       throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
     }
-    if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED) &&
-       e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) {
+    if(!isProxyDefined() && e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) {
       std::pair<std::string, uint16_t> peerInfo;
       socket->getPeerInfo(peerInfo);
       std::map<std::string, std::string> options;

+ 19 - 19
src/FtpInitiateConnectionCommand.cc

@@ -33,6 +33,9 @@
  */
 /* copyright --> */
 #include "FtpInitiateConnectionCommand.h"
+
+#include <map>
+
 #include "DownloadEngine.h"
 #include "Option.h"
 #include "Request.h"
@@ -47,7 +50,6 @@
 #include "prefs.h"
 #include "HttpConnection.h"
 #include "Socket.h"
-#include <map>
 
 namespace aria2 {
 
@@ -61,22 +63,28 @@ FtpInitiateConnectionCommand::FtpInitiateConnectionCommand
 FtpInitiateConnectionCommand::~FtpInitiateConnectionCommand() {}
 
 Command* FtpInitiateConnectionCommand::createNextCommand
-(const std::deque<std::string>& resolvedAddresses)
+(const std::deque<std::string>& resolvedAddresses,
+ const SharedHandle<Request>& proxyRequest)
 {
   Command* command;
-  if(useHTTPProxy()) {
+  if(!proxyRequest.isNull()) {
     logger->info(MSG_CONNECTING_TO_SERVER, cuid,
-		 e->option->get(PREF_HTTP_PROXY_HOST).c_str(),
-		 e->option->getAsInt(PREF_HTTP_PROXY_PORT));
+		 proxyRequest->getHost().c_str(), proxyRequest->getPort());
     socket.reset(new SocketCore());
     socket->establishConnection(resolvedAddresses.front(),
-				e->option->getAsInt(PREF_HTTP_PROXY_PORT));
+				proxyRequest->getPort());
     
-    if(useHTTPProxyGet()) {
-      SharedHandle<HttpConnection> hc(new HttpConnection(cuid, socket, e->option));
-      command = new HttpRequestCommand(cuid, req, _requestGroup, hc, e, socket);
-    } else if(useHTTPProxyConnect()) {
-      command = new FtpTunnelRequestCommand(cuid, req, _requestGroup, e, socket);
+    if(e->option->get(PREF_HTTP_PROXY_METHOD) == V_GET) {
+      SharedHandle<HttpConnection> hc
+	(new HttpConnection(cuid, socket, e->option));
+
+      HttpRequestCommand* c =
+	new HttpRequestCommand(cuid, req, _requestGroup, hc, e, socket);
+      c->setProxyRequest(proxyRequest);
+      command = c;
+    } else if(e->option->get(PREF_HTTP_PROXY_METHOD) == V_TUNNEL) {
+      command = new FtpTunnelRequestCommand(cuid, req, _requestGroup, e,
+					    proxyRequest, socket);
     } else {
       // TODO
       throw DlAbortEx("ERROR");
@@ -101,12 +109,4 @@ Command* FtpInitiateConnectionCommand::createNextCommand
   return command;
 }
 
-bool FtpInitiateConnectionCommand::useHTTPProxyGet() const {
-  return useHTTPProxy() && e->option->get(PREF_FTP_VIA_HTTP_PROXY) == V_GET;
-}
-
-bool FtpInitiateConnectionCommand::useHTTPProxyConnect() const {
-  return useHTTPProxy() && e->option->get(PREF_FTP_VIA_HTTP_PROXY) == V_TUNNEL;
-}
-
 } // namespace aria2

+ 2 - 4
src/FtpInitiateConnectionCommand.h

@@ -40,12 +40,10 @@
 namespace aria2 {
 
 class FtpInitiateConnectionCommand : public InitiateConnectionCommand {
-private:
-  bool useHTTPProxyGet() const;
-  bool useHTTPProxyConnect() const;
 protected:
   virtual Command* createNextCommand
-  (const std::deque<std::string>& resolvedAddresses);
+  (const std::deque<std::string>& resolvedAddresses,
+   const SharedHandle<Request>& proxyRequest);
 public:
   FtpInitiateConnectionCommand(int cuid, const SharedHandle<Request>& req,
 			       RequestGroup* requestGroup, DownloadEngine* e);

+ 1 - 2
src/FtpNegotiationCommand.cc

@@ -618,8 +618,7 @@ bool FtpNegotiationCommand::processSequence(const SegmentHandle& segment) {
 
 void FtpNegotiationCommand::poolConnection() const
 {
-  if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED) &&
-     e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) {
+  if(!isProxyDefined() && e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) {
     std::pair<std::string, uint16_t> peerInfo;
     socket->getPeerInfo(peerInfo);
     std::map<std::string, std::string> options;

+ 9 - 6
src/FtpTunnelRequestCommand.cc

@@ -39,12 +39,15 @@
 
 namespace aria2 {
 
-FtpTunnelRequestCommand::FtpTunnelRequestCommand(int cuid,
-						 const RequestHandle& req,
-						 RequestGroup* requestGroup,
-						 DownloadEngine* e,
-						 const SocketHandle& s)
-  :AbstractProxyRequestCommand(cuid, req, requestGroup, e, s) {}
+FtpTunnelRequestCommand::FtpTunnelRequestCommand
+(int cuid,
+ const RequestHandle& req,
+ RequestGroup* requestGroup,
+ DownloadEngine* e,
+ const SharedHandle<Request>& proxyRequest,
+ const SocketHandle& s)
+  :
+  AbstractProxyRequestCommand(cuid, req, requestGroup, e, proxyRequest, s) {}
 
 FtpTunnelRequestCommand::~FtpTunnelRequestCommand() {}
 

+ 1 - 0
src/FtpTunnelRequestCommand.h

@@ -47,6 +47,7 @@ public:
 			  const SharedHandle<Request>& req,
 			  RequestGroup* requestGroup,
 			  DownloadEngine* e,
+			  const SharedHandle<Request>& proxyRequest,
 			  const SharedHandle<SocketCore>& s);
   virtual ~FtpTunnelRequestCommand();
 

+ 1 - 1
src/HttpDownloadCommand.cc

@@ -63,7 +63,7 @@ bool HttpDownloadCommand::prepareForNextSegment() {
     e->commands.push_back(command);
     return true;
   } else {
-    if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED)) {
+    if(!isProxyDefined()) {
       if(req->isPipeliningEnabled() ||
 	 (req->isKeepAliveEnabled() &&
 	  ((!_transferEncodingDecoder.isNull() &&

+ 12 - 8
src/HttpInitiateConnectionCommand.cc

@@ -46,6 +46,7 @@
 #include "Socket.h"
 #include "message.h"
 #include "prefs.h"
+#include "A2STR.h"
 
 namespace aria2 {
 
@@ -59,22 +60,25 @@ HttpInitiateConnectionCommand::HttpInitiateConnectionCommand
 HttpInitiateConnectionCommand::~HttpInitiateConnectionCommand() {}
 
 Command* HttpInitiateConnectionCommand::createNextCommand
-(const std::deque<std::string>& resolvedAddresses)
+(const std::deque<std::string>& resolvedAddresses,
+ const SharedHandle<Request>& proxyRequest)
 {
   Command* command;
-  if(useHTTPProxy()) {
+  if(!proxyRequest.isNull()) {
     logger->info(MSG_CONNECTING_TO_SERVER, cuid,
-		 e->option->get(PREF_HTTP_PROXY_HOST).c_str(),
-		 e->option->getAsInt(PREF_HTTP_PROXY_PORT));
+		 proxyRequest->getHost().c_str(), proxyRequest->getPort());
     socket.reset(new SocketCore());
     socket->establishConnection(resolvedAddresses.front(),
-				e->option->getAsInt(PREF_HTTP_PROXY_PORT));
+				proxyRequest->getPort());
     if(useProxyTunnel()) {
-      command = new HttpProxyRequestCommand(cuid, req, _requestGroup, e, socket);
+      command = new HttpProxyRequestCommand(cuid, req, _requestGroup, e,
+					    proxyRequest, socket);
     } else if(useProxyGet()) {
       SharedHandle<HttpConnection> httpConnection(new HttpConnection(cuid, socket, e->option));
-      command = new HttpRequestCommand(cuid, req, _requestGroup,
-				       httpConnection, e, socket);
+      HttpRequestCommand* c = new HttpRequestCommand(cuid, req, _requestGroup,
+						     httpConnection, e, socket);
+      c->setProxyRequest(proxyRequest);
+      command = c;
     } else {
       // TODO
       throw DlAbortEx("ERROR");

+ 2 - 1
src/HttpInitiateConnectionCommand.h

@@ -45,7 +45,8 @@ private:
   bool useProxyTunnel() const;
 protected:
   virtual Command* createNextCommand
-  (const std::deque<std::string>& resolvedAddresses);
+  (const std::deque<std::string>& resolvedAddresses,
+   const SharedHandle<Request>& proxyRequest);
 public:
   HttpInitiateConnectionCommand(int cuid, const SharedHandle<Request>& req,
 				RequestGroup* requestGroup,

+ 9 - 6
src/HttpProxyRequestCommand.cc

@@ -39,12 +39,15 @@
 
 namespace aria2 {
 
-HttpProxyRequestCommand::HttpProxyRequestCommand(int cuid,
-						 const RequestHandle& req,
-						 RequestGroup* requestGroup,
-						 DownloadEngine* e,
-						 const SocketHandle& s)
-  :AbstractProxyRequestCommand(cuid, req, requestGroup, e, s) {}
+HttpProxyRequestCommand::HttpProxyRequestCommand
+(int cuid,
+ const RequestHandle& req,
+ RequestGroup* requestGroup,
+ DownloadEngine* e,
+ const SharedHandle<Request>& proxyRequest,
+ const SocketHandle& s)
+  :
+  AbstractProxyRequestCommand(cuid, req, requestGroup, e, proxyRequest, s) {}
 
 HttpProxyRequestCommand::~HttpProxyRequestCommand() {}
 

+ 1 - 0
src/HttpProxyRequestCommand.h

@@ -47,6 +47,7 @@ public:
 			  const SharedHandle<Request>& req,
 			  RequestGroup* requestGroup,
 			  DownloadEngine* e,
+			  const SharedHandle<Request>& proxyRequest,
 			  const SharedHandle<SocketCore>& s);
   virtual ~HttpProxyRequestCommand();
 

+ 13 - 16
src/HttpRequest.cc

@@ -55,8 +55,6 @@ namespace aria2 {
 const std::string HttpRequest::USER_AGENT("aria2");
 
 HttpRequest::HttpRequest():entityLength(0),
-			   proxyEnabled(false),
-			   proxyAuthEnabled(false),
 			   _contentEncodingEnabled(true),
 			   userAgent(USER_AGENT)
 {}
@@ -139,7 +137,7 @@ std::string HttpRequest::createRequest() const
   SharedHandle<AuthConfig> authConfig =
     _authConfigFactory->createAuthConfig(request);
   std::string requestLine = "GET ";
-  if(getProtocol() == Request::PROTO_FTP || proxyEnabled) {
+  if(!_proxyRequest.isNull()) {
     if(getProtocol() == Request::PROTO_FTP &&
        request->getUsername().empty() && !authConfig->getUser().empty()) {
       // Insert user into URI, like ftp://USER@host/
@@ -196,14 +194,14 @@ std::string HttpRequest::createRequest() const
     }
     requestLine += "\r\n";
   }
-  if(proxyEnabled) {
+  if(!_proxyRequest.isNull()) {
     if(request->isKeepAliveEnabled() || request->isPipeliningEnabled()) {
       requestLine += "Proxy-Connection: Keep-Alive\r\n";
     } else {
       requestLine += "Proxy-Connection: close\r\n";
     }
   }
-  if(proxyEnabled && proxyAuthEnabled) {
+  if(!_proxyRequest.isNull() && !_proxyRequest->getUsername().empty()) {
     requestLine += getProxyAuthString();
   }
   if(!authConfig->getUser().empty()) {
@@ -241,6 +239,7 @@ std::string HttpRequest::createRequest() const
 
 std::string HttpRequest::createProxyRequest() const
 {
+  assert(!_proxyRequest.isNull());
   std::string requestLine =
     std::string("CONNECT ")+getHost()+":"+Util::uitos(getPort())+
     std::string(" HTTP/1.1\r\n")+
@@ -251,7 +250,7 @@ std::string HttpRequest::createProxyRequest() const
   }else {
     requestLine += "Proxy-Connection: close\r\n";
   }
-  if(proxyAuthEnabled) {
+  if(!_proxyRequest->getUsername().empty()) {
     requestLine += getProxyAuthString();
   }
   requestLine += "\r\n";
@@ -261,8 +260,9 @@ std::string HttpRequest::createProxyRequest() const
 std::string HttpRequest::getProxyAuthString() const
 {
   return "Proxy-Authorization: Basic "+
-    Base64::encode(_authConfigFactory->createAuthConfigForHttpProxy(request)->
-		   getAuthText())+"\r\n";
+    Base64::encode(_proxyRequest->getUsername()+":"+
+		   _proxyRequest->getPassword())
+    +"\r\n";
 }
 
 void HttpRequest::enableContentEncoding()
@@ -287,14 +287,6 @@ void HttpRequest::addAcceptType(const std::string& type)
   _acceptTypes.push_back(type);
 }
 
-void HttpRequest::configure(const Option* option)
-{
-  proxyEnabled =
-    option->getAsBool(PREF_HTTP_PROXY_ENABLED) &&
-    option->get(PREF_HTTP_PROXY_METHOD) == V_GET;
-  proxyAuthEnabled = option->getAsBool(PREF_HTTP_PROXY_AUTH_ENABLED);
-}
-
 const std::string& HttpRequest::getPreviousURI() const
 {
   return request->getPreviousUrl();
@@ -357,4 +349,9 @@ void HttpRequest::setAuthConfigFactory
   _authConfigFactory = factory;
 }
 
+void HttpRequest::setProxyRequest(const SharedHandle<Request>& proxyRequest)
+{
+  _proxyRequest = proxyRequest;
+}
+
 } // namespace aria2

+ 8 - 23
src/HttpRequest.h

@@ -62,10 +62,6 @@ private:
 
   uint64_t entityLength;
 
-  bool proxyEnabled;
-
-  bool proxyAuthEnabled;
-
   bool _contentEncodingEnabled;
 
   std::string userAgent;
@@ -78,6 +74,8 @@ private:
 
   SharedHandle<AuthConfigFactory> _authConfigFactory;
 
+  SharedHandle<Request> _proxyRequest;
+
   std::string getHostText(const std::string& host, uint16_t port) const;
 
   std::string getProxyAuthString() const;
@@ -147,25 +145,6 @@ public:
    */
   std::string createProxyRequest() const;
 
-  /**
-   * Configures this object with option.
-   * Following values are evaluated:
-   * PREF_HTTP_PROXY_ENABLED,
-   * PREF_HTTP_PROXY_METHOD, PREF_HTTP_PROXY_AUTH_ENABLED,
-   * The evaluation results are stored in instance variables.
-   */
-  void configure(const Option* option);
-
-  void setProxyEnabled(bool proxyEnabled)
-  {
-    this->proxyEnabled = proxyEnabled;
-  }
-
-  void setProxyAuthEnabled(bool proxyAuthEnabled)
-  {
-    this->proxyAuthEnabled = proxyAuthEnabled;
-  }
-
   void enableContentEncoding();
 
   void disableContentEncoding();
@@ -191,6 +170,12 @@ public:
   SharedHandle<CookieStorage> getCookieStorage() const;
 
   void setAuthConfigFactory(const SharedHandle<AuthConfigFactory>& factory);
+
+  /*
+   * To use proxy, pass proxy string to Request::setUrl() and set it this
+   * object.
+   */
+  void setProxyRequest(const SharedHandle<Request>& proxyRequest);
 };
 
 typedef SharedHandle<HttpRequest> HttpRequestHandle;

+ 13 - 4
src/HttpRequestCommand.cc

@@ -79,7 +79,8 @@ createHttpRequest(const SharedHandle<Request>& req,
 		  const Option* option,
 		  const RequestGroup* rg,
 		  const SharedHandle<CookieStorage>& cookieStorage,
-		  const SharedHandle<AuthConfigFactory>& authConfigFactory)
+		  const SharedHandle<AuthConfigFactory>& authConfigFactory,
+		  const SharedHandle<Request>& proxyRequest)
 {
   HttpRequestHandle httpRequest(new HttpRequest());
   httpRequest->setUserAgent(option->get(PREF_USER_AGENT));
@@ -89,6 +90,7 @@ createHttpRequest(const SharedHandle<Request>& req,
   httpRequest->addHeader(option->get(PREF_HEADER));
   httpRequest->setCookieStorage(cookieStorage);
   httpRequest->setAuthConfigFactory(authConfigFactory);
+  httpRequest->setProxyRequest(proxyRequest);
   if(!rg->getAcceptFeatures().empty()) {
     const std::deque<std::string>& acceptFeatures = rg->getAcceptFeatures();
     std::string acceptFeaturesHeader = "Accept-Features: ";
@@ -98,7 +100,6 @@ createHttpRequest(const SharedHandle<Request>& req,
   }
   httpRequest->addAcceptType(rg->getAcceptTypes().begin(),
 			     rg->getAcceptTypes().end());
-  httpRequest->configure(option);
 
   return httpRequest;
 }
@@ -123,7 +124,8 @@ bool HttpRequestCommand::executeInternal() {
 			   _requestGroup->getTotalLength(), e->option,
 			   _requestGroup,
 			   e->getCookieStorage(),
-			   e->getAuthConfigFactory()));
+			   e->getAuthConfigFactory(),
+			   _proxyRequest));
       _httpConnection->sendRequest(httpRequest);
     } else {
       for(Segments::iterator itr = _segments.begin(); itr != _segments.end(); ++itr) {
@@ -134,7 +136,8 @@ bool HttpRequestCommand::executeInternal() {
 			       _requestGroup->getTotalLength(), e->option,
 			       _requestGroup,
 			       e->getCookieStorage(),
-			       e->getAuthConfigFactory()));
+			       e->getAuthConfigFactory(),
+			       _proxyRequest));
 	  _httpConnection->sendRequest(httpRequest);
 	}
       }
@@ -155,4 +158,10 @@ bool HttpRequestCommand::executeInternal() {
   }
 }
 
+void HttpRequestCommand::setProxyRequest
+(const SharedHandle<Request>& proxyRequest)
+{
+  _proxyRequest = proxyRequest;
+}
+
 } // namespace aria2

+ 4 - 0
src/HttpRequestCommand.h

@@ -44,6 +44,8 @@ class SocketCore;
 
 class HttpRequestCommand:public AbstractCommand {
 private:
+  SharedHandle<Request> _proxyRequest;
+
   SharedHandle<HttpConnection> _httpConnection;
 protected:
   virtual bool executeInternal();
@@ -55,6 +57,8 @@ public:
 		     DownloadEngine* e,
 		     const SharedHandle<SocketCore>& s);
   virtual ~HttpRequestCommand();
+
+  void setProxyRequest(const SharedHandle<Request>& proxyRequest);
 };
 
 } // namespace aria2

+ 1 - 2
src/HttpSkipResponseCommand.cc

@@ -137,8 +137,7 @@ bool HttpSkipResponseCommand::executeInternal()
 
 void HttpSkipResponseCommand::poolConnection() const
 {
-  if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED) &&
-     req->supportsPersistentConnection()) {
+  if(!isProxyDefined() && req->supportsPersistentConnection()) {
     std::pair<std::string, uint16_t> peerInfo;
     socket->getPeerInfo(peerInfo);
     e->poolSocket(peerInfo.first, peerInfo.second, socket);

+ 5 - 9
src/InitiateConnectionCommand.cc

@@ -62,10 +62,11 @@ InitiateConnectionCommand::~InitiateConnectionCommand() {}
 
 bool InitiateConnectionCommand::executeInternal() {
   std::string hostname;
-  if(useHTTPProxy()) {
-    hostname = e->option->get(PREF_HTTP_PROXY_HOST);
-  } else {
+  SharedHandle<Request> proxyRequest = createProxyRequest();
+  if(proxyRequest.isNull()) {
     hostname = req->getHost();
+  } else {
+    hostname = proxyRequest->getHost();
   }
   std::deque<std::string> addrs;
   std::string ipaddr = e->findCachedIPAddress(hostname);
@@ -97,14 +98,9 @@ bool InitiateConnectionCommand::executeInternal() {
     addrs.push_back(ipaddr);
   }
 
-  Command* command = createNextCommand(addrs);
+  Command* command = createNextCommand(addrs, proxyRequest);
   e->commands.push_back(command);
   return true;
 }
 
-bool InitiateConnectionCommand::useHTTPProxy() const
-{
-  return e->option->getAsBool(PREF_HTTP_PROXY_ENABLED);
-}
-
 } // namespace aria2

+ 2 - 3
src/InitiateConnectionCommand.h

@@ -41,8 +41,6 @@ namespace aria2 {
 
 class InitiateConnectionCommand : public AbstractCommand {
 protected:
-  bool useHTTPProxy() const;
-
   /**
    * Connect to the server.
    * This method just send connection request to the server.
@@ -52,7 +50,8 @@ protected:
   virtual bool executeInternal();
 
   virtual Command* createNextCommand
-  (const std::deque<std::string>& resolvedAddresses) = 0;
+  (const std::deque<std::string>& resolvedAddresses,
+   const SharedHandle<Request>& proxyRequest) = 0;
 public:
   InitiateConnectionCommand(int cuid, const SharedHandle<Request>& req,
 			    RequestGroup* requestGroup,

+ 34 - 33
src/OptionHandlerFactory.cc

@@ -471,30 +471,6 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_HTTP);
     handlers.push_back(op);
   }
-  {
-    SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
-				   (PREF_HTTP_PROXY,
-				    TEXT_HTTP_PROXY,
-				    NO_DEFAULT_VALUE,
-				    PREF_HTTP_PROXY_HOST,
-				    PREF_HTTP_PROXY_PORT));
-    op->addTag(TAG_HTTP);
-    handlers.push_back(op);
-  }
-  {
-    SharedHandle<OptionHandler> op(new DefaultOptionHandler
-				   (PREF_HTTP_PROXY_USER,
-				    TEXT_HTTP_PROXY_USER));
-    op->addTag(TAG_HTTP);
-    handlers.push_back(op);
-  }
-  {
-    SharedHandle<OptionHandler> op(new DefaultOptionHandler
-				   (PREF_HTTP_PROXY_PASSWD,
-				    TEXT_HTTP_PROXY_PASSWD));
-    op->addTag(TAG_HTTP);
-    handlers.push_back(op);
-  }
   {
     SharedHandle<OptionHandler> op(new ParameterOptionHandler
 				   (PREF_HTTP_PROXY_METHOD,
@@ -588,15 +564,6 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_FTP);
     handlers.push_back(op);
   }
-  {
-    SharedHandle<OptionHandler> op(new ParameterOptionHandler
-				   (PREF_FTP_VIA_HTTP_PROXY,
-				    TEXT_FTP_VIA_HTTP_PROXY,
-				    V_TUNNEL,
-				    V_GET, V_TUNNEL));
-    op->addTag(TAG_FTP);
-    handlers.push_back(op);
-  }
   {
     SharedHandle<OptionHandler> op(new DefaultOptionHandler
 				   (PREF_NETRC_PATH,
@@ -615,6 +582,40 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_HTTP);
     handlers.push_back(op);
   }
+  // Proxy options
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
+				   (PREF_HTTP_PROXY,
+				    TEXT_HTTP_PROXY,
+				    NO_DEFAULT_VALUE));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
+				   (PREF_HTTPS_PROXY,
+				    TEXT_HTTPS_PROXY,
+				    NO_DEFAULT_VALUE));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
+				   (PREF_FTP_PROXY,
+				    TEXT_FTP_PROXY,
+				    NO_DEFAULT_VALUE));
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
+				   (PREF_ALL_PROXY,
+				    TEXT_ALL_PROXY,
+				    NO_DEFAULT_VALUE));
+    op->addTag(TAG_HTTP);
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
   // BitTorrent/Metalink Options
   {
     SharedHandle<OptionHandler> op(new IntegerRangeOptionHandler

+ 30 - 14
src/OptionHandlerImpl.h

@@ -36,6 +36,14 @@
 #define _D_OPTION_HANDLER_IMPL_H_
 
 #include "OptionHandler.h"
+
+#include <cstdio>
+#include <utility>
+#include <algorithm>
+#include <numeric>
+#include <sstream>
+#include <iterator>
+
 #include "NameMatchOptionHandler.h"
 #include "Util.h"
 #include "FatalException.h"
@@ -43,12 +51,7 @@
 #include "Option.h"
 #include "StringFormat.h"
 #include "A2STR.h"
-#include <cstdio>
-#include <utility>
-#include <algorithm>
-#include <numeric>
-#include <sstream>
-#include <iterator>
+#include "Request.h"
 
 namespace aria2 {
 
@@ -439,23 +442,36 @@ public:
   }
 };
 
-class HttpProxyOptionHandler : public HostPortOptionHandler {
+class HttpProxyOptionHandler : public NameMatchOptionHandler {
 public:
   HttpProxyOptionHandler(const std::string& optName,
 			 const std::string& description,
-			 const std::string& defaultValue,
-			 const std::string& hostOptionName,
-			 const std::string& portOptionName):
-    HostPortOptionHandler(optName, description, defaultValue,
-			  hostOptionName, portOptionName)
+			 const std::string& defaultValue)
+    :
+    NameMatchOptionHandler(optName, description, defaultValue)
   {}
 
   virtual ~HttpProxyOptionHandler() {}
 
   virtual void parseArg(Option* option, const std::string& optarg)
   {
-    HostPortOptionHandler::parseArg(option, optarg);
-    option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
+    Request req;
+    std::string url;
+    if(Util::startsWith(optarg, "http://")) {
+      url = optarg;
+    } else {
+      url = "http://"+optarg;
+    }
+    if(req.setUrl(url)) {
+      option->put(_optName, url);
+    } else {
+      throw FatalException(_("unrecognized proxy format"));
+    }
+  }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return "[http://][USER:PASSWORD@]HOST[:PORT]";
   }
 };
 

+ 5 - 1
src/Request.cc

@@ -197,7 +197,11 @@ bool Request::parseUrl(const std::string& url) {
   host = hostAndPort.first;
   if(hostAndPort.second != A2STR::NIL) {
     try {
-      port = Util::parseInt(hostAndPort.second);
+      unsigned int tempPort = Util::parseUInt(hostAndPort.second);
+      if(65535 < tempPort) {
+	return false;
+      }
+      port = tempPort;
     } catch(RecoverableException& e) {
       return false;
     }

+ 27 - 12
src/option_processing.cc

@@ -107,8 +107,8 @@ Option* option_processing(int argc, char* const argv[])
       { PREF_HTTP_PROXY.c_str(), required_argument, &lopt, 1 },
       { PREF_HTTP_USER.c_str(), required_argument, &lopt, 2 },
       { PREF_HTTP_PASSWD.c_str(), required_argument, &lopt, 3 },
-      { PREF_HTTP_PROXY_USER.c_str(), required_argument, &lopt, 4 },
-      { PREF_HTTP_PROXY_PASSWD.c_str(), required_argument, &lopt, 5 },
+      { "http-proxy-user", required_argument, &lopt, 4 },
+      { "http-proxy-passwd", required_argument, &lopt, 5 },
       { PREF_HTTP_AUTH_SCHEME.c_str(), required_argument, &lopt, 6 },
       { PREF_REFERER.c_str(), required_argument, &lopt, 7 },
       { PREF_RETRY_WAIT.c_str(), required_argument, &lopt, 8 },
@@ -116,7 +116,7 @@ Option* option_processing(int argc, char* const argv[])
       { PREF_FTP_PASSWD.c_str(), required_argument, &lopt, 10 },
       { PREF_FTP_TYPE.c_str(), required_argument, &lopt, 11 },
       { PREF_FTP_PASV.c_str(), no_argument, NULL, 'p' },
-      { PREF_FTP_VIA_HTTP_PROXY.c_str(), required_argument, &lopt, 12 },
+      { "ftp-via-http-proxy", required_argument, &lopt, 12 },
       { PREF_HTTP_PROXY_METHOD.c_str(), required_argument, &lopt, 14 },
       { PREF_LOWEST_SPEED_LIMIT.c_str(), required_argument, &lopt, 200 },
       { PREF_MAX_DOWNLOAD_LIMIT.c_str(), required_argument, &lopt, 201 },
@@ -161,6 +161,9 @@ Option* option_processing(int argc, char* const argv[])
       { PREF_CONNECT_TIMEOUT.c_str(), required_argument, &lopt, 224 },
       { PREF_MAX_FILE_NOT_FOUND.c_str(), required_argument, &lopt, 225 },
       { PREF_AUTO_SAVE_INTERVAL.c_str(), required_argument, &lopt, 226 },
+      { PREF_HTTPS_PROXY.c_str(), required_argument, &lopt, 227 },
+      { PREF_FTP_PROXY.c_str(), required_argument, &lopt, 228 },
+      { PREF_ALL_PROXY.c_str(), required_argument, &lopt, 229 },
 #if defined ENABLE_BITTORRENT || defined ENABLE_METALINK
       { PREF_SHOW_FILES.c_str(), no_argument, NULL, 'S' },
       { PREF_SELECT_FILE.c_str(), required_argument, &lopt, 21 },
@@ -221,11 +224,15 @@ Option* option_processing(int argc, char* const argv[])
 	cmdstream << PREF_HTTP_PASSWD << "=" << optarg << "\n";
 	break;
       case 4:
-	cmdstream << PREF_HTTP_PROXY_USER << "=" << optarg << "\n";
-	break;
+	std::cout << "--http-proxy-user was deprecated. See --http-proxy,"
+		  << " --https-proxy, --ftp-proxy, --all-proxy options."
+		  << std::endl;
+	exit(EXIT_FAILURE);
       case 5: 
-	cmdstream << PREF_HTTP_PROXY_PASSWD << "=" << optarg << "\n";
-	break;
+	std::cout << "--http-proxy-passwd was deprecated. See --http-proxy,"
+		  << " --https-proxy, --ftp-proxy, --all-proxy options."
+		  << std::endl;
+	exit(EXIT_FAILURE);
       case 6:
 	cmdstream << PREF_HTTP_AUTH_SCHEME << "=" << optarg << "\n";
 	break;
@@ -245,8 +252,10 @@ Option* option_processing(int argc, char* const argv[])
 	cmdstream << PREF_FTP_TYPE << "=" << optarg << "\n";
 	break;
       case 12:
-	cmdstream << PREF_FTP_VIA_HTTP_PROXY << "=" << optarg << "\n";
-	break;
+	std::cout << "--ftp-via-http-proxy was deprecated."
+		  << " Use --http-proxy-method option instead."
+		  << std::endl;
+	exit(EXIT_FAILURE);
       case 14:
 	cmdstream << PREF_HTTP_PROXY_METHOD << "=" << optarg << "\n";
 	break;
@@ -409,6 +418,15 @@ Option* option_processing(int argc, char* const argv[])
       case 226:
 	cmdstream << PREF_AUTO_SAVE_INTERVAL << "=" << optarg << "\n";
 	break;
+      case 227:
+	cmdstream << PREF_HTTPS_PROXY << "=" << optarg << "\n";
+	break;
+      case 228:
+	cmdstream << PREF_FTP_PROXY << "=" << optarg << "\n";
+	break;
+      case 229:
+	cmdstream << PREF_ALL_PROXY << "=" << optarg << "\n";
+	break;
       }
       break;
     }
@@ -545,9 +563,6 @@ Option* option_processing(int argc, char* const argv[])
       exit(EXIT_FAILURE);
     }
   }
-  if(op->defined(PREF_HTTP_PROXY_USER)) {
-    op->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
-  }
   if(
 #ifdef ENABLE_BITTORRENT
      !op->defined(PREF_TORRENT_FILE) &&

+ 6 - 13
src/prefs.cc

@@ -155,10 +155,6 @@ const std::string PREF_FTP_PASSWD("ftp-passwd");
 const std::string PREF_FTP_TYPE("ftp-type");
 const std::string V_BINARY("binary");
 const std::string V_ASCII("ascii");
-// values: get | tunnel
-const std::string PREF_FTP_VIA_HTTP_PROXY("ftp-via-http-proxy");
-const std::string V_GET("get");
-const std::string V_TUNNEL("tunnel");
 // values: true | false
 const std::string PREF_FTP_PASV("ftp-pasv");
 // values: true | false
@@ -186,19 +182,16 @@ const std::string PREF_MAX_HTTP_PIPELINING("max-http-pipelining");
 const std::string PREF_HEADER("header");
 
 /** 
- * HTTP proxy related preferences
+ * Proxy related preferences
  */
 const std::string PREF_HTTP_PROXY("http-proxy");
-const std::string PREF_HTTP_PROXY_USER("http-proxy-user");
-const std::string PREF_HTTP_PROXY_PASSWD("http-proxy-passwd");
-const std::string PREF_HTTP_PROXY_HOST("http-proxy-host");
-const std::string PREF_HTTP_PROXY_PORT("http-proxy-port");
+const std::string PREF_HTTPS_PROXY("https-proxy");
+const std::string PREF_FTP_PROXY("ftp-proxy");
+const std::string PREF_ALL_PROXY("all-proxy");
 // values: get | tunnel
 const std::string PREF_HTTP_PROXY_METHOD("http-proxy-method");
-// values: true | false
-const std::string PREF_HTTP_PROXY_ENABLED("http-proxy-enabled");
-// values: true | false
-const std::string PREF_HTTP_PROXY_AUTH_ENABLED("http-proxy-auth-enabled");
+const std::string V_GET("get");
+const std::string V_TUNNEL("tunnel");
 
 /**
  * BitTorrent related preferences

+ 6 - 13
src/prefs.h

@@ -159,10 +159,6 @@ extern const std::string PREF_FTP_PASSWD;
 extern const std::string PREF_FTP_TYPE;
 extern const std::string V_BINARY;
 extern const std::string V_ASCII;
-// values: get | tunnel
-extern const std::string PREF_FTP_VIA_HTTP_PROXY;
-extern const std::string V_GET;
-extern const std::string V_TUNNEL;
 // values: true | false
 extern const std::string PREF_FTP_PASV;
 // values: true | false
@@ -190,19 +186,16 @@ extern const std::string PREF_MAX_HTTP_PIPELINING;
 extern const std::string PREF_HEADER;
 
 /**;
- * HTTP proxy related preferences
+ * Proxy related preferences
  */
 extern const std::string PREF_HTTP_PROXY;
-extern const std::string PREF_HTTP_PROXY_USER;
-extern const std::string PREF_HTTP_PROXY_PASSWD;
-extern const std::string PREF_HTTP_PROXY_HOST;
-extern const std::string PREF_HTTP_PROXY_PORT;
+extern const std::string PREF_HTTPS_PROXY;
+extern const std::string PREF_FTP_PROXY;
+extern const std::string PREF_ALL_PROXY;
 // values: get | tunnel
 extern const std::string PREF_HTTP_PROXY_METHOD;
-// values: true | false
-extern const std::string PREF_HTTP_PROXY_ENABLED;
-// values: true | false
-extern const std::string PREF_HTTP_PROXY_AUTH_ENABLED;
+extern const std::string V_GET;
+extern const std::string V_TUNNEL;
 
 /**
  * BitTorrent related preferences

+ 18 - 7
src/usage_text.h

@@ -57,15 +57,28 @@ _(" -t, --timeout=SEC            Set timeout in seconds.")
 #define TEXT_MAX_TRIES \
 _(" -m, --max-tries=N            Set number of tries. 0 means unlimited.")
 #define TEXT_HTTP_PROXY \
-_(" --http-proxy=HOST:PORT       Use HTTP proxy server. This affects all URLs.")
+_(" --http-proxy=PROXY           Use this proxy server for HTTP.\n"\
+  "                              See also  --all-proxy option.\n"\
+  "                              This affects all URLs.")
+#define TEXT_HTTPS_PROXY \
+_(" --https-proxy=PROXY          Use this proxy server for HTTPS.\n"\
+  "                              See also  --all-proxy option.\n"\
+  "                              This affects all URLs.")
+#define TEXT_FTP_PROXY \
+_(" --ftp-proxy=PROXY            Use this proxy server for FTP.\n"\
+  "                              See also  --all-proxy option.\n"\
+  "                              This affects all URLs.")
+#define TEXT_ALL_PROXY \
+_(" --all-proxy=PROXY            Use this proxy server in the all protocols.\n"\
+  "                              You can override this setting and specify a\n"\
+  "                              proxy server for particular proctol using\n"\
+  "                              --http-proxy, --https-proxy and --ftp-proxy\n"\
+  "                              options.\n"\
+  "                              This affects all URLs.")
 #define TEXT_HTTP_USER \
 _(" --http-user=USER             Set HTTP user. This affects all URLs.")
 #define TEXT_HTTP_PASSWD \
 _(" --http-passwd=PASSWD         Set HTTP password. This affects all URLs.")
-#define TEXT_HTTP_PROXY_USER \
-_(" --http-proxy-user=USER       Set HTTP proxy user. This affects all URLs.")
-#define TEXT_HTTP_PROXY_PASSWD \
-_(" --http-proxy-passwd=PASSWD   Set HTTP proxy password. This affects all URLs.")
 #define TEXT_HTTP_PROXY_METHOD \
 _(" --http-proxy-method=METHOD   Set the method to use in proxy request.")
 #define TEXT_HTTP_AUTH_SCHEME \
@@ -81,8 +94,6 @@ _(" --ftp-passwd=PASSWD          Set FTP password. This affects all URLs.")
 _(" --ftp-type=TYPE              Set FTP transfer type.")
 #define TEXT_FTP_PASV \
 _(" -p, --ftp-pasv               Use passive mode in FTP.")
-#define TEXT_FTP_VIA_HTTP_PROXY \
-_(" --ftp-via-http-proxy=METHOD  Use HTTP proxy in FTP.")
 #define TEXT_LOWEST_SPEED_LIMIT \
 _(" --lowest-speed-limit=SPEED   Close connection if download speed is lower than\n"\
   "                              or equal to this value(bytes per sec).\n"\

+ 3 - 29
test/AuthConfigFactoryTest.cc

@@ -1,10 +1,12 @@
 #include "AuthConfigFactory.h"
+
+#include <cppunit/extensions/HelperMacros.h>
+
 #include "Netrc.h"
 #include "prefs.h"
 #include "Request.h"
 #include "AuthConfig.h"
 #include "Option.h"
-#include <cppunit/extensions/HelperMacros.h>
 
 namespace aria2 {
 
@@ -12,13 +14,11 @@ class AuthConfigFactoryTest:public CppUnit::TestFixture {
 
   CPPUNIT_TEST_SUITE(AuthConfigFactoryTest);
   CPPUNIT_TEST(testCreateAuthConfig_http);
-  CPPUNIT_TEST(testCreateAuthConfigForHttpProxy);
   CPPUNIT_TEST(testCreateAuthConfig_ftp);
   CPPUNIT_TEST_SUITE_END();
   
 public:
   void testCreateAuthConfig_http();
-  void testCreateAuthConfigForHttpProxy();
   void testCreateAuthConfig_ftp();
 };
 
@@ -71,32 +71,6 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http()
 		       factory.createAuthConfig(req)->getAuthText());  
 }
 
-void AuthConfigFactoryTest::testCreateAuthConfigForHttpProxy()
-{
-  SharedHandle<Request> req(new Request());
-  req->setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
-  // with Netrc
-  SharedHandle<Netrc> netrc(new Netrc());
-  netrc->addAuthenticator
-    (SharedHandle<Authenticator>(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount")));
-
-  Option option;
-  option.put(PREF_NO_NETRC, V_FALSE);
-
-  AuthConfigFactory factory(&option);
-  factory.setNetrc(netrc);
-
-  // netrc is not used in http proxy auth
-  CPPUNIT_ASSERT_EQUAL(std::string(":"),
-		       factory.createAuthConfigForHttpProxy(req)->getAuthText());
-
-  option.put(PREF_HTTP_PROXY_USER, "userDefinedUser");
-  option.put(PREF_HTTP_PROXY_PASSWD, "userDefinedPassword");
-  CPPUNIT_ASSERT_EQUAL(std::string("userDefinedUser:userDefinedPassword"),
-		       factory.createAuthConfigForHttpProxy(req)->getAuthText());
-
-}
-
 void AuthConfigFactoryTest::testCreateAuthConfig_ftp()
 {
   SharedHandle<Request> req(new Request());

+ 40 - 63
test/HttpRequestTest.cc

@@ -106,12 +106,6 @@ void HttpRequestTest::testCreateRequest()
 {
   SharedHandle<Piece> p;
 
-  _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);
 
@@ -225,8 +219,6 @@ void HttpRequestTest::testCreateRequest()
   _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"
     "Accept: */*\r\n"
@@ -240,41 +232,10 @@ void HttpRequestTest::testCreateRequest()
   CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
 
   // enable http proxy auth
-  _option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE);
-
-  httpRequest.configure(_option.get());
-
-  expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
-    "User-Agent: aria2\r\n"
-    "Accept: */*\r\n"
-    "Host: localhost:8080\r\n"
-    "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());
-
-  _option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE);
-
-  httpRequest.configure(_option.get());
-
-  expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
-    "User-Agent: aria2\r\n"
-    "Accept: */*\r\n"
-    "Host: localhost:8080\r\n"
-    "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());
-
-  _option->put(PREF_HTTP_PROXY_METHOD, V_GET);
-
-  httpRequest.configure(_option.get());
+  SharedHandle<Request> proxyRequest(new Request());
+  CPPUNIT_ASSERT(proxyRequest->setUrl
+		 ("http://aria2proxyuser:aria2proxypasswd@localhost:9000"));
+  httpRequest.setProxyRequest(proxyRequest);
 
   expectedText = "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
     "User-Agent: aria2\r\n"
@@ -308,9 +269,8 @@ void HttpRequestTest::testCreateRequest()
 
   request->setPipeliningHint(false);
 
-  _option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE);
-
-  httpRequest.configure(_option.get());
+  // turn off proxy auth
+  CPPUNIT_ASSERT(proxyRequest->setUrl("http://localhost:9000"));
 
   expectedText = "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
     "User-Agent: aria2\r\n"
@@ -328,17 +288,16 @@ void HttpRequestTest::testCreateRequest()
 
 void HttpRequestTest::testCreateRequest_ftp()
 {
-  _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");
+   _option->put(PREF_FTP_USER, "aria2user");
+   _option->put(PREF_FTP_PASSWD, "aria2passwd");
 
   SharedHandle<Request> request(new Request());
   request->setUrl("ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2");
 
+  SharedHandle<Request> proxyRequest(new Request());
+  CPPUNIT_ASSERT(proxyRequest->setUrl
+		 ("http://localhost:9000"));
+
   HttpRequest httpRequest;
   SharedHandle<Piece> p(new Piece(0, 1024*1024));
   SharedHandle<Segment> segment
@@ -347,8 +306,7 @@ void HttpRequestTest::testCreateRequest_ftp()
   httpRequest.setRequest(request);
   httpRequest.setSegment(segment);
   httpRequest.setAuthConfigFactory(_authConfigFactory);
-
-  httpRequest.configure(_option.get());
+  httpRequest.setProxyRequest(proxyRequest);
 
   std::string expectedText =
     "GET ftp://aria2user@localhost:8080/archives/aria2-1.0.0.tar.bz2"
@@ -359,17 +317,15 @@ void HttpRequestTest::testCreateRequest_ftp()
     "Pragma: no-cache\r\n"
     "Cache-Control: no-cache\r\n"
     "Connection: close\r\n"
+    "Proxy-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);
-
-  httpRequest.configure(_option.get());
+  // test proxy authorization
+  CPPUNIT_ASSERT(proxyRequest->setUrl
+		 ("http://aria2proxyuser:aria2proxypasswd@localhost:9000"));
 
   expectedText =
     "GET ftp://aria2user@localhost:8080/archives/aria2-1.0.0.tar.bz2"
@@ -386,7 +342,6 @@ void HttpRequestTest::testCreateRequest_ftp()
     "\r\n";
 
   CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
-  
 }
 
 void HttpRequestTest::testCreateRequest_with_cookie()
@@ -502,10 +457,14 @@ void HttpRequestTest::testCreateProxyRequest()
   SharedHandle<Piece> p(new Piece(0, 1024*1024));
   SharedHandle<Segment> segment(new PiecedSegment(1024*1024, p));
 
+  SharedHandle<Request> proxyRequest(new Request());
+  CPPUNIT_ASSERT(proxyRequest->setUrl("http://localhost:9000"));
+
   HttpRequest httpRequest;
 
   httpRequest.setRequest(request);
   httpRequest.setSegment(segment);
+  httpRequest.setProxyRequest(proxyRequest);
 
   request->supportsPersistentConnection(true);
 
@@ -538,7 +497,20 @@ void HttpRequestTest::testCreateProxyRequest()
     "Proxy-Connection: Keep-Alive\r\n"
     "\r\n";
 
-  CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());  
+  CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
+
+  // test proxy authorization
+  CPPUNIT_ASSERT(proxyRequest->setUrl
+		 ("http://aria2proxyuser:aria2proxypasswd@localhost:9000"));
+
+  expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
+    "User-Agent: aria2\r\n"
+    "Host: localhost:80\r\n"
+    "Proxy-Connection: Keep-Alive\r\n"
+    "Proxy-Authorization: Basic YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n"
+    "\r\n";
+
+  CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
 }
 
 void HttpRequestTest::testIsRangeSatisfied()
@@ -621,6 +593,11 @@ void HttpRequestTest::testUserAgent()
 
   CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
 
+  SharedHandle<Request> proxyRequest(new Request());
+  CPPUNIT_ASSERT(proxyRequest->setUrl("http://localhost:9000"));
+  
+  httpRequest.setProxyRequest(proxyRequest);
+
   std::string expectedTextForProxy = "CONNECT localhost:8080 HTTP/1.1\r\n"
     "User-Agent: aria2 (Linux)\r\n"
     "Host: localhost:8080\r\n"

+ 14 - 36
test/OptionHandlerTest.cc

@@ -328,51 +328,29 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
 
 void OptionHandlerTest::testHttpProxyOptionHandler()
 {
-  HttpProxyOptionHandler handler(PREF_HTTP_PROXY,
-				 "",
-				 "",
-				 PREF_HTTP_PROXY_HOST,
-				 PREF_HTTP_PROXY_PORT);
+  HttpProxyOptionHandler handler(PREF_HTTP_PROXY, "", "");
   CPPUNIT_ASSERT(handler.canHandle(PREF_HTTP_PROXY));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
-  handler.parse(&option, "bar:80");
-  CPPUNIT_ASSERT_EQUAL(std::string("bar:80"), option.get(PREF_HTTP_PROXY));
-  CPPUNIT_ASSERT_EQUAL(std::string("bar"), option.get(PREF_HTTP_PROXY_HOST));
-  CPPUNIT_ASSERT_EQUAL(std::string("80"), option.get(PREF_HTTP_PROXY_PORT));
-  CPPUNIT_ASSERT_EQUAL(std::string(V_TRUE), option.get(PREF_HTTP_PROXY_ENABLED));
+  handler.parse(&option, "proxy:65535");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:65535"),
+		       option.get(PREF_HTTP_PROXY));
+
+  handler.parse(&option, "http://proxy:8080");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:8080"),
+		       option.get(PREF_HTTP_PROXY));
+
+  handler.parse(&option, "ftp://proxy:8080");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://ftp://proxy:8080"),
+		       option.get(PREF_HTTP_PROXY));
 
   try {
-    handler.parse(&option, "bar");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  }
-  try {
-    handler.parse(&option, "bar:");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  }
-  try {
-    handler.parse(&option, ":");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  }
-  try {
-    handler.parse(&option, ":80");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  }
-  try {
-    handler.parse(&option, "foo:bar");
+    handler.parse(&option, "http://bar:65536");
     CPPUNIT_FAIL("exception must be thrown.");
   } catch(Exception& e) {
     std::cerr << e.stackTrace() << std::endl;
   }
-  CPPUNIT_ASSERT_EQUAL(std::string("HOST:PORT"),
+  CPPUNIT_ASSERT_EQUAL(std::string("[http://][USER:PASSWORD@]HOST[:PORT]"),
 		       handler.createPossibleValuesString());
 }