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

Accept IPv4 network address with CIDR block in --no-proxy option
	and no_proxy environment variable.  Current implementation does
	not resolve hostname in URI to compare network address. So it is
	only effecive if URI has numeric IP addresses.
	* doc/aria2c.1.txt
	* src/AbstractCommand.cc
	* src/OptionHandlerFactory.cc
	* src/bitfield.h
	* src/usage_text.h
	* src/util.cc
	* src/util.h
	* test/UtilTest.cc
	* test/bitfieldTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-03-19 08:56:17 +00:00
parent 55d7c99638
commit 4951142346
12 changed files with 211 additions and 30 deletions

View File

@ -1,3 +1,19 @@
2010-03-19 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Accept IPv4 network address with CIDR block in --no-proxy option
and no_proxy environment variable. Current implementation does
not resolve hostname in URI to compare network address. So it is
only effecive if URI has numeric IP addresses.
* doc/aria2c.1.txt
* src/AbstractCommand.cc
* src/OptionHandlerFactory.cc
* src/bitfield.h
* src/usage_text.h
* src/util.cc
* src/util.h
* test/UtilTest.cc
* test/bitfieldTest.cc
2010-03-19 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Reduced interval for metadatagetmode to quickly gather metadata.

View File

@ -2,12 +2,12 @@
.\" Title: aria2c
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 03/13/2010
.\" Date: 03/19/2010
.\" Manual: Aria2 Manual
.\" Source: Aria2 1.9.0
.\" Source: Aria2 1.9.1a
.\" Language: English
.\"
.TH "ARIA2C" "1" "03/13/2010" "Aria2 1\&.9\&.0" "Aria2 Manual"
.TH "ARIA2C" "1" "03/19/2010" "Aria2 1\&.9\&.1a" "Aria2 Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -197,7 +197,23 @@ Disables netrc support\&. netrc support is enabled by default\&.
.PP
\fB\-\-no\-proxy\fR=DOMAINS
.RS 4
Specify comma separated hostnames or domains where proxy should not be used\&.
Specify comma separated hostnames, domains and network address with or without CIDR block where proxy should not be used\&.
.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
For network address with CIDR block, only IPv4 address works\&. Current implementation does not resolve hostname in URI to compare network address specified in \fB\-\-no\-proxy\fR\&. So it is only effecive if URI has numeric IP addresses\&.
.sp .5v
.RE
.PP
\fB\-o\fR, \fB\-\-out\fR=FILE
@ -1369,7 +1385,7 @@ overrides this value\&.
.PP
no_proxy [DOMAIN,\&...]
.RS 4
Specify comma\-separated hostname or domains to which proxy should not be used\&. Overrides no\-proxy value in configuration file\&. The command\-line option
Specify comma\-separated hostname, domains and network address with or without CIDR block to which proxy should not be used\&. Overrides no\-proxy value in configuration file\&. The command\-line option
\fB\-\-no\-proxy\fR
overrides this value\&.
.RE
@ -3030,6 +3046,16 @@ aria2c \-\-http\-proxy="http://proxy:8080" "http://host/file"
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
aria2c \-\-http\-proxy="http://proxy:8080" \-\-no\-proxy="localhost,127\&.0\&.0\&.1,192\&.168\&.0\&.0/16" "http://host/file"
.fi
.if n \{\
.RE
.\}
.sp
For FTP:
.sp
.if n \{\
@ -3054,7 +3080,7 @@ aria2c \-\-ftp\-proxy="http://proxy:8080" "ftp://host/file"
.ps -1
.br
.sp
See \fB\-\-http\-proxy\fR, \fB\-\-https\-proxy\fR, \fB\-\-ftp\-proxy\fR and \fB\-\-all\-proxy\fR for details\&. You can specify proxy in the environment variables\&. See \fBENVIRONMENT\fR section\&.
See \fB\-\-http\-proxy\fR, \fB\-\-https\-proxy\fR, \fB\-\-ftp\-proxy\fR, \fB\-\-all\-proxy\fR and \fB\-\-no\-proxy\fR for details\&. You can specify proxy in the environment variables\&. See \fBENVIRONMENT\fR section\&.
.sp .5v
.RE
.RE

View File

@ -793,10 +793,23 @@ then you get HTTP proxy "http://proxy" with user "user" and password
</dt>
<dd>
<p>
Specify comma separated hostnames or domains where proxy should not be
used.
Specify comma separated hostnames, domains and network address with
or without CIDR block where proxy should not be used.
</p>
</dd>
</dl></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">For network address with CIDR block, only IPv4 address works. Current
implementation does not resolve hostname in URI to compare network
address specified in <strong>--no-proxy</strong>. So it is only effecive if URI has
numeric IP addresses.</td>
</tr></table>
</div>
<div class="dlist"><dl>
<dt class="hdlist1">
<strong>-o</strong>, <strong>--out</strong>=FILE
</dt>
@ -2281,9 +2294,10 @@ no_proxy [DOMAIN,&#8230;]
</dt>
<dd>
<p>
Specify comma-separated hostname or domains to which proxy should not be used.
Overrides no-proxy value in configuration file.
The command-line option <strong>--no-proxy</strong> overrides this value.
Specify comma-separated hostname, domains and network address with
or without CIDR block to which proxy should not be used. Overrides
no-proxy value in configuration file. The command-line option
<strong>--no-proxy</strong> overrides this value.
</p>
</dd>
</dl></div>
@ -3621,6 +3635,10 @@ pprint(r)</tt></pre>
<div class="content">
<pre><tt>aria2c --http-proxy="http://proxy:8080" "http://host/file"</tt></pre>
</div></div>
<div class="listingblock">
<div class="content">
<pre><tt>aria2c --http-proxy="http://proxy:8080" --no-proxy="localhost,127.0.0.1,192.168.0.0/16" "http://host/file"</tt></pre>
</div></div>
<div class="paragraph"><p>For FTP:</p></div>
<div class="listingblock">
<div class="content">
@ -3631,9 +3649,9 @@ pprint(r)</tt></pre>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">See <strong>--http-proxy</strong>, <strong>--https-proxy</strong>, <strong>--ftp-proxy</strong> and <strong>--all-proxy</strong> for
details.
You can specify proxy in the environment variables. See <strong>ENVIRONMENT</strong> section.</td>
<td class="content">See <strong>--http-proxy</strong>, <strong>--https-proxy</strong>, <strong>--ftp-proxy</strong>, <strong>--all-proxy</strong> and
<strong>--no-proxy</strong> for details. You can specify proxy in the environment
variables. See <strong>ENVIRONMENT</strong> section.</td>
</tr></table>
</div>
<h4 id="_proxy_with_authorization">Proxy with authorization</h4>
@ -3965,7 +3983,7 @@ files in the program, then also delete it here.</p></div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2010-03-13 00:35:15 JST
Last updated 2010-03-19 17:37:54 JST
</div>
</div>
</body>

View File

@ -3,7 +3,7 @@ ARIA2C(1)
Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
:man source: Aria2
:man manual: Aria2 Manual
:man version: 1.9.0
:man version: 1.9.1a
NAME
----
@ -144,8 +144,14 @@ then you get HTTP proxy "http://proxy" with user "user" and password
Disables netrc support. netrc support is enabled by default.
*--no-proxy*=DOMAINS::
Specify comma separated hostnames or domains where proxy should not be
used.
Specify comma separated hostnames, domains and network address with
or without CIDR block where proxy should not be used.
[NOTE]
For network address with CIDR block, only IPv4 address works. Current
implementation does not resolve hostname in URI to compare network
address specified in *--no-proxy*. So it is only effecive if URI has
numeric IP addresses.
*-o*, *--out*=FILE::
@ -973,9 +979,11 @@ all_proxy [\http://][USER:PASSWORD@]HOST[:PORT]::
The command-line option *--all-proxy* overrides this value.
no_proxy [DOMAIN,...]::
Specify comma-separated hostname or domains to which proxy should not be used.
Overrides no-proxy value in configuration file.
The command-line option *--no-proxy* overrides this value.
Specify comma-separated hostname, domains and network address with
or without CIDR block to which proxy should not be used. Overrides
no-proxy value in configuration file. The command-line option
*--no-proxy* overrides this value.
FILES
-----
@ -1798,15 +1806,20 @@ For HTTP:
----------------------------------------------------------
aria2c --http-proxy="http://proxy:8080" "http://host/file"
----------------------------------------------------------
----------------------------------------------------------
aria2c --http-proxy="http://proxy:8080" --no-proxy="localhost,127.0.0.1,192.168.0.0/16" "http://host/file"
----------------------------------------------------------
For FTP:
--------------------------------------------------------
aria2c --ftp-proxy="http://proxy:8080" "ftp://host/file"
--------------------------------------------------------
[NOTE]
See *--http-proxy*, *--https-proxy*, *--ftp-proxy* and *--all-proxy* for
details.
You can specify proxy in the environment variables. See *ENVIRONMENT* section.
See *--http-proxy*, *--https-proxy*, *--ftp-proxy*, *--all-proxy* and
*--no-proxy* for details. You can specify proxy in the environment
variables. See *ENVIRONMENT* section.
Proxy with authorization
^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -448,9 +448,33 @@ static bool inNoProxy(const SharedHandle<Request>& req,
if(entries.empty()) {
return false;
}
return
std::find_if(entries.begin(), entries.end(),
DomainMatch(A2STR::DOT_C+req->getHost())) != entries.end();
DomainMatch domainMatch(A2STR::DOT_C+req->getHost());
for(std::vector<std::string>::const_iterator i = entries.begin(),
eoi = entries.end(); i != eoi; ++i) {
std::string::size_type slashpos = (*i).find('/');
if(slashpos == std::string::npos) {
if(domainMatch(*i)) {
return true;
}
} else {
if(!util::isNumericHost(req->getHost())) {
// TODO We don't resolve hostname here. More complete
// implementation is that we should first resolve
// hostname(which may result in several IP addresses) and
// evaluates against all of them
continue;
}
std::string ip = (*i).substr(0, slashpos);
uint32_t bits;
if(!util::parseUIntNoThrow(bits, (*i).substr(slashpos+1))) {
continue;
}
if(util::inSameCidrBlock(ip, req->getHost(), bits)) {
return true;
}
}
}
return false;
}
bool AbstractCommand::isProxyDefined() const

View File

@ -971,7 +971,9 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_NO_PROXY,
TEXT_NO_PROXY));
TEXT_NO_PROXY,
NO_DEFAULT_VALUE,
"HOSTNAME,DOMAIN,NETWORK/CIDR"));
op->addTag(TAG_FTP);
op->addTag(TAG_HTTP);
op->addTag(TAG_HTTPS);

View File

@ -51,7 +51,11 @@ namespace bitfield {
// then 0x80 is returned. nbits = 12, then 0xf0 is returned.
inline unsigned char lastByteMask(size_t nbits)
{
return -256 >> (8-((nbits+7)/8*8-nbits));
if(nbits == 0) {
return 0;
} else {
return -256 >> (8-((nbits+7)/8*8-nbits));
}
}
// Returns true if index-th bits is set. Otherwise returns false.

View File

@ -480,7 +480,8 @@
_(" --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 where\n" \
_(" --no-proxy=DOMAINS Specify comma separated hostnames, domains or\n" \
" network address with or without CIDR block where\n" \
" proxy should not be used.")
#define TEXT_USE_HEAD \
_(" --use-head[=true|false] Use HEAD method for the first request to the HTTP\n" \

View File

@ -75,6 +75,7 @@
#include "A2STR.h"
#include "array_fun.h"
#include "a2functional.h"
#include "bitfield.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "MessageDigestHelper.h"
#endif // ENABLE_MESSAGE_DIGEST
@ -1263,6 +1264,39 @@ std::string escapePath(const std::string& s)
return d;
}
bool getCidrPrefix(struct in_addr& in, const std::string& ip, int bits)
{
struct in_addr t;
if(inet_aton(ip.c_str(), &t) == 0) {
return false;
}
int lastindex = bits/8;
if(lastindex < 4) {
char* p = reinterpret_cast<char*>(&t.s_addr);
const char* last = p+4;
p += lastindex;
if(bits%8 != 0) {
*p &= bitfield::lastByteMask(bits);
++p;
}
for(; p != last; ++p) {
*p &= 0;
}
}
in = t;
return true;
}
bool inSameCidrBlock(const std::string& ip1, const std::string& ip2, int bits)
{
struct in_addr in1;
struct in_addr in2;
if(!getCidrPrefix(in1, ip1, bits) || !getCidrPrefix(in2, ip2, bits)) {
return false;
}
return in1.s_addr == in2.s_addr;
}
} // namespace util
} // namespace aria2

View File

@ -382,6 +382,13 @@ bool detectDirTraversal(const std::string& s);
// '_': '"', '*', ':', '<', '>', '?', '\', '|'.
std::string escapePath(const std::string& s);
// Stores network address of numeric IPv4 address ip using CIDR bits
// into in. On success, returns true. Otherwise returns false.
bool getCidrPrefix(struct in_addr& in, const std::string& ip, int bits);
// Returns true if ip1 and ip2 are in the same CIDR block.
bool inSameCidrBlock(const std::string& ip1, const std::string& ip2, int bits);
} // namespace util
} // namespace aria2

View File

@ -63,6 +63,8 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testIsNumericHost);
CPPUNIT_TEST(testDetectDirTraversal);
CPPUNIT_TEST(testEscapePath);
CPPUNIT_TEST(testGetCidrPrefix);
CPPUNIT_TEST(testInSameCidrBlock);
CPPUNIT_TEST_SUITE_END();
private:
@ -114,6 +116,8 @@ public:
void testIsNumericHost();
void testDetectDirTraversal();
void testEscapePath();
void testGetCidrPrefix();
void testInSameCidrBlock();
};
@ -1064,4 +1068,34 @@ void UtilTest::testEscapePath()
#endif // !__MINGW32__
}
void UtilTest::testGetCidrPrefix()
{
struct in_addr in;
CPPUNIT_ASSERT(util::getCidrPrefix(in, "192.168.0.1", 16));
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.0"), std::string(inet_ntoa(in)));
CPPUNIT_ASSERT(util::getCidrPrefix(in, "192.168.255.255", 17));
CPPUNIT_ASSERT_EQUAL(std::string("192.168.128.0"),std::string(inet_ntoa(in)));
CPPUNIT_ASSERT(util::getCidrPrefix(in, "192.168.128.1", 16));
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.0"), std::string(inet_ntoa(in)));
CPPUNIT_ASSERT(util::getCidrPrefix(in, "192.168.0.1", 32));
CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), std::string(inet_ntoa(in)));
CPPUNIT_ASSERT(util::getCidrPrefix(in, "192.168.0.1", 0));
CPPUNIT_ASSERT_EQUAL(std::string("0.0.0.0"), std::string(inet_ntoa(in)));
CPPUNIT_ASSERT(util::getCidrPrefix(in, "10.10.1.44", 27));
CPPUNIT_ASSERT_EQUAL(std::string("10.10.1.32"), std::string(inet_ntoa(in)));
CPPUNIT_ASSERT(!util::getCidrPrefix(in, "::1", 32));
}
void UtilTest::testInSameCidrBlock()
{
CPPUNIT_ASSERT(util::inSameCidrBlock("192.168.128.1", "192.168.0.1", 16));
CPPUNIT_ASSERT(!util::inSameCidrBlock("192.168.128.1", "192.168.0.1", 17));
}
} // namespace aria2

View File

@ -56,6 +56,8 @@ void bitfieldTest::testCountSetBit()
void bitfieldTest::testLastByteMask()
{
CPPUNIT_ASSERT_EQUAL((unsigned int)0,
(unsigned int)bitfield::lastByteMask(0));
CPPUNIT_ASSERT_EQUAL((unsigned int)128,
(unsigned int)bitfield::lastByteMask(9));
CPPUNIT_ASSERT_EQUAL((unsigned int)240,