summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/net_util.cc17
-rw-r--r--net/base/net_util.h8
-rw-r--r--net/base/net_util_unittest.cc15
-rw-r--r--net/proxy/proxy_bypass_rules.cc13
-rw-r--r--net/proxy/proxy_server.cc10
5 files changed, 47 insertions, 16 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 704add2..d63dfe8 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -376,6 +376,23 @@ bool ParseHostAndPort(std::string::const_iterator host_and_port_begin,
if (port_component.len == 0)
return false; // Reject inputs like "foo:"
+ unsigned char tmp_ipv6_addr[16];
+
+ // If the hostname starts with a bracket, it is either an IPv6 literal or
+ // invalid. If it is an IPv6 literal then strip the brackets.
+ if (hostname_component.len > 0 &&
+ auth_begin[hostname_component.begin] == '[') {
+ if (auth_begin[hostname_component.end() - 1] == ']' &&
+ url::IPv6AddressToNumber(
+ auth_begin, hostname_component, tmp_ipv6_addr)) {
+ // Strip the brackets.
+ hostname_component.begin++;
+ hostname_component.len -= 2;
+ } else {
+ return false;
+ }
+ }
+
// Pass results back to caller.
host->assign(auth_begin + hostname_component.begin, hostname_component.len);
*port = parsed_port_number;
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 49780e8..8420cb3 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -81,8 +81,12 @@ NET_EXPORT_PRIVATE extern size_t GetCountOfExplicitlyAllowedPorts();
// Saves the result into |*host| and |*port|. If the input did not have
// the optional port, sets |*port| to -1.
// Returns true if the parsing was successful, false otherwise.
-// The returned host is NOT canonicalized, and may be invalid. If <host> is
-// an IPv6 literal address, the returned host includes the square brackets.
+// The returned host is NOT canonicalized, and may be invalid.
+//
+// IPv6 literals must be specified in a bracketed form, for instance:
+// [::1]:90 and [::1]
+//
+// The resultant |*host| in both cases will be "::1" (not bracketed).
NET_EXPORT bool ParseHostAndPort(
std::string::const_iterator host_and_port_begin,
std::string::const_iterator host_and_port_end,
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 3bb518f..5ef1d49 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -246,9 +246,20 @@ TEST(NetUtilTest, ParseHostAndPort) {
{
"[1080:0:0:0:8:800:200C:4171]:11",
true,
+ "1080:0:0:0:8:800:200C:4171",
+ 11
+ },
+ {
"[1080:0:0:0:8:800:200C:4171]",
- 11,
+ true,
+ "1080:0:0:0:8:800:200C:4171",
+ -1
},
+
+ // Because no validation is done on the host, the following are accepted,
+ // even though they are invalid names.
+ {"]", true, "]", -1},
+ {"::1", true, ":", 1},
// Invalid inputs:
{"foo:bar", false, "", -1},
{"foo:", false, "", -1},
@@ -262,6 +273,8 @@ TEST(NetUtilTest, ParseHostAndPort) {
{":password@host:80", false, "", -1},
{":password@host", false, "", -1},
{"@host", false, "", -1},
+ {"[", false, "", -1},
+ {"[]", false, "", -1},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
diff --git a/net/proxy/proxy_bypass_rules.cc b/net/proxy/proxy_bypass_rules.cc
index 6bf1c61..239a2fe 100644
--- a/net/proxy/proxy_bypass_rules.cc
+++ b/net/proxy/proxy_bypass_rules.cc
@@ -6,10 +6,11 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "net/base/host_port_pair.h"
#include "net/base/net_util.h"
namespace net {
@@ -131,6 +132,7 @@ class BypassIPBlockRule : public ProxyBypassRules::Rule {
};
// Returns true if the given string represents an IP address.
+// IPv6 addresses are expected to be bracketed.
bool IsIPAddress(const std::string& domain) {
// From GURL::HostIsIPAddress()
url::RawCanonOutputT<char, 128> ignored_output;
@@ -305,9 +307,12 @@ bool ProxyBypassRules::AddRuleFromStringInternal(
std::string host;
int port;
if (ParseHostAndPort(raw, &host, &port)) {
- if (IsIPAddress(host)) {
+ // Note that HostPortPair is used to merely to convert any IPv6 literals to
+ // a URL-safe format that can be used by canonicalization below.
+ std::string bracketed_host = HostPortPair(host, 80).HostForURL();
+ if (IsIPAddress(bracketed_host)) {
// Canonicalize the IP literal before adding it as a string pattern.
- GURL tmp_url("http://" + host);
+ GURL tmp_url("http://" + bracketed_host);
return AddRuleForHostname(scheme, tmp_url.host(), port);
}
}
diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc
index d74a89f0..0b9ba67 100644
--- a/net/proxy/proxy_server.cc
+++ b/net/proxy/proxy_server.cc
@@ -64,14 +64,6 @@ ProxyServer::Scheme GetSchemeFromURIInternal(std::string::const_iterator begin,
return ProxyServer::SCHEME_INVALID;
}
-std::string HostNoBrackets(const std::string& host) {
- // Remove brackets from an RFC 2732-style IPv6 literal address.
- const std::string::size_type len = host.size();
- if (len >= 2 && host[0] == '[' && host[len - 1] == ']')
- return host.substr(1, len - 2);
- return host;
-}
-
} // namespace
ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair)
@@ -246,7 +238,7 @@ ProxyServer ProxyServer::FromSchemeHostAndPort(
if (port == -1)
port = GetDefaultPortForScheme(scheme);
- host_port_pair = HostPortPair(HostNoBrackets(host), port);
+ host_port_pair = HostPortPair(host, port);
}
return ProxyServer(scheme, host_port_pair);