Переглянути джерело

2008-11-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Added --no-proxy option. It receives comman separated hostname
	or domains to which proxy should not be used.
	aria2 honors the environment variable no_proxy to override
	no-proxy value in configuration file. The user can override the
	environment variable no_proxy with --no-proxy command-line
	option.
	* src/AbstractCommand.cc
	* src/OptionHandlerFactory.cc
	* src/option_processing.cc
	* src/prefs.cc
	* src/prefs.h
	* src/usage_text.h
Tatsuhiro Tsujikawa 17 роки тому
батько
коміт
0308785bd8
7 змінених файлів з 72 додано та 1 видалено
  1. 14 0
      ChangeLog
  2. 38 1
      src/AbstractCommand.cc
  3. 8 0
      src/OptionHandlerFactory.cc
  4. 5 0
      src/option_processing.cc
  5. 2 0
      src/prefs.cc
  6. 2 0
      src/prefs.h
  7. 3 0
      src/usage_text.h

+ 14 - 0
ChangeLog

@@ -1,3 +1,17 @@
+2008-11-09  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Added --no-proxy option. It receives comman separated hostname or
+	domains to which proxy should not be used.
+	aria2 honors the environment variable no_proxy to override no-proxy
+	value in configuration file. The user can override the environment
+	variable no_proxy with --no-proxy command-line option.
+	* src/AbstractCommand.cc
+	* src/OptionHandlerFactory.cc
+	* src/option_processing.cc
+	* src/prefs.cc
+	* src/prefs.h
+	* src/usage_text.h
+	
 2008-11-09  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Added the ability to verify peer in SSL/TLS using given CA certificates.

+ 38 - 1
src/AbstractCommand.cc

@@ -33,6 +33,9 @@
  */
 /* copyright --> */
 #include "AbstractCommand.h"
+
+#include <algorithm>
+
 #include "RequestGroup.h"
 #include "Request.h"
 #include "DownloadEngine.h"
@@ -58,6 +61,7 @@
 #include "ServerStat.h"
 #include "RequestGroupMan.h"
 #include "A2STR.h"
+#include "Util.h"
 
 namespace aria2 {
 
@@ -329,9 +333,39 @@ static bool isProxyGETRequest(const std::string& protocol, const Option* option)
   return isProxyRequest(protocol, option);
 }
 
+class DomainMatch {
+private:
+  std::string _hostname;
+public:
+  DomainMatch(const std::string& hostname):_hostname(hostname) {}
+
+  bool operator()(const std::string& domain) const
+  {
+    if(Util::startsWith(domain, ".")) {
+      return Util::endsWith(_hostname, domain);
+    } else {
+      return Util::endsWith(_hostname, "."+domain);
+    }
+  }
+};
+
+static bool inNoProxy(const SharedHandle<Request>& req,
+		      const std::string& noProxy)
+{
+  std::deque<std::string> entries;
+  Util::slice(entries, noProxy, ',', true);
+  if(entries.empty()) {
+    return false;
+  }
+  return
+    std::find_if(entries.begin(), entries.end(),
+		 DomainMatch("."+req->getHost())) != entries.end();
+}
+
 bool AbstractCommand::isProxyDefined() const
 {
-  return isProxyRequest(req->getProtocol(), e->option);
+  return isProxyRequest(req->getProtocol(), e->option) &&
+    !inNoProxy(req, e->option->get(PREF_NO_PROXY));
 }
 
 static const std::string& getProxyString(const SharedHandle<Request>& req,
@@ -351,6 +385,9 @@ static const std::string& getProxyString(const SharedHandle<Request>& req,
 SharedHandle<Request> AbstractCommand::createProxyRequest() const
 {
   SharedHandle<Request> proxyRequest;
+  if(inNoProxy(req, e->option->get(PREF_NO_PROXY))) {
+    return proxyRequest;
+  }
   std::string proxy = getProxyString(req, e->option);
   if(!proxy.empty()) {
     proxyRequest.reset(new Request());

+ 8 - 0
src/OptionHandlerFactory.cc

@@ -636,6 +636,14 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_HTTP);
     handlers.push_back(op);
   }
+  {
+    SharedHandle<OptionHandler> op(new DefaultOptionHandler
+				   (PREF_NO_PROXY,
+				    TEXT_NO_PROXY));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
   {
     SharedHandle<OptionHandler> op(new ParameterOptionHandler
 				   (PREF_PROXY_METHOD,

+ 5 - 0
src/option_processing.cc

@@ -186,6 +186,7 @@ Option* option_processing(int argc, char* const argv[])
       { PREF_PRIVATE_KEY.c_str(), required_argument, &lopt, 232 },
       { PREF_CA_CERTIFICATE.c_str(), optional_argument, &lopt, 233 },
       { PREF_CHECK_CERTIFICATE.c_str(), optional_argument, &lopt, 234 },
+      { PREF_NO_PROXY.c_str(), required_argument, &lopt, 235 },
 #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 },
@@ -466,6 +467,9 @@ Option* option_processing(int argc, char* const argv[])
       case 234:
 	cmdstream << PREF_CHECK_CERTIFICATE << "=" << toBoolArg(optarg) << "\n";
 	break;
+      case 235:
+	cmdstream << PREF_NO_PROXY << "=" << optarg << "\n";
+	break;
       }
       break;
     }
@@ -593,6 +597,7 @@ Option* option_processing(int argc, char* const argv[])
     overrideWithEnv(op, oparser, PREF_HTTPS_PROXY, "https_proxy");
     overrideWithEnv(op, oparser, PREF_FTP_PROXY, "ftp_proxy");
     overrideWithEnv(op, oparser, PREF_ALL_PROXY, "all_proxy");
+    overrideWithEnv(op, oparser, PREF_NO_PROXY, "no_proxy");
 
     try {
       oparser.parse(op, cmdstream);

+ 2 - 0
src/prefs.cc

@@ -196,6 +196,8 @@ const std::string PREF_HTTP_PROXY("http-proxy");
 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: comma separeted hostname or domain
+const std::string PREF_NO_PROXY("no-proxy");
 // values: get | tunnel
 const std::string PREF_PROXY_METHOD("proxy-method");
 const std::string V_GET("get");

+ 2 - 0
src/prefs.h

@@ -200,6 +200,8 @@ extern const std::string PREF_HTTP_PROXY;
 extern const std::string PREF_HTTPS_PROXY;
 extern const std::string PREF_FTP_PROXY;
 extern const std::string PREF_ALL_PROXY;
+// values: comma separeted hostname or domain
+extern const std::string PREF_NO_PROXY;
 // values: get | tunnel
 extern const std::string PREF_PROXY_METHOD;
 extern const std::string V_GET;

+ 3 - 0
src/usage_text.h

@@ -407,3 +407,6 @@ _(" --ca-certificate=FILE        Use the certificate authorities in FILE to veri
 #define TEXT_CHECK_CERTIFICATE \
 _(" --check-certificate[=true|false] Verify the peer using certificates specified\n"\
   "                              in --ca-certificate option.")
+#define TEXT_NO_PROXY \
+_(" --no-proxy=DOMAINS           Specify comma separated hostnames or domains to\n"\
+  "                              which proxy should not be used.")