Bladeren bron

2010-03-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Resurrected --http-proxy-user and --http-proxy-passwd option.
	Added --https-proxy-user, --https-proxy-passwd, --ftp-proxy-user,
	--ftp-proxy-passwd, --all-proxy-user, --all-proxy-passwd option.
	* doc/aria2c.1.txt
	* src/OptionHandlerFactory.cc
	* src/OptionHandlerImpl.h
	* src/prefs.cc
	* src/prefs.h
	* src/usage_text.h
	* test/OptionHandlerTest.cc
Tatsuhiro Tsujikawa 15 jaren geleden
bovenliggende
commit
ca2b33c3da
10 gewijzigde bestanden met toevoegingen van 560 en 9 verwijderingen
  1. 13 0
      ChangeLog
  2. 90 3
      doc/aria2c.1
  3. 91 1
      doc/aria2c.1.html
  4. 54 1
      doc/aria2c.1.txt
  5. 70 0
      src/OptionHandlerFactory.cc
  6. 116 4
      src/OptionHandlerImpl.h
  7. 8 0
      src/prefs.cc
  8. 8 0
      src/prefs.h
  9. 16 0
      src/usage_text.h
  10. 94 0
      test/OptionHandlerTest.cc

+ 13 - 0
ChangeLog

@@ -1,3 +1,16 @@
+2010-03-12  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Resurrected --http-proxy-user and --http-proxy-passwd option.
+	Added --https-proxy-user, --https-proxy-passwd, --ftp-proxy-user,
+	--ftp-proxy-passwd, --all-proxy-user, --all-proxy-passwd option.
+	* doc/aria2c.1.txt
+	* src/OptionHandlerFactory.cc
+	* src/OptionHandlerImpl.h
+	* src/prefs.cc
+	* src/prefs.h
+	* src/usage_text.h
+	* test/OptionHandlerTest.cc
+
 2010-03-10  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 2010-03-10  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 
 	Updated Russian and Simplified Chinese translation. Thanks to all
 	Updated Russian and Simplified Chinese translation. Thanks to all

+ 90 - 3
doc/aria2c.1

@@ -2,12 +2,12 @@
 .\"     Title: aria2c
 .\"     Title: aria2c
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 03/09/2010
+.\"      Date: 03/12/2010
 .\"    Manual: Aria2 Manual
 .\"    Manual: Aria2 Manual
-.\"    Source: Aria2 1.9.0a
+.\"    Source: Aria2 1.9.0
 .\"  Language: English
 .\"  Language: English
 .\"
 .\"
-.TH "ARIA2C" "1" "03/09/2010" "Aria2 1\&.9\&.0a" "Aria2 Manual"
+.TH "ARIA2C" "1" "03/12/2010" "Aria2 1\&.9\&.0" "Aria2 Manual"
 .\" -----------------------------------------------------------------
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" -----------------------------------------------------------------
@@ -114,6 +114,36 @@ and
 \fB\-\-ftp\-proxy\fR
 \fB\-\-ftp\-proxy\fR
 options\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 options\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 .RE
 .RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.sp
+If user and password are embedded in proxy URI and they are also specified by \fB\-\-{http,https,ftp,all}\-proxy\-{user,passwd}\fR options, those appeared later have precedence\&. For example, you have http\-proxy\-user="myname", http\-proxy\-passwd="mypass" in aria2\&.conf and you specify \-\-http\-proxy="http://proxy" in command\-line, then you get HTTP proxy "http://proxy" with user "myname" and password "mypass"\&. Another example: if you specified in command\-line \-\-http\-proxy="http://user:pass@proxy" \-\-http\-proxy\-user="myname" \-\-http\-proxy\-passwd="mypass", then you will get HTTP proxy "http://proxy" with user "myname" and password "mypass"\&. One more example: if you specified in command\-line \-\-http\-proxy\-user="myname" \-\-http\-proxy\-passwd="mypass" \-\-http\-proxy="http://user:pass@proxy", then you get HTTP proxy "http://proxy" with user "user" and password "pass"\&.
+.sp .5v
+.RE
+.PP
+\fB\-\-all\-proxy\-passwd\fR=PASSWD
+.RS 4
+Set password for
+\fB\-\-all\-proxy\fR
+option\&.
+.RE
+.PP
+\fB\-\-all\-proxy\-user\fR=USER
+.RS 4
+Set user for
+\fB\-\-all\-proxy\fR
+option\&.
+.RE
 .PP
 .PP
 \fB\-\-connect\-timeout\fR=SEC
 \fB\-\-connect\-timeout\fR=SEC
 .RS 4
 .RS 4
@@ -339,6 +369,25 @@ Use this proxy server for HTTP\&. To erase previously defined proxy, use ""\&. S
 option\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 option\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 .RE
 .RE
 .PP
 .PP
+\fB\-\-http\-proxy\-passwd\fR=PASSWD
+.RS 4
+Set password for
+\fB\-\-http\-proxy\fR
+option\&.
+.RE
+.sp
+\fB\-\-http\-proxy\-user\fR=USER:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+Set user for *\-\-http\-proxy* option\&.
+.fi
+.if n \{\
+.RE
+.\}
+.PP
 \fB\-\-https\-proxy\fR=PROXY
 \fB\-\-https\-proxy\fR=PROXY
 .RS 4
 .RS 4
 Use this proxy server for HTTPS\&. To erase previously defined proxy, use ""\&. See also
 Use this proxy server for HTTPS\&. To erase previously defined proxy, use ""\&. See also
@@ -346,6 +395,20 @@ Use this proxy server for HTTPS\&. To erase previously defined proxy, use ""\&.
 option\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 option\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 .RE
 .RE
 .PP
 .PP
+\fB\-\-https\-proxy\-passwd\fR=PASSWD
+.RS 4
+Set password for
+\fB\-\-https\-proxy\fR
+option\&.
+.RE
+.PP
+\fB\-\-https\-proxy\-user\fR=USER
+.RS 4
+Set user for
+\fB\-\-https\-proxy\fR
+option\&.
+.RE
+.PP
 \fB\-\-private\-key\fR=FILE
 \fB\-\-private\-key\fR=FILE
 .RS 4
 .RS 4
 Use the private key in FILE\&. The private key must be decrypted and in PEM format\&. The behavior when encrypted one is given is undefined\&. See also
 Use the private key in FILE\&. The private key must be decrypted and in PEM format\&. The behavior when encrypted one is given is undefined\&. See also
@@ -444,6 +507,20 @@ Use this proxy server for FTP\&. To erase previously defined proxy, use ""\&. Se
 option\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 option\&. This affects all URLs\&. The format of PROXY is [http://][USER:PASSWORD@]HOST[:PORT]
 .RE
 .RE
 .PP
 .PP
+\fB\-\-ftp\-proxy\-passwd\fR=PASSWD
+.RS 4
+Set password for
+\fB\-\-ftp\-proxy\fR
+option\&.
+.RE
+.PP
+\fB\-\-ftp\-proxy\-user\fR=USER
+.RS 4
+Set user for
+\fB\-\-ftp\-proxy\fR
+option\&.
+.RE
+.PP
 \fB\-\-ftp\-type\fR=TYPE
 \fB\-\-ftp\-type\fR=TYPE
 .RS 4
 .RS 4
 Set FTP transfer type\&. TYPE is either
 Set FTP transfer type\&. TYPE is either
@@ -2889,6 +2966,16 @@ aria2c \-\-http\-proxy="http://username:password@proxy:8080" "http://host/file"
 .if n \{\
 .if n \{\
 .RE
 .RE
 .\}
 .\}
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+aria2c \-\-http\-proxy="http://proxy:8080" \-\-http\-proxy\-user="username" \-\-http\-proxy\-passwd="password" "http://host/file"
+.fi
+.if n \{\
+.RE
+.\}
 .RE
 .RE
 .SS "Metalink Download"
 .SS "Metalink Download"
 .sp
 .sp

+ 91 - 1
doc/aria2c.1.html

@@ -685,6 +685,45 @@ downloading a file like BitTorrent.</p></div>
   The format of PROXY is [<a href="http://][USER:PASSWORD@]HOST[:PORT">http://][USER:PASSWORD@]HOST[:PORT</a>]
   The format of PROXY is [<a href="http://][USER:PASSWORD@]HOST[:PORT">http://][USER:PASSWORD@]HOST[:PORT</a>]
 </p>
 </p>
 </dd>
 </dd>
+</dl></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content">If user and password are embedded in proxy URI and they are also
+specified by <strong>--{http,https,ftp,all}-proxy-{user,passwd}</strong> options,
+those appeared later have precedence. For example, you have
+http-proxy-user="myname", http-proxy-passwd="mypass" in aria2.conf and
+you specify --http-proxy="http://proxy" in command-line, then you get
+HTTP proxy "http://proxy" with user "myname" and password
+"mypass". Another example: if you specified in command-line
+--http-proxy="http://user:pass@proxy" --http-proxy-user="myname"
+--http-proxy-passwd="mypass", then you will get HTTP proxy
+"http://proxy" with user "myname" and password "mypass".  One more
+example: if you specified in command-line --http-proxy-user="myname"
+--http-proxy-passwd="mypass" --http-proxy="http://user:pass@proxy",
+then you get HTTP proxy "http://proxy" with user "user" and password
+"pass".</td>
+</tr></table>
+</div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+<strong>--all-proxy-passwd</strong>=PASSWD
+</dt>
+<dd>
+<p>
+  Set password for <strong>--all-proxy</strong> option.
+</p>
+</dd>
+<dt class="hdlist1">
+<strong>--all-proxy-user</strong>=USER
+</dt>
+<dd>
+<p>
+  Set user for <strong>--all-proxy</strong> option.
+</p>
+</dd>
 <dt class="hdlist1">
 <dt class="hdlist1">
 <strong>--connect-timeout</strong>=SEC
 <strong>--connect-timeout</strong>=SEC
 </dt>
 </dt>
@@ -970,6 +1009,21 @@ aria2c -o myfile.zip "http://mirror1/file.zip" "http://mirror2/file.zip"</td>
 </p>
 </p>
 </dd>
 </dd>
 <dt class="hdlist1">
 <dt class="hdlist1">
+<strong>--http-proxy-passwd</strong>=PASSWD
+</dt>
+<dd>
+<p>
+  Set password for <strong>--http-proxy</strong> option.
+</p>
+</dd>
+</dl></div>
+<div class="paragraph"><p><strong>--http-proxy-user</strong>=USER:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>Set user for *--http-proxy* option.</tt></pre>
+</div></div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
 <strong>--https-proxy</strong>=PROXY
 <strong>--https-proxy</strong>=PROXY
 </dt>
 </dt>
 <dd>
 <dd>
@@ -980,6 +1034,22 @@ aria2c -o myfile.zip "http://mirror1/file.zip" "http://mirror2/file.zip"</td>
 </p>
 </p>
 </dd>
 </dd>
 <dt class="hdlist1">
 <dt class="hdlist1">
+<strong>--https-proxy-passwd</strong>=PASSWD
+</dt>
+<dd>
+<p>
+  Set password for <strong>--https-proxy</strong> option.
+</p>
+</dd>
+<dt class="hdlist1">
+<strong>--https-proxy-user</strong>=USER
+</dt>
+<dd>
+<p>
+  Set user for <strong>--https-proxy</strong> option.
+</p>
+</dd>
+<dt class="hdlist1">
 <strong>--private-key</strong>=FILE
 <strong>--private-key</strong>=FILE
 </dt>
 </dt>
 <dd>
 <dd>
@@ -1120,6 +1190,22 @@ aria2c -o myfile.zip "http://mirror1/file.zip" "http://mirror2/file.zip"</td>
 </p>
 </p>
 </dd>
 </dd>
 <dt class="hdlist1">
 <dt class="hdlist1">
+<strong>--ftp-proxy-passwd</strong>=PASSWD
+</dt>
+<dd>
+<p>
+  Set password for <strong>--ftp-proxy</strong> option.
+</p>
+</dd>
+<dt class="hdlist1">
+<strong>--ftp-proxy-user</strong>=USER
+</dt>
+<dd>
+<p>
+  Set user for <strong>--ftp-proxy</strong> option.
+</p>
+</dd>
+<dt class="hdlist1">
 <strong>--ftp-type</strong>=TYPE
 <strong>--ftp-type</strong>=TYPE
 </dt>
 </dt>
 <dd>
 <dd>
@@ -3504,6 +3590,10 @@ You can specify proxy in the environment variables. See <strong>ENVIRONMENT</str
 <div class="content">
 <div class="content">
 <pre><tt>aria2c --http-proxy="http://username:password@proxy:8080" "http://host/file"</tt></pre>
 <pre><tt>aria2c --http-proxy="http://username:password@proxy:8080" "http://host/file"</tt></pre>
 </div></div>
 </div></div>
+<div class="listingblock">
+<div class="content">
+<pre><tt>aria2c --http-proxy="http://proxy:8080" --http-proxy-user="username" --http-proxy-passwd="password" "http://host/file"</tt></pre>
+</div></div>
 <h3 id="_metalink_download">Metalink Download</h3><div style="clear:left"></div>
 <h3 id="_metalink_download">Metalink Download</h3><div style="clear:left"></div>
 <h4 id="_download_files_with_remote_metalink">Download files with remote Metalink</h4>
 <h4 id="_download_files_with_remote_metalink">Download files with remote Metalink</h4>
 <div class="listingblock">
 <div class="listingblock">
@@ -3824,7 +3914,7 @@ files in the program, then also delete it here.</p></div>
 <div id="footnotes"><hr /></div>
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer">
 <div id="footer-text">
 <div id="footer-text">
-Last updated 2010-03-09 00:04:25 JST
+Last updated 2010-03-11 23:51:12 JST
 </div>
 </div>
 </div>
 </div>
 </body>
 </body>

+ 54 - 1
doc/aria2c.1.txt

@@ -3,7 +3,7 @@ ARIA2C(1)
 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
 :man source: Aria2
 :man source: Aria2
 :man manual: Aria2 Manual
 :man manual: Aria2 Manual
-:man version: 1.9.0a
+:man version: 1.9.0
 
 
 NAME
 NAME
 ----
 ----
@@ -84,6 +84,31 @@ HTTP/FTP Options
   *--https-proxy* and *--ftp-proxy* options.  This affects all URLs.
   *--https-proxy* and *--ftp-proxy* options.  This affects all URLs.
   The format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
   The format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
 
 
+[NOTE]
+
+If user and password are embedded in proxy URI and they are also
+specified by *--{http,https,ftp,all}-proxy-{user,passwd}* options,
+those appeared later have precedence. For example, you have
+http-proxy-user="myname", http-proxy-passwd="mypass" in aria2.conf and
+you specify --http-proxy="http://proxy" in command-line, then you get
+HTTP proxy "http://proxy" with user "myname" and password
+"mypass". Another example: if you specified in command-line
+--http-proxy="http://user:pass@proxy" --http-proxy-user="myname"
+--http-proxy-passwd="mypass", then you will get HTTP proxy
+"http://proxy" with user "myname" and password "mypass".  One more
+example: if you specified in command-line --http-proxy-user="myname"
+--http-proxy-passwd="mypass" --http-proxy="http://user:pass@proxy",
+then you get HTTP proxy "http://proxy" with user "user" and password
+"pass".
+
+*--all-proxy-passwd*=PASSWD::
+
+  Set password for *--all-proxy* option.
+
+*--all-proxy-user*=USER::
+
+  Set user for *--all-proxy* option.
+
 *--connect-timeout*=SEC::
 *--connect-timeout*=SEC::
   Set the connect timeout in seconds to establish connection to
   Set the connect timeout in seconds to establish connection to
   HTTP/FTP/proxy server. After the connection is established, this
   HTTP/FTP/proxy server. After the connection is established, this
@@ -239,12 +264,28 @@ HTTP Specific Options
   use "".  See also *--all-proxy* option.  This affects all URLs.  The
   use "".  See also *--all-proxy* option.  This affects all URLs.  The
   format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
   format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
 
 
+*--http-proxy-passwd*=PASSWD::
+
+  Set password for *--http-proxy* option.
+
+*--http-proxy-user*=USER:
+
+  Set user for *--http-proxy* option.
+
 *--https-proxy*=PROXY::
 *--https-proxy*=PROXY::
 
 
   Use this proxy server for HTTPS. To erase previously defined proxy,
   Use this proxy server for HTTPS. To erase previously defined proxy,
   use "". See also *--all-proxy* option.  This affects all URLs.  The
   use "". See also *--all-proxy* option.  This affects all URLs.  The
   format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
   format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
 
 
+*--https-proxy-passwd*=PASSWD::
+
+  Set password for *--https-proxy* option.
+
+*--https-proxy-user*=USER::
+
+  Set user for *--https-proxy* option.
+
 *--private-key*=FILE::
 *--private-key*=FILE::
   Use the private key in FILE.
   Use the private key in FILE.
   The private key must be decrypted and in PEM format.
   The private key must be decrypted and in PEM format.
@@ -315,6 +356,14 @@ FTP Specific Options
   use "".  See also *--all-proxy* option.  This affects all URLs.  The
   use "".  See also *--all-proxy* option.  This affects all URLs.  The
   format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
   format of PROXY is [\http://][USER:PASSWORD@]HOST[:PORT]
 
 
+*--ftp-proxy-passwd*=PASSWD::
+
+  Set password for *--ftp-proxy* option.
+
+*--ftp-proxy-user*=USER::
+
+  Set user for *--ftp-proxy* option.
+
 *--ftp-type*=TYPE::
 *--ftp-type*=TYPE::
   Set FTP transfer type. TYPE is either 'binary' or 'ascii'.
   Set FTP transfer type. TYPE is either 'binary' or 'ascii'.
   Default: 'binary'
   Default: 'binary'
@@ -1754,6 +1803,10 @@ Proxy with authorization
 aria2c --http-proxy="http://username:password@proxy:8080" "http://host/file"
 aria2c --http-proxy="http://username:password@proxy:8080" "http://host/file"
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 
 
+----------------------------------------------------------------------------
+aria2c --http-proxy="http://proxy:8080" --http-proxy-user="username" --http-proxy-passwd="password" "http://host/file"
+----------------------------------------------------------------------------
+
 Metalink Download
 Metalink Download
 ~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~
 Download files with remote Metalink
 Download files with remote Metalink

+ 70 - 0
src/OptionHandlerFactory.cc

@@ -871,6 +871,22 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_HTTP);
     op->addTag(TAG_HTTP);
     handlers.push_back(op);
     handlers.push_back(op);
   }
   }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyPasswdOptionHandler
+                                   (PREF_HTTP_PROXY_PASSWD,
+                                    TEXT_HTTP_PROXY_PASSWD,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyUserOptionHandler
+                                   (PREF_HTTP_PROXY_USER,
+                                    TEXT_HTTP_PROXY_USER,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_HTTP);
+    handlers.push_back(op);
+  }
   {
   {
     SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
     SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
                                    (PREF_HTTPS_PROXY,
                                    (PREF_HTTPS_PROXY,
@@ -880,6 +896,24 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_HTTPS);
     op->addTag(TAG_HTTPS);
     handlers.push_back(op);
     handlers.push_back(op);
   }
   }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyPasswdOptionHandler
+                                   (PREF_HTTPS_PROXY_PASSWD,
+                                    TEXT_HTTPS_PROXY_PASSWD,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_HTTP);
+    op->addTag(TAG_HTTPS);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyUserOptionHandler
+                                   (PREF_HTTPS_PROXY_USER,
+                                    TEXT_HTTPS_PROXY_USER,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_HTTP);
+    op->addTag(TAG_HTTPS);
+    handlers.push_back(op);
+  }
   {
   {
     SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
     SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
                                    (PREF_FTP_PROXY,
                                    (PREF_FTP_PROXY,
@@ -888,6 +922,22 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_FTP);
     op->addTag(TAG_FTP);
     handlers.push_back(op);
     handlers.push_back(op);
   }
   }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyPasswdOptionHandler
+                                   (PREF_FTP_PROXY_PASSWD,
+                                    TEXT_FTP_PROXY_PASSWD,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyUserOptionHandler
+                                   (PREF_FTP_PROXY_USER,
+                                    TEXT_FTP_PROXY_USER,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_FTP);
+    handlers.push_back(op);
+  }
   {
   {
     SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
     SharedHandle<OptionHandler> op(new HttpProxyOptionHandler
                                    (PREF_ALL_PROXY,
                                    (PREF_ALL_PROXY,
@@ -898,6 +948,26 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     op->addTag(TAG_HTTPS);
     op->addTag(TAG_HTTPS);
     handlers.push_back(op);
     handlers.push_back(op);
   }
   }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyPasswdOptionHandler
+                                   (PREF_ALL_PROXY_PASSWD,
+                                    TEXT_ALL_PROXY_PASSWD,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    op->addTag(TAG_HTTPS);
+    handlers.push_back(op);
+  }
+  {
+    SharedHandle<OptionHandler> op(new HttpProxyUserOptionHandler
+                                   (PREF_ALL_PROXY_USER,
+                                    TEXT_ALL_PROXY_USER,
+                                    NO_DEFAULT_VALUE));
+    op->addTag(TAG_FTP);
+    op->addTag(TAG_HTTP);
+    op->addTag(TAG_HTTPS);
+    handlers.push_back(op);
+  }
   {
   {
     SharedHandle<OptionHandler> op(new DefaultOptionHandler
     SharedHandle<OptionHandler> op(new DefaultOptionHandler
                                    (PREF_NO_PROXY,
                                    (PREF_NO_PROXY,

+ 116 - 4
src/OptionHandlerImpl.h

@@ -37,6 +37,7 @@
 
 
 #include "OptionHandler.h"
 #include "OptionHandler.h"
 
 
+#include <cassert>
 #include <cstdio>
 #include <cstdio>
 #include <utility>
 #include <utility>
 #include <algorithm>
 #include <algorithm>
@@ -543,7 +544,96 @@ public:
   }
   }
 };
 };
 
 
+class HttpProxyUserOptionHandler:public NameMatchOptionHandler {
+public:
+  HttpProxyUserOptionHandler(const std::string& optName,
+                             const std::string& description,
+                             const std::string& defaultValue,
+                             char shortName = 0):
+    NameMatchOptionHandler(optName, description, defaultValue,
+                           OptionHandler::REQ_ARG, shortName)
+  {}
+
+  virtual void parseArg(Option& option, const std::string& optarg)
+  {
+    if(util::endsWith(_optName, "-user")) {
+      const std::string proxyPref = _optName.substr(0, _optName.size()-5);
+      const std::string& olduri = option.get(proxyPref);
+      if(!olduri.empty()) {
+        Request req;
+        bool b = req.setUri(olduri);
+        assert(b);
+        std::string uri = "http://";
+        if(!optarg.empty()) {
+          uri += util::percentEncode(optarg);
+        }
+        if(req.hasPassword()) {
+          uri += A2STR::COLON_C;
+          uri += util::percentEncode(req.getPassword());
+        }
+        if(uri.size() > 7) {
+          uri += "@";
+        }
+        strappend(uri, req.getHost(),A2STR::COLON_C,util::uitos(req.getPort()));
+        option.put(proxyPref, uri);
+      }
+    }
+    option.put(_optName, optarg);
+  }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return "";
+  }
+};
+
+class HttpProxyPasswdOptionHandler:public NameMatchOptionHandler {
+public:
+  HttpProxyPasswdOptionHandler(const std::string& optName,
+                               const std::string& description,
+                               const std::string& defaultValue,
+                               char shortName = 0):
+    NameMatchOptionHandler(optName, description, defaultValue,
+                           OptionHandler::REQ_ARG, shortName)
+  {}
+
+  virtual void parseArg(Option& option, const std::string& optarg)
+  {
+    if(util::endsWith(_optName, "-passwd")) {
+      const std::string proxyPref = _optName.substr(0, _optName.size()-7);
+      const std::string& olduri = option.get(proxyPref);
+      if(!olduri.empty()) {
+        Request req;
+        bool b = req.setUri(olduri);
+        assert(b);
+        std::string uri = "http://";
+        if(!req.getUsername().empty()) {
+          uri += util::percentEncode(req.getUsername());
+        }
+        uri += A2STR::COLON_C;
+        if(!optarg.empty()) {
+          uri += util::percentEncode(optarg);
+        }
+        if(uri.size() > 7) {
+          uri += "@";
+        }
+        strappend(uri, req.getHost(), A2STR::COLON_C,util::itos(req.getPort()));
+        option.put(proxyPref, uri);
+      }
+    }
+    option.put(_optName, optarg);
+  }
+
+  virtual std::string createPossibleValuesString() const
+  {
+    return "";
+  }
+};
+
 class HttpProxyOptionHandler : public NameMatchOptionHandler {
 class HttpProxyOptionHandler : public NameMatchOptionHandler {
+private:
+  std::string _proxyUserPref;
+  std::string _proxyPasswdPref;
 public:
 public:
   HttpProxyOptionHandler(const std::string& optName,
   HttpProxyOptionHandler(const std::string& optName,
                          const std::string& description,
                          const std::string& description,
@@ -551,7 +641,9 @@ public:
                          char shortName = 0)
                          char shortName = 0)
     :
     :
     NameMatchOptionHandler(optName, description, defaultValue,
     NameMatchOptionHandler(optName, description, defaultValue,
-                           OptionHandler::REQ_ARG, shortName)
+                           OptionHandler::REQ_ARG, shortName),
+    _proxyUserPref(_optName+"-user"),
+    _proxyPasswdPref(_optName+"-passwd")
   {}
   {}
 
 
   virtual ~HttpProxyOptionHandler() {}
   virtual ~HttpProxyOptionHandler() {}
@@ -568,11 +660,31 @@ public:
       } else {
       } else {
         uri = "http://"+optarg;
         uri = "http://"+optarg;
       }
       }
-      if(req.setUri(uri)) {
-        option.put(_optName, uri);
-      } else {
+      if(!req.setUri(uri)) {
         throw DL_ABORT_EX(_("unrecognized proxy format"));
         throw DL_ABORT_EX(_("unrecognized proxy format"));
       }
       }
+      uri = "http://";
+      if(req.getUsername().empty()) {
+        if(option.defined(_proxyUserPref)) {
+          uri += util::percentEncode(option.get(_proxyUserPref));
+        }
+      } else {
+        uri += util::percentEncode(req.getUsername());
+      }
+      if(!req.hasPassword()) {
+        if(option.defined(_proxyPasswdPref)) {
+          uri += A2STR::COLON_C;
+          uri += util::percentEncode(option.get(_proxyPasswdPref));
+        }
+      } else {
+        uri += A2STR::COLON_C;
+        uri += util::percentEncode(req.getPassword());
+      }
+      if(uri.size() > 7) {
+        uri += "@";
+      }
+      strappend(uri, req.getHost(), A2STR::COLON_C, util::uitos(req.getPort()));
+      option.put(_optName, uri);
     }
     }
   }
   }
 
 

+ 8 - 0
src/prefs.cc

@@ -240,6 +240,14 @@ const std::string PREF_NO_PROXY("no-proxy");
 const std::string PREF_PROXY_METHOD("proxy-method");
 const std::string PREF_PROXY_METHOD("proxy-method");
 const std::string V_GET("get");
 const std::string V_GET("get");
 const std::string V_TUNNEL("tunnel");
 const std::string V_TUNNEL("tunnel");
+const std::string PREF_HTTP_PROXY_USER("http-proxy-user");
+const std::string PREF_HTTP_PROXY_PASSWD("http-proxy-passwd");
+const std::string PREF_HTTPS_PROXY_USER("https-proxy-user");
+const std::string PREF_HTTPS_PROXY_PASSWD("https-proxy-passwd");
+const std::string PREF_FTP_PROXY_USER("ftp-proxy-user");
+const std::string PREF_FTP_PROXY_PASSWD("ftp-proxy-passwd");
+const std::string PREF_ALL_PROXY_USER("all-proxy-user");
+const std::string PREF_ALL_PROXY_PASSWD("all-proxy-passwd");
 
 
 /**
 /**
  * BitTorrent related preferences
  * BitTorrent related preferences

+ 8 - 0
src/prefs.h

@@ -244,6 +244,14 @@ extern const std::string PREF_NO_PROXY;
 extern const std::string PREF_PROXY_METHOD;
 extern const std::string PREF_PROXY_METHOD;
 extern const std::string V_GET;
 extern const std::string V_GET;
 extern const std::string V_TUNNEL;
 extern const std::string V_TUNNEL;
+extern const std::string PREF_HTTP_PROXY_USER;
+extern const std::string PREF_HTTP_PROXY_PASSWD;
+extern const std::string PREF_HTTPS_PROXY_USER;
+extern const std::string PREF_HTTPS_PROXY_PASSWD;
+extern const std::string PREF_FTP_PROXY_USER;
+extern const std::string PREF_FTP_PROXY_PASSWD;
+extern const std::string PREF_ALL_PROXY_USER;
+extern const std::string PREF_ALL_PROXY_PASSWD;
 
 
 /**
 /**
  * BitTorrent related preferences
  * BitTorrent related preferences

+ 16 - 0
src/usage_text.h

@@ -618,3 +618,19 @@
 #define TEXT_REUSE_URI                          \
 #define TEXT_REUSE_URI                          \
   _(" --reuse-uri[=true|false]     Reuse already used URIs if no unused URIs are\n" \
   _(" --reuse-uri[=true|false]     Reuse already used URIs if no unused URIs are\n" \
     "                              left.")
     "                              left.")
+#define TEXT_ALL_PROXY_USER                                             \
+  _(" --all-proxy-user=USER        Set user for --all-proxy option.")
+#define TEXT_ALL_PROXY_PASSWD                                           \
+  _(" --all-proxy-passwd=PASSWD    Set password for --all-proxy option.")
+#define TEXT_HTTP_PROXY_USER                                            \
+  _(" --http-proxy-user=USER       Set user for --http-proxy option.")
+#define TEXT_HTTP_PROXY_PASSWD                                          \
+  _(" --http-proxy-passwd=PASSWD   Set password for --http-proxy option.")
+#define TEXT_HTTPS_PROXY_USER                                           \
+  _(" --https-proxy-user=USER      Set user for --https-proxy option.")
+#define TEXT_HTTPS_PROXY_PASSWD                                         \
+  _(" --https-proxy-passwd=PASSWD  Set password for --https-proxy option.")
+#define TEXT_FTP_PROXY_USER                                             \
+  _(" --ftp-proxy-user=USER        Set user for --ftp-proxy option.")
+#define TEXT_FTP_PROXY_PASSWD                                           \
+  _(" --ftp-proxy-passwd=PASSWD    Set password for --ftp-proxy option.")

+ 94 - 0
test/OptionHandlerTest.cc

@@ -26,6 +26,8 @@ class OptionHandlerTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testFloatNumberOptionHandler_max);
   CPPUNIT_TEST(testFloatNumberOptionHandler_max);
   CPPUNIT_TEST(testFloatNumberOptionHandler_min_max);
   CPPUNIT_TEST(testFloatNumberOptionHandler_min_max);
   CPPUNIT_TEST(testHttpProxyOptionHandler);
   CPPUNIT_TEST(testHttpProxyOptionHandler);
+  CPPUNIT_TEST(testHttpProxyUserOptionHandler);
+  CPPUNIT_TEST(testHttpProxyPasswdOptionHandler);
   CPPUNIT_TEST_SUITE_END();
   CPPUNIT_TEST_SUITE_END();
   
   
 public:
 public:
@@ -45,6 +47,8 @@ public:
   void testFloatNumberOptionHandler_max();
   void testFloatNumberOptionHandler_max();
   void testFloatNumberOptionHandler_min_max();
   void testFloatNumberOptionHandler_min_max();
   void testHttpProxyOptionHandler();
   void testHttpProxyOptionHandler();
+  void testHttpProxyUserOptionHandler();
+  void testHttpProxyPasswdOptionHandler();
 };
 };
 
 
 
 
@@ -323,6 +327,96 @@ void OptionHandlerTest::testHttpProxyOptionHandler()
   } catch(Exception& e) {}
   } catch(Exception& e) {}
   CPPUNIT_ASSERT_EQUAL(std::string("[http://][USER:PASSWORD@]HOST[:PORT]"),
   CPPUNIT_ASSERT_EQUAL(std::string("[http://][USER:PASSWORD@]HOST[:PORT]"),
                        handler.createPossibleValuesString());
                        handler.createPossibleValuesString());
+
+  handler.parse(option, "http://user%40:passwd%40@proxy:8080");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://user%40:passwd%40@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY_USER, "proxy@user");
+  handler.parse(option, "http://proxy:8080");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://proxy%40user@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY_PASSWD, "proxy@passwd");
+  handler.parse(option, "http://proxy:8080");
+  CPPUNIT_ASSERT_EQUAL
+    (std::string("http://proxy%40user:proxy%40passwd@proxy:8080"),
+     option.get(PREF_HTTP_PROXY));
+
+  handler.parse(option, "http://user:passwd@proxy:8080");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://user:passwd@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY_USER, "");
+  handler.parse(option, "http://proxy:8080");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://:proxy%40passwd@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY_PASSWD, "");
+  handler.parse(option, "http://proxy:8080");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://:@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+}
+
+void OptionHandlerTest::testHttpProxyUserOptionHandler()
+{
+  HttpProxyUserOptionHandler handler(PREF_HTTP_PROXY_USER, "", "");
+  Option option;
+  handler.parse(option, "proxyuser");
+  CPPUNIT_ASSERT_EQUAL(std::string("proxyuser"),
+                       option.get(PREF_HTTP_PROXY_USER));
+
+  option.put(PREF_HTTP_PROXY, "http://proxy:8080");
+  handler.parse(option, "proxy@user");
+  CPPUNIT_ASSERT_EQUAL(std::string("proxy@user"),
+                       option.get(PREF_HTTP_PROXY_USER));
+  CPPUNIT_ASSERT_EQUAL(std::string("http://proxy%40user@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY, "http://user@proxy:8080");
+  handler.parse(option, "proxyuser");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://proxyuser@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY, "http://user:passwd%40@proxy:8080");
+  handler.parse(option, "proxyuser");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://proxyuser:passwd%40@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  handler.parse(option, "");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://:passwd%40@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+}
+
+void OptionHandlerTest::testHttpProxyPasswdOptionHandler()
+{
+  HttpProxyPasswdOptionHandler handler(PREF_HTTP_PROXY_PASSWD, "", "");
+  Option option;
+  handler.parse(option, "proxypasswd");
+  CPPUNIT_ASSERT_EQUAL(std::string("proxypasswd"),
+                       option.get(PREF_HTTP_PROXY_PASSWD));
+
+  option.put(PREF_HTTP_PROXY, "http://proxy:8080");
+  handler.parse(option, "proxy@passwd");
+  CPPUNIT_ASSERT_EQUAL(std::string("proxy@passwd"),
+                       option.get(PREF_HTTP_PROXY_PASSWD));
+  CPPUNIT_ASSERT_EQUAL(std::string("http://:proxy%40passwd@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY, "http://:pass@proxy:8080");
+  handler.parse(option, "proxypasswd");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://:proxypasswd@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  option.put(PREF_HTTP_PROXY, "http://user%40:pass@proxy:8080");
+  handler.parse(option, "proxypasswd");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://user%40:proxypasswd@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+
+  handler.parse(option, "");
+  CPPUNIT_ASSERT_EQUAL(std::string("http://user%40:@proxy:8080"),
+                       option.get(PREF_HTTP_PROXY));
+  
 }
 }
 
 
 } // namespace aria2
 } // namespace aria2