summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/net_util.cc57
-rw-r--r--net/base/net_util.h2
-rw-r--r--net/base/net_util_unittest.cc13
3 files changed, 42 insertions, 30 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index a1b4b73..5c042d1 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -965,37 +965,44 @@ bool GetHostAndPort(std::string::const_iterator host_and_port_begin,
if (host_and_port_begin >= host_and_port_end)
return false;
- // TODO(eroman): support IPv6 literals.
- std::string::const_iterator colon =
- std::find(host_and_port_begin, host_and_port_end, ':');
-
- if (colon == host_and_port_end) {
- // No colon.
- host->assign(host_and_port_begin, host_and_port_end);
- *port = -1;
- return true;
- }
+ // When using url_parse, we use char*.
+ const char* auth_begin = &(*host_and_port_begin);
+ int auth_len = host_and_port_end - host_and_port_begin;
- if (colon == host_and_port_begin)
- return false; // No host.
+ url_parse::Component auth_component(0, auth_len);
+ url_parse::Component username_component;
+ url_parse::Component password_component;
+ url_parse::Component hostname_component;
+ url_parse::Component port_component;
- if (colon == host_and_port_end - 1)
- return false; // There is nothing past the colon.
+ url_parse::ParseAuthority(auth_begin, auth_component, &username_component,
+ &password_component, &hostname_component, &port_component);
- // Parse the port number to an integer.
- std::string port_string(colon + 1, host_and_port_end);
- int parsed_port_number = url_parse::ParsePort(port_string.data(),
- url_parse::Component(0, port_string.size()));
+ // There shouldn't be a username/password.
+ if (username_component.is_valid() || password_component.is_valid())
+ return false;
- // If parsing failed, port_number will be either PORT_INVALID or
- // PORT_UNSPECIFIED, both of which are negative.
- if (parsed_port_number < 0)
- return false; // Failed parsing the port number.
+ if (!hostname_component.is_nonempty())
+ return false; // Failed parsing.
- // Else successfully parsed port number.
+ int parsed_port_number = -1;
+ if (port_component.is_nonempty()) {
+ parsed_port_number = url_parse::ParsePort(auth_begin, port_component);
+
+ // If parsing failed, port_number will be either PORT_INVALID or
+ // PORT_UNSPECIFIED, both of which are negative.
+ if (parsed_port_number < 0)
+ return false; // Failed parsing the port number.
+ }
+
+ if (port_component.len == 0)
+ return false; // Reject inputs like "foo:"
+
+ // Pass results back to caller.
+ host->assign(auth_begin + hostname_component.begin, hostname_component.len);
*port = parsed_port_number;
- host->assign(host_and_port_begin, colon);
- return true;
+
+ return true; // Success.
}
bool GetHostAndPort(const std::string& host_and_port,
diff --git a/net/base/net_util.h b/net/base/net_util.h
index e62e95a..1fda9bd 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -44,7 +44,7 @@ bool FileURLToFilePath(const GURL& url, std::wstring* file_path);
// 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.
-// TODO(eroman): support IPv6 literals.
+// The returned host is NOT canonicalized, and may be invalid.
bool GetHostAndPort(std::string::const_iterator host_and_port_begin,
std::string::const_iterator host_and_port_end,
std::string* host,
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index d3f7b83..c83d510 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -747,11 +747,10 @@ TEST(NetUtilTest, GetHostAndPort) {
{"foo:10", true, "foo", 10},
{"foo", true, "foo", -1},
{
- // TODO(eroman): support IPv6 literals.
"[1080:0:0:0:8:800:200C:4171]:11",
- false,
- "",
- -1,
+ true,
+ "[1080:0:0:0:8:800:200C:4171]",
+ 11,
},
// Invalid inputs:
{"foo:bar", false, "", -1},
@@ -760,6 +759,12 @@ TEST(NetUtilTest, GetHostAndPort) {
{":80", false, "", -1},
{"", false, "", -1},
{"porttoolong:300000", false, "", -1},
+ {"usrname@host", false, "", -1},
+ {"usrname:password@host", false, "", -1},
+ {":password@host", false, "", -1},
+ {":password@host:80", false, "", -1},
+ {":password@host", false, "", -1},
+ {"@host", false, "", -1},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {