diff options
author | tfarina <tfarina@chromium.org> | 2016-01-20 06:23:44 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-20 14:24:45 +0000 |
commit | 7a4a7fd42bbe342f02afef28035ea237baddffd9 (patch) | |
tree | 6bf5c1892035d69b44cbf1f5b02e532d94b41c33 /net | |
parent | ef7ee132097748158460014e336036adddeec2a5 (diff) | |
download | chromium_src-7a4a7fd42bbe342f02afef28035ea237baddffd9.zip chromium_src-7a4a7fd42bbe342f02afef28035ea237baddffd9.tar.gz chromium_src-7a4a7fd42bbe342f02afef28035ea237baddffd9.tar.bz2 |
net: move more functions out of net_util.h
This moves everything except IsHostnameNonUnique(), GetHostName(),
ResolveLocalHostname() and IsLocalhost() out of net_util.h,
moving them into url_util.h.
We will discuss what to do with the remaining 4 functions in a
separate CL.
BUG=488531
TEST=net_unittests
R=eroman@chromium.org
TBR=darin@chromium.org
Review URL: https://codereview.chromium.org/1585773008
Cr-Commit-Position: refs/heads/master@{#370385}
Diffstat (limited to 'net')
-rw-r--r-- | net/base/host_mapping_rules.cc | 2 | ||||
-rw-r--r-- | net/base/net_util.cc | 198 | ||||
-rw-r--r-- | net/base/net_util.h | 61 | ||||
-rw-r--r-- | net/base/net_util_unittest.cc | 222 | ||||
-rw-r--r-- | net/base/registry_controlled_domains/registry_controlled_domain.cc | 2 | ||||
-rw-r--r-- | net/base/url_util.cc | 189 | ||||
-rw-r--r-- | net/base/url_util.h | 58 | ||||
-rw-r--r-- | net/base/url_util_unittest.cc | 223 | ||||
-rw-r--r-- | net/cert/cert_verify_proc.cc | 1 | ||||
-rw-r--r-- | net/cert/x509_certificate.cc | 2 | ||||
-rw-r--r-- | net/cookies/cookie_util.cc | 2 | ||||
-rw-r--r-- | net/http/http_auth_handler_digest.cc | 2 | ||||
-rw-r--r-- | net/http/http_auth_handler_ntlm.cc | 2 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 2 | ||||
-rw-r--r-- | net/http/http_util_icu.cc | 2 | ||||
-rw-r--r-- | net/proxy/proxy_bypass_rules.cc | 2 | ||||
-rw-r--r-- | net/proxy/proxy_server.cc | 2 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 2 | ||||
-rw-r--r-- | net/quic/crypto/crypto_utils.cc | 2 | ||||
-rw-r--r-- | net/spdy/spdy_http_utils.cc | 2 | ||||
-rw-r--r-- | net/tools/gdig/gdig.cc | 2 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.cc | 2 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.cc | 2 |
23 files changed, 488 insertions, 496 deletions
diff --git a/net/base/host_mapping_rules.cc b/net/base/host_mapping_rules.cc index 5e60425..3c24b24 100644 --- a/net/base/host_mapping_rules.cc +++ b/net/base/host_mapping_rules.cc @@ -10,7 +10,7 @@ #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "net/base/host_port_pair.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" namespace net { diff --git a/net/base/net_util.cc b/net/base/net_util.cc index f89cc99..a539110 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -4,34 +4,19 @@ #include "net/base/net_util.h" -#include <algorithm> -#include <string> - #include "build/build_config.h" -#if defined(OS_WIN) -#include <windows.h> -#include <iphlpapi.h> -#include <winsock2.h> -#pragma comment(lib, "iphlpapi.lib") -#elif defined(OS_POSIX) -#include <fcntl.h> -#include <netdb.h> +#if defined(OS_POSIX) #include <unistd.h> -#endif // defined(OS_POSIX) +#endif #include "base/logging.h" #include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/sys_byteorder.h" #include "net/base/address_list.h" #include "net/base/ip_address_number.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/url_util.h" #include "url/gurl.h" -#include "url/third_party/mozilla/url_parse.h" -#include "url/url_canon.h" #include "url/url_canon_ip.h" #if defined(OS_WIN) @@ -66,146 +51,6 @@ bool IsLocal6Hostname(const std::string& host) { } // namespace -std::string CanonicalizeHost(const std::string& host, - url::CanonHostInfo* host_info) { - // Try to canonicalize the host. - const url::Component raw_host_component(0, static_cast<int>(host.length())); - std::string canon_host; - url::StdStringCanonOutput canon_host_output(&canon_host); - url::CanonicalizeHostVerbose(host.c_str(), raw_host_component, - &canon_host_output, host_info); - - if (host_info->out_host.is_nonempty() && - host_info->family != url::CanonHostInfo::BROKEN) { - // Success! Assert that there's no extra garbage. - canon_host_output.Complete(); - DCHECK_EQ(host_info->out_host.len, static_cast<int>(canon_host.length())); - } else { - // Empty host, or canonicalization failed. We'll return empty. - canon_host.clear(); - } - - return canon_host; -} - -inline bool IsHostCharAlphanumeric(char c) { - // We can just check lowercase because uppercase characters have already been - // normalized. - return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')); -} - -bool IsCanonicalizedHostCompliant(const std::string& host) { - if (host.empty()) - return false; - - bool in_component = false; - bool most_recent_component_started_alphanumeric = false; - - for (std::string::const_iterator i(host.begin()); i != host.end(); ++i) { - const char c = *i; - if (!in_component) { - most_recent_component_started_alphanumeric = IsHostCharAlphanumeric(c); - if (!most_recent_component_started_alphanumeric && (c != '-') && - (c != '_')) { - return false; - } - in_component = true; - } else if (c == '.') { - in_component = false; - } else if (!IsHostCharAlphanumeric(c) && (c != '-') && (c != '_')) { - return false; - } - } - - return most_recent_component_started_alphanumeric; -} - -bool ParseHostAndPort(std::string::const_iterator host_and_port_begin, - std::string::const_iterator host_and_port_end, - std::string* host, - int* port) { - if (host_and_port_begin >= host_and_port_end) - return false; - - // When using url, we use char*. - const char* auth_begin = &(*host_and_port_begin); - int auth_len = host_and_port_end - host_and_port_begin; - - url::Component auth_component(0, auth_len); - url::Component username_component; - url::Component password_component; - url::Component hostname_component; - url::Component port_component; - - url::ParseAuthority(auth_begin, auth_component, &username_component, - &password_component, &hostname_component, &port_component); - - // There shouldn't be a username/password. - if (username_component.is_valid() || password_component.is_valid()) - return false; - - if (!hostname_component.is_nonempty()) - return false; // Failed parsing. - - int parsed_port_number = -1; - if (port_component.is_nonempty()) { - parsed_port_number = url::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:" - - 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; - - return true; // Success. -} - -bool ParseHostAndPort(const std::string& host_and_port, - std::string* host, - int* port) { - return ParseHostAndPort( - host_and_port.begin(), host_and_port.end(), host, port); -} - -std::string GetHostAndPort(const GURL& url) { - // For IPv6 literals, GURL::host() already includes the brackets so it is - // safe to just append a colon. - return base::StringPrintf("%s:%d", url.host().c_str(), - url.EffectiveIntPort()); -} - -std::string GetHostAndOptionalPort(const GURL& url) { - // For IPv6 literals, GURL::host() already includes the brackets - // so it is safe to just append a colon. - if (url.has_port()) - return base::StringPrintf("%s:%s", url.host().c_str(), url.port().c_str()); - return url.host(); -} - bool IsHostnameNonUnique(const std::string& hostname) { // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. const std::string host_or_ip = hostname.find(':') != std::string::npos ? @@ -272,19 +117,6 @@ std::string GetHostName() { #endif // !defined(OS_NACL) } -std::string GetHostOrSpecFromURL(const GURL& url) { - return url.has_host() ? TrimEndingDot(url.host_piece()) : url.spec(); -} - -GURL SimplifyUrlForRequest(const GURL& url) { - DCHECK(url.is_valid()); - GURL::Replacements replacements; - replacements.ClearUsername(); - replacements.ClearPassword(); - replacements.ClearRef(); - return url.ReplaceComponents(replacements); -} - bool ResolveLocalHostname(base::StringPiece host, uint16_t port, AddressList* address_list) { @@ -346,30 +178,4 @@ bool IsLocalhost(base::StringPiece host) { return false; } -bool HasGoogleHost(const GURL& url) { - static const char* kGoogleHostSuffixes[] = { - ".google.com", - ".youtube.com", - ".gmail.com", - ".doubleclick.net", - ".gstatic.com", - ".googlevideo.com", - ".googleusercontent.com", - ".googlesyndication.com", - ".google-analytics.com", - ".googleadservices.com", - ".googleapis.com", - ".ytimg.com", - }; - base::StringPiece host = url.host_piece(); - for (const char* suffix : kGoogleHostSuffixes) { - // Here it's possible to get away with faster case-sensitive comparisons - // because the list above is all lowercase, and a GURL's host name will - // always be canonicalized to lowercase as well. - if (base::EndsWith(host, suffix, base::CompareCase::SENSITIVE)) - return true; - } - return false; -} - } // namespace net diff --git a/net/base/net_util.h b/net/base/net_util.h index 1bf6510..f227ce9 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -9,48 +9,16 @@ #include <stdint.h> #include <string> -#include <vector> #include "base/strings/string_piece.h" #include "net/base/net_export.h" class GURL; -namespace url { -struct CanonHostInfo; -} - namespace net { class AddressList; -// Splits an input of the form <host>[":"<port>] into its consitituent parts. -// 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. -// -// 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, - std::string* host, - int* port); -NET_EXPORT bool ParseHostAndPort( - const std::string& host_and_port, - std::string* host, - int* port); - -// Returns a host:port string for the given URL. -NET_EXPORT std::string GetHostAndPort(const GURL& url); - -// Returns a host[:port] string for the given URL, where the port is omitted -// if it is the default for the URL's scheme. -NET_EXPORT std::string GetHostAndOptionalPort(const GURL& url); - // Returns true if |hostname| contains a non-registerable or non-assignable // domain name (eg: a gTLD that has not been assigned by IANA) or an IP address // that falls in an IANA-reserved range. @@ -59,31 +27,6 @@ NET_EXPORT bool IsHostnameNonUnique(const std::string& hostname); // Returns the hostname of the current system. Returns empty string on failure. NET_EXPORT std::string GetHostName(); -// Returns either the host from |url|, or, if the host is empty, the full spec. -NET_EXPORT std::string GetHostOrSpecFromURL(const GURL& url); - -// Canonicalizes |host| and returns it. Also fills |host_info| with -// IP address information. |host_info| must not be NULL. -NET_EXPORT std::string CanonicalizeHost(const std::string& host, - url::CanonHostInfo* host_info); - -// Returns true if |host| is not an IP address and is compliant with a set of -// rules based on RFC 1738 and tweaked to be compatible with the real world. -// The rules are: -// * One or more components separated by '.' -// * Each component contains only alphanumeric characters and '-' or '_' -// * The last component begins with an alphanumeric character -// * Optional trailing dot after last component (means "treat as FQDN") -// -// NOTE: You should only pass in hosts that have been returned from -// CanonicalizeHost(), or you may not get accurate results. -NET_EXPORT bool IsCanonicalizedHostCompliant(const std::string& host); - -// Strip the portions of |url| that aren't core to the network request. -// - user name / password -// - reference section -NET_EXPORT GURL SimplifyUrlForRequest(const GURL& url); - // Resolves a local hostname (such as "localhost" or "localhost6") into // IP endpoints with the given port. Returns true if |host| is a local // hostname and false otherwise. Special IPv6 names (e.g. "localhost6") @@ -101,10 +44,6 @@ NET_EXPORT_PRIVATE bool ResolveLocalHostname(base::StringPiece host, // machine. NET_EXPORT bool IsLocalhost(base::StringPiece host); -// Returns true if the url's host is a Google server. This should only be used -// for histograms and shouldn't be used to affect behavior. -NET_EXPORT_PRIVATE bool HasGoogleHost(const GURL& url); - } // namespace net #endif // NET_BASE_NET_UTIL_H_ diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc index b92244a..fcffc59 100644 --- a/net/base/net_util_unittest.cc +++ b/net/base/net_util_unittest.cc @@ -78,139 +78,6 @@ void TestIPv6LoopbackOnly(const std::string& host) { } // anonymous namespace -TEST(NetUtilTest, CompliantHost) { - struct { - const char* const host; - bool expected_output; - } compliant_host_cases[] = { - {"", false}, - {"a", true}, - {"-", false}, - {"_", false}, - {".", false}, - {"9", true}, - {"9a", true}, - {"9_", true}, - {"a.", true}, - {"a.a", true}, - {"9.a", true}, - {"a.9", true}, - {"_9a", false}, - {"-9a", false}, - {"a.a9", true}, - {"_.9a", true}, - {"a.-a9", false}, - {"a+9a", false}, - {"-a.a9", true}, - {"a_.a9", true}, - {"1-.a-b", true}, - {"1_.a-b", true}, - {"1-2.a_b", true}, - {"a.b.c.d.e", true}, - {"1.2.3.4.5", true}, - {"1.2.3.4.5.", true}, - }; - - for (size_t i = 0; i < arraysize(compliant_host_cases); ++i) { - EXPECT_EQ(compliant_host_cases[i].expected_output, - IsCanonicalizedHostCompliant(compliant_host_cases[i].host)); - } -} - -TEST(NetUtilTest, ParseHostAndPort) { - const struct { - const char* const input; - bool success; - const char* const expected_host; - int expected_port; - } tests[] = { - // Valid inputs: - {"foo:10", true, "foo", 10}, - {"foo", true, "foo", -1}, - { - "[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]", - 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}, - {":", false, "", -1}, - {":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}, - {"[", false, "", -1}, - {"[]", false, "", -1}, - }; - - for (size_t i = 0; i < arraysize(tests); ++i) { - std::string host; - int port; - bool ok = ParseHostAndPort(tests[i].input, &host, &port); - - EXPECT_EQ(tests[i].success, ok); - - if (tests[i].success) { - EXPECT_EQ(tests[i].expected_host, host); - EXPECT_EQ(tests[i].expected_port, port); - } - } -} - -TEST(NetUtilTest, GetHostAndPort) { - const struct { - GURL url; - const char* const expected_host_and_port; - } tests[] = { - { GURL("http://www.foo.com/x"), "www.foo.com:80"}, - { GURL("http://www.foo.com:21/x"), "www.foo.com:21"}, - - // For IPv6 literals should always include the brackets. - { GURL("http://[1::2]/x"), "[1::2]:80"}, - { GURL("http://[::a]:33/x"), "[::a]:33"}, - }; - for (size_t i = 0; i < arraysize(tests); ++i) { - std::string host_and_port = GetHostAndPort(tests[i].url); - EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); - } -} - -TEST(NetUtilTest, GetHostAndOptionalPort) { - const struct { - GURL url; - const char* const expected_host_and_port; - } tests[] = { - { GURL("http://www.foo.com/x"), "www.foo.com"}, - { GURL("http://www.foo.com:21/x"), "www.foo.com:21"}, - - // For IPv6 literals should always include the brackets. - { GURL("http://[1::2]/x"), "[1::2]"}, - { GURL("http://[::a]:33/x"), "[::a]:33"}, - }; - for (size_t i = 0; i < arraysize(tests); ++i) { - std::string host_and_port = GetHostAndOptionalPort(tests[i].url); - EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); - } -} - TEST(NetUtilTest, GetHostName) { // We can't check the result of GetHostName() directly, since the result // will differ across machines. Our goal here is to simply exercise the @@ -219,60 +86,6 @@ TEST(NetUtilTest, GetHostName) { EXPECT_FALSE(hostname.empty()); } -TEST(NetUtilTest, SimplifyUrlForRequest) { - struct { - const char* const input_url; - const char* const expected_simplified_url; - } tests[] = { - { - // Reference section should be stripped. - "http://www.google.com:78/foobar?query=1#hash", - "http://www.google.com:78/foobar?query=1", - }, - { - // Reference section can itself contain #. - "http://192.168.0.1?query=1#hash#10#11#13#14", - "http://192.168.0.1?query=1", - }, - { // Strip username/password. - "http://user:pass@google.com", - "http://google.com/", - }, - { // Strip both the reference and the username/password. - "http://user:pass@google.com:80/sup?yo#X#X", - "http://google.com/sup?yo", - }, - { // Try an HTTPS URL -- strip both the reference and the username/password. - "https://user:pass@google.com:80/sup?yo#X#X", - "https://google.com:80/sup?yo", - }, - { // Try an FTP URL -- strip both the reference and the username/password. - "ftp://user:pass@google.com:80/sup?yo#X#X", - "ftp://google.com:80/sup?yo", - }, - { // Try a nonstandard URL - "foobar://user:pass@google.com:80/sup?yo#X#X", - "foobar://user:pass@google.com:80/sup?yo", - }, - }; - for (size_t i = 0; i < arraysize(tests); ++i) { - SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, - tests[i].input_url)); - GURL input_url(GURL(tests[i].input_url)); - GURL expected_url(GURL(tests[i].expected_simplified_url)); - EXPECT_EQ(expected_url, SimplifyUrlForRequest(input_url)); - } -} - -TEST(NetUtilTest, GetHostOrSpecFromURL) { - EXPECT_EQ("example.com", - GetHostOrSpecFromURL(GURL("http://example.com/test"))); - EXPECT_EQ("example.com", - GetHostOrSpecFromURL(GURL("http://example.com./test"))); - EXPECT_EQ("file:///tmp/test.html", - GetHostOrSpecFromURL(GURL("file:///tmp/test.html"))); -} - TEST(NetUtilTest, IsLocalhost) { EXPECT_TRUE(IsLocalhost("localhost")); EXPECT_TRUE(IsLocalhost("localHosT")); @@ -375,41 +188,6 @@ TEST(NetUtilTest, ResolveLocalHostname) { ResolveLocalHostname("foo.localhoste", kLocalhostLookupPort, &addresses)); } -TEST(NetUtilTest, GoogleHost) { - struct { - GURL url; - bool expected_output; - } google_host_cases[] = { - {GURL("http://.google.com"), true}, - {GURL("http://.youtube.com"), true}, - {GURL("http://.gmail.com"), true}, - {GURL("http://.doubleclick.net"), true}, - {GURL("http://.gstatic.com"), true}, - {GURL("http://.googlevideo.com"), true}, - {GURL("http://.googleusercontent.com"), true}, - {GURL("http://.googlesyndication.com"), true}, - {GURL("http://.google-analytics.com"), true}, - {GURL("http://.googleadservices.com"), true}, - {GURL("http://.googleapis.com"), true}, - {GURL("http://a.google.com"), true}, - {GURL("http://b.youtube.com"), true}, - {GURL("http://c.gmail.com"), true}, - {GURL("http://google.com"), false}, - {GURL("http://youtube.com"), false}, - {GURL("http://gmail.com"), false}, - {GURL("http://google.coma"), false}, - {GURL("http://agoogle.com"), false}, - {GURL("http://oogle.com"), false}, - {GURL("http://google.co"), false}, - {GURL("http://oggole.com"), false}, - }; - - for (size_t i = 0; i < arraysize(google_host_cases); ++i) { - EXPECT_EQ(google_host_cases[i].expected_output, - HasGoogleHost(google_host_cases[i].url)); - } -} - struct NonUniqueNameTestData { bool is_unique; const char* const hostname; diff --git a/net/base/registry_controlled_domains/registry_controlled_domain.cc b/net/base/registry_controlled_domains/registry_controlled_domain.cc index 7e62316..e2a70c3 100644 --- a/net/base/registry_controlled_domains/registry_controlled_domain.cc +++ b/net/base/registry_controlled_domains/registry_controlled_domain.cc @@ -50,7 +50,7 @@ #include "base/strings/utf_string_conversions.h" #include "net/base/lookup_string_in_fixed_set.h" #include "net/base/net_module.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "url/gurl.h" #include "url/third_party/mozilla/url_parse.h" diff --git a/net/base/url_util.cc b/net/base/url_util.cc index a581807..913fe91 100644 --- a/net/base/url_util.cc +++ b/net/base/url_util.cc @@ -5,11 +5,26 @@ #include "net/base/url_util.h" #include "base/logging.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "net/base/escape.h" #include "url/gurl.h" +#include "url/third_party/mozilla/url_parse.h" +#include "url/url_canon.h" +#include "url/url_canon_ip.h" namespace net { +namespace { + +bool IsHostCharAlphanumeric(char c) { + // We can just check lowercase because uppercase characters have already been + // normalized. + return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')); +} + +} // namespace + GURL AppendQueryParameter(const GURL& url, const std::string& name, const std::string& value) { @@ -129,6 +144,93 @@ bool GetValueForKeyInQuery(const GURL& url, return false; } +bool ParseHostAndPort(std::string::const_iterator host_and_port_begin, + std::string::const_iterator host_and_port_end, + std::string* host, + int* port) { + if (host_and_port_begin >= host_and_port_end) + return false; + + // When using url, we use char*. + const char* auth_begin = &(*host_and_port_begin); + int auth_len = host_and_port_end - host_and_port_begin; + + url::Component auth_component(0, auth_len); + url::Component username_component; + url::Component password_component; + url::Component hostname_component; + url::Component port_component; + + url::ParseAuthority(auth_begin, auth_component, &username_component, + &password_component, &hostname_component, &port_component); + + // There shouldn't be a username/password. + if (username_component.is_valid() || password_component.is_valid()) + return false; + + if (!hostname_component.is_nonempty()) + return false; // Failed parsing. + + int parsed_port_number = -1; + if (port_component.is_nonempty()) { + parsed_port_number = url::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:" + + 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; + + return true; // Success. +} + +bool ParseHostAndPort(const std::string& host_and_port, + std::string* host, + int* port) { + return ParseHostAndPort( + host_and_port.begin(), host_and_port.end(), host, port); +} + + +std::string GetHostAndPort(const GURL& url) { + // For IPv6 literals, GURL::host() already includes the brackets so it is + // safe to just append a colon. + return base::StringPrintf("%s:%d", url.host().c_str(), + url.EffectiveIntPort()); +} + +std::string GetHostAndOptionalPort(const GURL& url) { + // For IPv6 literals, GURL::host() already includes the brackets + // so it is safe to just append a colon. + if (url.has_port()) + return base::StringPrintf("%s:%s", url.host().c_str(), url.port().c_str()); + return url.host(); +} + std::string TrimEndingDot(const base::StringPiece& host) { base::StringPiece host_trimmed = host; size_t len = host_trimmed.length(); @@ -138,6 +240,67 @@ std::string TrimEndingDot(const base::StringPiece& host) { return host_trimmed.as_string(); } +std::string GetHostOrSpecFromURL(const GURL& url) { + return url.has_host() ? TrimEndingDot(url.host_piece()) : url.spec(); +} + +std::string CanonicalizeHost(const std::string& host, + url::CanonHostInfo* host_info) { + // Try to canonicalize the host. + const url::Component raw_host_component(0, static_cast<int>(host.length())); + std::string canon_host; + url::StdStringCanonOutput canon_host_output(&canon_host); + url::CanonicalizeHostVerbose(host.c_str(), raw_host_component, + &canon_host_output, host_info); + + if (host_info->out_host.is_nonempty() && + host_info->family != url::CanonHostInfo::BROKEN) { + // Success! Assert that there's no extra garbage. + canon_host_output.Complete(); + DCHECK_EQ(host_info->out_host.len, static_cast<int>(canon_host.length())); + } else { + // Empty host, or canonicalization failed. We'll return empty. + canon_host.clear(); + } + + return canon_host; +} + +bool IsCanonicalizedHostCompliant(const std::string& host) { + if (host.empty()) + return false; + + bool in_component = false; + bool most_recent_component_started_alphanumeric = false; + + for (std::string::const_iterator i(host.begin()); i != host.end(); ++i) { + const char c = *i; + if (!in_component) { + most_recent_component_started_alphanumeric = IsHostCharAlphanumeric(c); + if (!most_recent_component_started_alphanumeric && (c != '-') && + (c != '_')) { + return false; + } + in_component = true; + } else if (c == '.') { + in_component = false; + } else if (!IsHostCharAlphanumeric(c) && (c != '-') && (c != '_')) { + return false; + } + } + + return most_recent_component_started_alphanumeric; +} + +GURL SimplifyUrlForRequest(const GURL& url) { + DCHECK(url.is_valid()); + GURL::Replacements replacements; + replacements.ClearUsername(); + replacements.ClearPassword(); + replacements.ClearRef(); + return url.ReplaceComponents(replacements); +} + void GetIdentityFromURL(const GURL& url, base::string16* username, base::string16* password) { @@ -147,4 +310,30 @@ void GetIdentityFromURL(const GURL& url, *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags); } +bool HasGoogleHost(const GURL& url) { + static const char* kGoogleHostSuffixes[] = { + ".google.com", + ".youtube.com", + ".gmail.com", + ".doubleclick.net", + ".gstatic.com", + ".googlevideo.com", + ".googleusercontent.com", + ".googlesyndication.com", + ".google-analytics.com", + ".googleadservices.com", + ".googleapis.com", + ".ytimg.com", + }; + base::StringPiece host = url.host_piece(); + for (const char* suffix : kGoogleHostSuffixes) { + // Here it's possible to get away with faster case-sensitive comparisons + // because the list above is all lowercase, and a GURL's host name will + // always be canonicalized to lowercase as well. + if (base::EndsWith(host, suffix, base::CompareCase::SENSITIVE)) + return true; + } + return false; +} + } // namespace net diff --git a/net/base/url_util.h b/net/base/url_util.h index 239a93c..d4a7eef 100644 --- a/net/base/url_util.h +++ b/net/base/url_util.h @@ -15,6 +15,10 @@ class GURL; +namespace url { +struct CanonHostInfo; +} + namespace net { // Returns a new GURL by appending the given query parameter name and the @@ -79,16 +83,70 @@ NET_EXPORT bool GetValueForKeyInQuery(const GURL& url, const std::string& search_key, std::string* out_value); +// Splits an input of the form <host>[":"<port>] into its consitituent parts. +// 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. +// +// 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, + std::string* host, + int* port); +NET_EXPORT bool ParseHostAndPort(const std::string& host_and_port, + std::string* host, + int* port); + +// Returns a host:port string for the given URL. +NET_EXPORT std::string GetHostAndPort(const GURL& url); + +// Returns a host[:port] string for the given URL, where the port is omitted +// if it is the default for the URL's scheme. +NET_EXPORT std::string GetHostAndOptionalPort(const GURL& url); // Returns the hostname by trimming the ending dot, if one exists. NET_EXPORT std::string TrimEndingDot(const base::StringPiece& host); +// Returns either the host from |url|, or, if the host is empty, the full spec. +NET_EXPORT std::string GetHostOrSpecFromURL(const GURL& url); + +// Canonicalizes |host| and returns it. Also fills |host_info| with +// IP address information. |host_info| must not be NULL. +NET_EXPORT std::string CanonicalizeHost(const std::string& host, + url::CanonHostInfo* host_info); + +// Returns true if |host| is not an IP address and is compliant with a set of +// rules based on RFC 1738 and tweaked to be compatible with the real world. +// The rules are: +// * One or more components separated by '.' +// * Each component contains only alphanumeric characters and '-' or '_' +// * The last component begins with an alphanumeric character +// * Optional trailing dot after last component (means "treat as FQDN") +// +// NOTE: You should only pass in hosts that have been returned from +// CanonicalizeHost(), or you may not get accurate results. +NET_EXPORT bool IsCanonicalizedHostCompliant(const std::string& host); + +// Strip the portions of |url| that aren't core to the network request. +// - user name / password +// - reference section +NET_EXPORT GURL SimplifyUrlForRequest(const GURL& url); + // Extracts the unescaped username/password from |url|, saving the results // into |*username| and |*password|. NET_EXPORT_PRIVATE void GetIdentityFromURL(const GURL& url, base::string16* username, base::string16* password); +// Returns true if the url's host is a Google server. This should only be used +// for histograms and shouldn't be used to affect behavior. +NET_EXPORT_PRIVATE bool HasGoogleHost(const GURL& url); + } // namespace net #endif // NET_BASE_URL_UTIL_H_ diff --git a/net/base/url_util_unittest.cc b/net/base/url_util_unittest.cc index 863e552..8140e3a 100644 --- a/net/base/url_util_unittest.cc +++ b/net/base/url_util_unittest.cc @@ -165,7 +165,193 @@ TEST(UrlUtilTest, ParseQueryInvalidURL) { EXPECT_TRUE(it.IsAtEnd()); } -TEST(NetUtilTest, GetIdentityFromURL) { +TEST(UrlUtilTest, ParseHostAndPort) { + const struct { + const char* const input; + bool success; + const char* const expected_host; + int expected_port; + } tests[] = { + // Valid inputs: + {"foo:10", true, "foo", 10}, + {"foo", true, "foo", -1}, + { + "[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]", + 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}, + {":", false, "", -1}, + {":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}, + {"[", false, "", -1}, + {"[]", false, "", -1}, + }; + + for (size_t i = 0; i < arraysize(tests); ++i) { + std::string host; + int port; + bool ok = ParseHostAndPort(tests[i].input, &host, &port); + + EXPECT_EQ(tests[i].success, ok); + + if (tests[i].success) { + EXPECT_EQ(tests[i].expected_host, host); + EXPECT_EQ(tests[i].expected_port, port); + } + } +} +TEST(UrlUtilTest, GetHostAndPort) { + const struct { + GURL url; + const char* const expected_host_and_port; + } tests[] = { + { GURL("http://www.foo.com/x"), "www.foo.com:80"}, + { GURL("http://www.foo.com:21/x"), "www.foo.com:21"}, + + // For IPv6 literals should always include the brackets. + { GURL("http://[1::2]/x"), "[1::2]:80"}, + { GURL("http://[::a]:33/x"), "[::a]:33"}, + }; + for (size_t i = 0; i < arraysize(tests); ++i) { + std::string host_and_port = GetHostAndPort(tests[i].url); + EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); + } +} + +TEST(UrlUtilTest, GetHostAndOptionalPort) { + const struct { + GURL url; + const char* const expected_host_and_port; + } tests[] = { + { GURL("http://www.foo.com/x"), "www.foo.com"}, + { GURL("http://www.foo.com:21/x"), "www.foo.com:21"}, + + // For IPv6 literals should always include the brackets. + { GURL("http://[1::2]/x"), "[1::2]"}, + { GURL("http://[::a]:33/x"), "[::a]:33"}, + }; + for (size_t i = 0; i < arraysize(tests); ++i) { + std::string host_and_port = GetHostAndOptionalPort(tests[i].url); + EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); + } +} + +TEST(UrlUtilTest, GetHostOrSpecFromURL) { + EXPECT_EQ("example.com", + GetHostOrSpecFromURL(GURL("http://example.com/test"))); + EXPECT_EQ("example.com", + GetHostOrSpecFromURL(GURL("http://example.com./test"))); + EXPECT_EQ("file:///tmp/test.html", + GetHostOrSpecFromURL(GURL("file:///tmp/test.html"))); +} + +TEST(UrlUtilTest, CompliantHost) { + struct { + const char* const host; + bool expected_output; + } compliant_host_cases[] = { + {"", false}, + {"a", true}, + {"-", false}, + {"_", false}, + {".", false}, + {"9", true}, + {"9a", true}, + {"9_", true}, + {"a.", true}, + {"a.a", true}, + {"9.a", true}, + {"a.9", true}, + {"_9a", false}, + {"-9a", false}, + {"a.a9", true}, + {"_.9a", true}, + {"a.-a9", false}, + {"a+9a", false}, + {"-a.a9", true}, + {"a_.a9", true}, + {"1-.a-b", true}, + {"1_.a-b", true}, + {"1-2.a_b", true}, + {"a.b.c.d.e", true}, + {"1.2.3.4.5", true}, + {"1.2.3.4.5.", true}, + }; + + for (size_t i = 0; i < arraysize(compliant_host_cases); ++i) { + EXPECT_EQ(compliant_host_cases[i].expected_output, + IsCanonicalizedHostCompliant(compliant_host_cases[i].host)); + } +} + +TEST(UrlUtilTest, SimplifyUrlForRequest) { + struct { + const char* const input_url; + const char* const expected_simplified_url; + } tests[] = { + { + // Reference section should be stripped. + "http://www.google.com:78/foobar?query=1#hash", + "http://www.google.com:78/foobar?query=1", + }, + { + // Reference section can itself contain #. + "http://192.168.0.1?query=1#hash#10#11#13#14", + "http://192.168.0.1?query=1", + }, + { // Strip username/password. + "http://user:pass@google.com", + "http://google.com/", + }, + { // Strip both the reference and the username/password. + "http://user:pass@google.com:80/sup?yo#X#X", + "http://google.com/sup?yo", + }, + { // Try an HTTPS URL -- strip both the reference and the username/password. + "https://user:pass@google.com:80/sup?yo#X#X", + "https://google.com:80/sup?yo", + }, + { // Try an FTP URL -- strip both the reference and the username/password. + "ftp://user:pass@google.com:80/sup?yo#X#X", + "ftp://google.com:80/sup?yo", + }, + { // Try a nonstandard URL + "foobar://user:pass@google.com:80/sup?yo#X#X", + "foobar://user:pass@google.com:80/sup?yo", + }, + }; + for (size_t i = 0; i < arraysize(tests); ++i) { + SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, + tests[i].input_url)); + GURL input_url(GURL(tests[i].input_url)); + GURL expected_url(GURL(tests[i].expected_simplified_url)); + EXPECT_EQ(expected_url, SimplifyUrlForRequest(input_url)); + } +} + +TEST(UrlUtilTest, GetIdentityFromURL) { struct { const char* const input_url; const char* const expected_username; @@ -236,5 +422,40 @@ TEST(UrlUtilTest, GetIdentityFromURL_UTF8) { EXPECT_EQ(WideToUTF16(L"\x4f60\x597d"), password); } +TEST(UrlUtilTest, GoogleHost) { + struct { + GURL url; + bool expected_output; + } google_host_cases[] = { + {GURL("http://.google.com"), true}, + {GURL("http://.youtube.com"), true}, + {GURL("http://.gmail.com"), true}, + {GURL("http://.doubleclick.net"), true}, + {GURL("http://.gstatic.com"), true}, + {GURL("http://.googlevideo.com"), true}, + {GURL("http://.googleusercontent.com"), true}, + {GURL("http://.googlesyndication.com"), true}, + {GURL("http://.google-analytics.com"), true}, + {GURL("http://.googleadservices.com"), true}, + {GURL("http://.googleapis.com"), true}, + {GURL("http://a.google.com"), true}, + {GURL("http://b.youtube.com"), true}, + {GURL("http://c.gmail.com"), true}, + {GURL("http://google.com"), false}, + {GURL("http://youtube.com"), false}, + {GURL("http://gmail.com"), false}, + {GURL("http://google.coma"), false}, + {GURL("http://agoogle.com"), false}, + {GURL("http://oogle.com"), false}, + {GURL("http://google.co"), false}, + {GURL("http://oggole.com"), false}, + }; + + for (size_t i = 0; i < arraysize(google_host_cases); ++i) { + EXPECT_EQ(google_host_cases[i].expected_output, + HasGoogleHost(google_host_cases[i].url)); + } +} + } // namespace } // namespace net diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc index bdb4b87..df5cd6f 100644 --- a/net/cert/cert_verify_proc.cc +++ b/net/cert/cert_verify_proc.cc @@ -16,6 +16,7 @@ #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "net/base/url_util.h" #include "net/cert/cert_status_flags.h" #include "net/cert/cert_verifier.h" #include "net/cert/cert_verify_proc_whitelist.h" diff --git a/net/cert/x509_certificate.cc b/net/cert/x509_certificate.cc index d925ce6..18b9621 100644 --- a/net/cert/x509_certificate.cc +++ b/net/cert/x509_certificate.cc @@ -27,8 +27,8 @@ #include "base/synchronization/lock.h" #include "base/time/time.h" #include "crypto/secure_hash.h" -#include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "net/base/url_util.h" #include "net/cert/pem_tokenizer.h" #include "url/url_canon.h" diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc index 4071e6f..210b8d4 100644 --- a/net/cookies/cookie_util.cc +++ b/net/cookies/cookie_util.cc @@ -11,8 +11,8 @@ #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "build/build_config.h" -#include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "net/base/url_util.h" #include "url/gurl.h" namespace net { diff --git a/net/http/http_auth_handler_digest.cc b/net/http/http_auth_handler_digest.cc index 14c9ecd..3590b8e 100644 --- a/net/http/http_auth_handler_digest.cc +++ b/net/http/http_auth_handler_digest.cc @@ -14,7 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "net/base/net_errors.h" #include "net/base/net_string_util.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "net/http/http_auth.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_scheme.h" diff --git a/net/http/http_auth_handler_ntlm.cc b/net/http/http_auth_handler_ntlm.cc index 2411f9f..bc65807 100644 --- a/net/http/http_auth_handler_ntlm.cc +++ b/net/http/http_auth_handler_ntlm.cc @@ -11,7 +11,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_scheme.h" diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 201e391..423cb870 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -30,8 +30,8 @@ #include "net/base/load_flags.h" #include "net/base/load_timing_info.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" #include "net/base/upload_data_stream.h" +#include "net/base/url_util.h" #include "net/http/http_auth.h" #include "net/http/http_auth_handler.h" #include "net/http/http_auth_handler_factory.h" diff --git a/net/http/http_util_icu.cc b/net/http/http_util_icu.cc index 9ee7e98..df5d618 100644 --- a/net/http/http_util_icu.cc +++ b/net/http/http_util_icu.cc @@ -8,7 +8,7 @@ #include "net/http/http_util.h" #include "base/logging.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" namespace net { diff --git a/net/proxy/proxy_bypass_rules.cc b/net/proxy/proxy_bypass_rules.cc index be18edb..f31fa7b 100644 --- a/net/proxy/proxy_bypass_rules.cc +++ b/net/proxy/proxy_bypass_rules.cc @@ -13,7 +13,7 @@ #include "base/strings/stringprintf.h" #include "net/base/host_port_pair.h" #include "net/base/ip_address_number.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" namespace net { diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc index d3ba5ba..76fa0d6 100644 --- a/net/proxy/proxy_server.cc +++ b/net/proxy/proxy_server.cc @@ -7,7 +7,7 @@ #include <algorithm> #include "base/strings/string_util.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "net/http/http_util.h" namespace net { diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index 2c30f74..cb140f6 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -23,7 +23,7 @@ #include "net/base/completion_callback.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "net/log/net_log.h" #include "net/proxy/dhcp_proxy_script_fetcher.h" #include "net/proxy/multi_threaded_proxy_resolver.h" diff --git a/net/quic/crypto/crypto_utils.cc b/net/quic/crypto/crypto_utils.cc index 0c6a4a7..8843e2c 100644 --- a/net/quic/crypto/crypto_utils.cc +++ b/net/quic/crypto/crypto_utils.cc @@ -5,7 +5,7 @@ #include "net/quic/crypto/crypto_utils.h" #include "crypto/hkdf.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "net/quic/crypto/crypto_handshake.h" #include "net/quic/crypto/crypto_protocol.h" #include "net/quic/crypto/quic_decrypter.h" diff --git a/net/spdy/spdy_http_utils.cc b/net/spdy/spdy_http_utils.cc index 4eb811f..0091edf 100644 --- a/net/spdy/spdy_http_utils.cc +++ b/net/spdy/spdy_http_utils.cc @@ -11,7 +11,7 @@ #include "base/time/time.h" #include "net/base/escape.h" #include "net/base/load_flags.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "net/http/http_request_headers.h" #include "net/http/http_request_info.h" #include "net/http/http_response_headers.h" diff --git a/net/tools/gdig/gdig.cc b/net/tools/gdig/gdig.cc index 9a0176b..e0af40f 100644 --- a/net/tools/gdig/gdig.cc +++ b/net/tools/gdig/gdig.cc @@ -25,7 +25,7 @@ #include "net/base/address_list.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "net/dns/dns_client.h" #include "net/dns/dns_config_service.h" #include "net/dns/dns_protocol.h" diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index c2a70dd..3315d7e9 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -24,11 +24,11 @@ #include "net/base/host_port_pair.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" #include "net/base/network_delegate.h" #include "net/base/network_quality_estimator.h" #include "net/base/sdch_manager.h" #include "net/base/sdch_net_log_params.h" +#include "net/base/url_util.h" #include "net/cert/cert_status_flags.h" #include "net/cookies/cookie_store.h" #include "net/http/http_content_disposition.h" diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index b1bf618..d0e5d25 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -51,13 +51,13 @@ #include "net/base/load_timing_info_test_util.h" #include "net/base/net_errors.h" #include "net/base/net_module.h" -#include "net/base/net_util.h" #include "net/base/network_quality_estimator.h" #include "net/base/request_priority.h" #include "net/base/test_data_directory.h" #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_data_stream.h" #include "net/base/upload_file_element_reader.h" +#include "net/base/url_util.h" #include "net/cert/ev_root_ca_metadata.h" #include "net/cert/mock_cert_verifier.h" #include "net/cert/test_root_certs.h" |