Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1108)

Unified Diff: net/base/net_util.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/net_util.h ('k') | net/base/net_util_icu.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/net_util.cc
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
deleted file mode 100644
index 3b49dffb5c20d889003a09755276ddaa8e41542d..0000000000000000000000000000000000000000
--- a/net/base/net_util.cc
+++ /dev/null
@@ -1,1065 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/base/net_util.h"
-
-#include <errno.h>
-#include <string.h>
-
-#include <algorithm>
-#include <iterator>
-#include <limits>
-#include <set>
-
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#include <iphlpapi.h>
-#include <winsock2.h>
-#include <ws2bth.h>
-#pragma comment(lib, "iphlpapi.lib")
-#elif defined(OS_POSIX)
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#if !defined(OS_NACL)
-#include <net/if.h>
-#if !defined(OS_ANDROID)
-#include <ifaddrs.h>
-#endif // !defined(OS_NACL)
-#endif // !defined(OS_ANDROID)
-#endif // defined(OS_POSIX)
-
-#include "base/basictypes.h"
-#include "base/json/string_escape.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.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 "base/values.h"
-#include "url/gurl.h"
-#include "url/url_canon.h"
-#include "url/url_canon_ip.h"
-#include "url/url_parse.h"
-#include "net/base/dns_util.h"
-#include "net/base/net_module.h"
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "net/grit/net_resources.h"
-#include "net/http/http_content_disposition.h"
-
-#if defined(OS_ANDROID)
-#include "net/android/network_library.h"
-#endif
-#if defined(OS_WIN)
-#include "net/base/winsock_init.h"
-#endif
-
-namespace net {
-
-namespace {
-
-// The general list of blocked ports. Will be blocked unless a specific
-// protocol overrides it. (Ex: ftp can use ports 20 and 21)
-static const int kRestrictedPorts[] = {
- 1, // tcpmux
- 7, // echo
- 9, // discard
- 11, // systat
- 13, // daytime
- 15, // netstat
- 17, // qotd
- 19, // chargen
- 20, // ftp data
- 21, // ftp access
- 22, // ssh
- 23, // telnet
- 25, // smtp
- 37, // time
- 42, // name
- 43, // nicname
- 53, // domain
- 77, // priv-rjs
- 79, // finger
- 87, // ttylink
- 95, // supdup
- 101, // hostriame
- 102, // iso-tsap
- 103, // gppitnp
- 104, // acr-nema
- 109, // pop2
- 110, // pop3
- 111, // sunrpc
- 113, // auth
- 115, // sftp
- 117, // uucp-path
- 119, // nntp
- 123, // NTP
- 135, // loc-srv /epmap
- 139, // netbios
- 143, // imap2
- 179, // BGP
- 389, // ldap
- 465, // smtp+ssl
- 512, // print / exec
- 513, // login
- 514, // shell
- 515, // printer
- 526, // tempo
- 530, // courier
- 531, // chat
- 532, // netnews
- 540, // uucp
- 556, // remotefs
- 563, // nntp+ssl
- 587, // stmp?
- 601, // ??
- 636, // ldap+ssl
- 993, // ldap+ssl
- 995, // pop3+ssl
- 2049, // nfs
- 3659, // apple-sasl / PasswordServer
- 4045, // lockd
- 6000, // X11
- 6665, // Alternate IRC [Apple addition]
- 6666, // Alternate IRC [Apple addition]
- 6667, // Standard IRC [Apple addition]
- 6668, // Alternate IRC [Apple addition]
- 6669, // Alternate IRC [Apple addition]
- 0xFFFF, // Used to block all invalid port numbers (see
- // third_party/WebKit/Source/platform/weborigin/KURL.cpp,
- // KURL::port())
-};
-
-// FTP overrides the following restricted ports.
-static const int kAllowedFtpPorts[] = {
- 21, // ftp data
- 22, // ssh
-};
-
-bool IPNumberPrefixCheck(const IPAddressNumber& ip_number,
- const unsigned char* ip_prefix,
- size_t prefix_length_in_bits) {
- // Compare all the bytes that fall entirely within the prefix.
- int num_entire_bytes_in_prefix = prefix_length_in_bits / 8;
- for (int i = 0; i < num_entire_bytes_in_prefix; ++i) {
- if (ip_number[i] != ip_prefix[i])
- return false;
- }
-
- // In case the prefix was not a multiple of 8, there will be 1 byte
- // which is only partially masked.
- int remaining_bits = prefix_length_in_bits % 8;
- if (remaining_bits != 0) {
- unsigned char mask = 0xFF << (8 - remaining_bits);
- int i = num_entire_bytes_in_prefix;
- if ((ip_number[i] & mask) != (ip_prefix[i] & mask))
- return false;
- }
- return true;
-}
-
-} // namespace
-
-static base::LazyInstance<std::multiset<int> >::Leaky
- g_explicitly_allowed_ports = LAZY_INSTANCE_INITIALIZER;
-
-size_t GetCountOfExplicitlyAllowedPorts() {
- return g_explicitly_allowed_ports.Get().size();
-}
-
-std::string GetSpecificHeader(const std::string& headers,
- const std::string& name) {
- // We want to grab the Value from the "Key: Value" pairs in the headers,
- // which should look like this (no leading spaces, \n-separated) (we format
- // them this way in url_request_inet.cc):
- // HTTP/1.1 200 OK\n
- // ETag: "6d0b8-947-24f35ec0"\n
- // Content-Length: 2375\n
- // Content-Type: text/html; charset=UTF-8\n
- // Last-Modified: Sun, 03 Sep 2006 04:34:43 GMT\n
- if (headers.empty())
- return std::string();
-
- std::string match('\n' + name + ':');
-
- std::string::const_iterator begin =
- std::search(headers.begin(), headers.end(), match.begin(), match.end(),
- base::CaseInsensitiveCompareASCII<char>());
-
- if (begin == headers.end())
- return std::string();
-
- begin += match.length();
-
- std::string ret;
- base::TrimWhitespace(std::string(begin,
- std::find(begin, headers.end(), '\n')),
- base::TRIM_ALL, &ret);
- return ret;
-}
-
-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;
-}
-
-std::string GetDirectoryListingHeader(const base::string16& title) {
- static const base::StringPiece header(
- NetModule::GetResource(IDR_DIR_HEADER_HTML));
- // This can be null in unit tests.
- DLOG_IF(WARNING, header.empty()) <<
- "Missing resource: directory listing header";
-
- std::string result;
- if (!header.empty())
- result.assign(header.data(), header.size());
-
- result.append("<script>start(");
- base::EscapeJSONString(title, true, &result);
- result.append(");</script>\n");
-
- return result;
-}
-
-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;
- bool last_char_was_underscore = 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 != '-'))
- return false;
- in_component = true;
- } else {
- if (c == '.') {
- if (last_char_was_underscore)
- return false;
- in_component = false;
- } else if (IsHostCharAlphanumeric(c) || (c == '-')) {
- last_char_was_underscore = false;
- } else if (c == '_') {
- last_char_was_underscore = true;
- } else {
- return false;
- }
- }
- }
-
- return most_recent_component_started_alphanumeric;
-}
-
-base::string16 StripWWW(const base::string16& text) {
- const base::string16 www(base::ASCIIToUTF16("www."));
- return StartsWith(text, www, true) ? text.substr(www.length()) : text;
-}
-
-base::string16 StripWWWFromHost(const GURL& url) {
- DCHECK(url.is_valid());
- return StripWWW(base::ASCIIToUTF16(url.host()));
-}
-
-bool IsPortValid(int port) {
- return port >= 0 && port <= std::numeric_limits<uint16>::max();
-}
-
-bool IsPortAllowedByDefault(int port) {
- int array_size = arraysize(kRestrictedPorts);
- for (int i = 0; i < array_size; i++) {
- if (kRestrictedPorts[i] == port) {
- return false;
- }
- }
- return IsPortValid(port);
-}
-
-bool IsPortAllowedByFtp(int port) {
- int array_size = arraysize(kAllowedFtpPorts);
- for (int i = 0; i < array_size; i++) {
- if (kAllowedFtpPorts[i] == port) {
- return true;
- }
- }
- // Port not explicitly allowed by FTP, so return the default restrictions.
- return IsPortAllowedByDefault(port);
-}
-
-bool IsPortAllowedByOverride(int port) {
- if (g_explicitly_allowed_ports.Get().empty())
- return false;
-
- return g_explicitly_allowed_ports.Get().count(port) > 0;
-}
-
-int SetNonBlocking(int fd) {
-#if defined(OS_WIN)
- unsigned long no_block = 1;
- return ioctlsocket(fd, FIONBIO, &no_block);
-#elif defined(OS_POSIX)
- int flags = fcntl(fd, F_GETFL, 0);
- if (-1 == flags)
- return flags;
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-#endif
-}
-
-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 ?
- "[" + hostname + "]" : hostname;
- url::CanonHostInfo host_info;
- std::string canonical_name = CanonicalizeHost(host_or_ip, &host_info);
-
- // If canonicalization fails, then the input is truly malformed. However,
- // to avoid mis-reporting bad inputs as "non-unique", treat them as unique.
- if (canonical_name.empty())
- return false;
-
- // If |hostname| is an IP address, check to see if it's in an IANA-reserved
- // range.
- if (host_info.IsIPAddress()) {
- IPAddressNumber host_addr;
- if (!ParseIPLiteralToNumber(hostname.substr(host_info.out_host.begin,
- host_info.out_host.len),
- &host_addr)) {
- return false;
- }
- switch (host_info.family) {
- case url::CanonHostInfo::IPV4:
- case url::CanonHostInfo::IPV6:
- return IsIPAddressReserved(host_addr);
- case url::CanonHostInfo::NEUTRAL:
- case url::CanonHostInfo::BROKEN:
- return false;
- }
- }
-
- // Check for a registry controlled portion of |hostname|, ignoring private
- // registries, as they already chain to ICANN-administered registries,
- // and explicitly ignoring unknown registries.
- //
- // Note: This means that as new gTLDs are introduced on the Internet, they
- // will be treated as non-unique until the registry controlled domain list
- // is updated. However, because gTLDs are expected to provide significant
- // advance notice to deprecate older versions of this code, this an
- // acceptable tradeoff.
- return 0 == registry_controlled_domains::GetRegistryLength(
- canonical_name,
- registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
- registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
-}
-
-// Don't compare IPv4 and IPv6 addresses (they have different range
-// reservations). Keep separate reservation arrays for each IP type, and
-// consolidate adjacent reserved ranges within a reservation array when
-// possible.
-// Sources for info:
-// www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
-// www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
-// They're formatted here with the prefix as the last element. For example:
-// 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10.
-bool IsIPAddressReserved(const IPAddressNumber& host_addr) {
- static const unsigned char kReservedIPv4[][5] = {
- { 0,0,0,0,8 }, { 10,0,0,0,8 }, { 100,64,0,0,10 }, { 127,0,0,0,8 },
- { 169,254,0,0,16 }, { 172,16,0,0,12 }, { 192,0,2,0,24 },
- { 192,88,99,0,24 }, { 192,168,0,0,16 }, { 198,18,0,0,15 },
- { 198,51,100,0,24 }, { 203,0,113,0,24 }, { 224,0,0,0,3 }
- };
- static const unsigned char kReservedIPv6[][17] = {
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 },
- { 0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 },
- { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 },
- { 0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3 },
- { 0xe0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
- { 0xf0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5 },
- { 0xf8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6 },
- { 0xfc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7 },
- { 0xfe,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9 },
- { 0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 },
- { 0xfe,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 },
- };
- size_t array_size = 0;
- const unsigned char* array = NULL;
- switch (host_addr.size()) {
- case kIPv4AddressSize:
- array_size = arraysize(kReservedIPv4);
- array = kReservedIPv4[0];
- break;
- case kIPv6AddressSize:
- array_size = arraysize(kReservedIPv6);
- array = kReservedIPv6[0];
- break;
- }
- if (!array)
- return false;
- size_t width = host_addr.size() + 1;
- for (size_t i = 0; i < array_size; ++i, array += width) {
- if (IPNumberPrefixCheck(host_addr, array, array[width-1]))
- return true;
- }
- return false;
-}
-
-SockaddrStorage::SockaddrStorage(const SockaddrStorage& other)
- : addr_len(other.addr_len),
- addr(reinterpret_cast<struct sockaddr*>(&addr_storage)) {
- memcpy(addr, other.addr, addr_len);
-}
-
-void SockaddrStorage::operator=(const SockaddrStorage& other) {
- addr_len = other.addr_len;
- // addr is already set to &this->addr_storage by default ctor.
- memcpy(addr, other.addr, addr_len);
-}
-
-// Extracts the address and port portions of a sockaddr.
-bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr,
- socklen_t sock_addr_len,
- const uint8** address,
- size_t* address_len,
- uint16* port) {
- if (sock_addr->sa_family == AF_INET) {
- if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in)))
- return false;
- const struct sockaddr_in* addr =
- reinterpret_cast<const struct sockaddr_in*>(sock_addr);
- *address = reinterpret_cast<const uint8*>(&addr->sin_addr);
- *address_len = kIPv4AddressSize;
- if (port)
- *port = base::NetToHost16(addr->sin_port);
- return true;
- }
-
- if (sock_addr->sa_family == AF_INET6) {
- if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in6)))
- return false;
- const struct sockaddr_in6* addr =
- reinterpret_cast<const struct sockaddr_in6*>(sock_addr);
- *address = reinterpret_cast<const uint8*>(&addr->sin6_addr);
- *address_len = kIPv6AddressSize;
- if (port)
- *port = base::NetToHost16(addr->sin6_port);
- return true;
- }
-
-#if defined(OS_WIN)
- if (sock_addr->sa_family == AF_BTH) {
- if (sock_addr_len < static_cast<socklen_t>(sizeof(SOCKADDR_BTH)))
- return false;
- const SOCKADDR_BTH* addr =
- reinterpret_cast<const SOCKADDR_BTH*>(sock_addr);
- *address = reinterpret_cast<const uint8*>(&addr->btAddr);
- *address_len = kBluetoothAddressSize;
- if (port)
- *port = static_cast<uint16>(addr->port);
- return true;
- }
-#endif
-
- return false; // Unrecognized |sa_family|.
-}
-
-std::string IPAddressToString(const uint8* address,
- size_t address_len) {
- std::string str;
- url::StdStringCanonOutput output(&str);
-
- if (address_len == kIPv4AddressSize) {
- url::AppendIPv4Address(address, &output);
- } else if (address_len == kIPv6AddressSize) {
- url::AppendIPv6Address(address, &output);
- } else {
- CHECK(false) << "Invalid IP address with length: " << address_len;
- }
-
- output.Complete();
- return str;
-}
-
-std::string IPAddressToStringWithPort(const uint8* address,
- size_t address_len,
- uint16 port) {
- std::string address_str = IPAddressToString(address, address_len);
-
- if (address_len == kIPv6AddressSize) {
- // Need to bracket IPv6 addresses since they contain colons.
- return base::StringPrintf("[%s]:%d", address_str.c_str(), port);
- }
- return base::StringPrintf("%s:%d", address_str.c_str(), port);
-}
-
-std::string NetAddressToString(const struct sockaddr* sa,
- socklen_t sock_addr_len) {
- const uint8* address;
- size_t address_len;
- if (!GetIPAddressFromSockAddr(sa, sock_addr_len, &address,
- &address_len, NULL)) {
- NOTREACHED();
- return std::string();
- }
- return IPAddressToString(address, address_len);
-}
-
-std::string NetAddressToStringWithPort(const struct sockaddr* sa,
- socklen_t sock_addr_len) {
- const uint8* address;
- size_t address_len;
- uint16 port;
- if (!GetIPAddressFromSockAddr(sa, sock_addr_len, &address,
- &address_len, &port)) {
- NOTREACHED();
- return std::string();
- }
- return IPAddressToStringWithPort(address, address_len, port);
-}
-
-std::string IPAddressToString(const IPAddressNumber& addr) {
- return IPAddressToString(&addr.front(), addr.size());
-}
-
-std::string IPAddressToStringWithPort(const IPAddressNumber& addr,
- uint16 port) {
- return IPAddressToStringWithPort(&addr.front(), addr.size(), port);
-}
-
-std::string IPAddressToPackedString(const IPAddressNumber& addr) {
- return std::string(reinterpret_cast<const char *>(&addr.front()),
- addr.size());
-}
-
-std::string GetHostName() {
-#if defined(OS_NACL)
- NOTIMPLEMENTED();
- return std::string();
-#else // defined(OS_NACL)
-#if defined(OS_WIN)
- EnsureWinsockInit();
-#endif
-
- // Host names are limited to 255 bytes.
- char buffer[256];
- int result = gethostname(buffer, sizeof(buffer));
- if (result != 0) {
- DVLOG(1) << "gethostname() failed with " << result;
- buffer[0] = '\0';
- }
- return std::string(buffer);
-#endif // !defined(OS_NACL)
-}
-
-void GetIdentityFromURL(const GURL& url,
- base::string16* username,
- base::string16* password) {
- UnescapeRule::Type flags =
- UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS;
- *username = UnescapeAndDecodeUTF8URLComponent(url.username(), flags);
- *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags);
-}
-
-std::string GetHostOrSpecFromURL(const GURL& url) {
- return url.has_host() ? TrimEndingDot(url.host()) : url.spec();
-}
-
-bool CanStripTrailingSlash(const GURL& url) {
- // Omit the path only for standard, non-file URLs with nothing but "/" after
- // the hostname.
- return url.IsStandard() && !url.SchemeIsFile() &&
- !url.SchemeIsFileSystem() && !url.has_query() && !url.has_ref()
- && url.path() == "/";
-}
-
-GURL SimplifyUrlForRequest(const GURL& url) {
- DCHECK(url.is_valid());
- GURL::Replacements replacements;
- replacements.ClearUsername();
- replacements.ClearPassword();
- replacements.ClearRef();
- return url.ReplaceComponents(replacements);
-}
-
-// Specifies a comma separated list of port numbers that should be accepted
-// despite bans. If the string is invalid no allowed ports are stored.
-void SetExplicitlyAllowedPorts(const std::string& allowed_ports) {
- if (allowed_ports.empty())
- return;
-
- std::multiset<int> ports;
- size_t last = 0;
- size_t size = allowed_ports.size();
- // The comma delimiter.
- const std::string::value_type kComma = ',';
-
- // Overflow is still possible for evil user inputs.
- for (size_t i = 0; i <= size; ++i) {
- // The string should be composed of only digits and commas.
- if (i != size && !IsAsciiDigit(allowed_ports[i]) &&
- (allowed_ports[i] != kComma))
- return;
- if (i == size || allowed_ports[i] == kComma) {
- if (i > last) {
- int port;
- base::StringToInt(base::StringPiece(allowed_ports.begin() + last,
- allowed_ports.begin() + i),
- &port);
- ports.insert(port);
- }
- last = i + 1;
- }
- }
- g_explicitly_allowed_ports.Get() = ports;
-}
-
-ScopedPortException::ScopedPortException(int port) : port_(port) {
- g_explicitly_allowed_ports.Get().insert(port);
-}
-
-ScopedPortException::~ScopedPortException() {
- std::multiset<int>::iterator it =
- g_explicitly_allowed_ports.Get().find(port_);
- if (it != g_explicitly_allowed_ports.Get().end())
- g_explicitly_allowed_ports.Get().erase(it);
- else
- NOTREACHED();
-}
-
-bool HaveOnlyLoopbackAddresses() {
-#if defined(OS_ANDROID)
- return android::HaveOnlyLoopbackAddresses();
-#elif defined(OS_NACL)
- NOTIMPLEMENTED();
- return false;
-#elif defined(OS_POSIX)
- struct ifaddrs* interface_addr = NULL;
- int rv = getifaddrs(&interface_addr);
- if (rv != 0) {
- DVLOG(1) << "getifaddrs() failed with errno = " << errno;
- return false;
- }
-
- bool result = true;
- for (struct ifaddrs* interface = interface_addr;
- interface != NULL;
- interface = interface->ifa_next) {
- if (!(IFF_UP & interface->ifa_flags))
- continue;
- if (IFF_LOOPBACK & interface->ifa_flags)
- continue;
- const struct sockaddr* addr = interface->ifa_addr;
- if (!addr)
- continue;
- if (addr->sa_family == AF_INET6) {
- // Safe cast since this is AF_INET6.
- const struct sockaddr_in6* addr_in6 =
- reinterpret_cast<const struct sockaddr_in6*>(addr);
- const struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
- if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr))
- continue;
- }
- if (addr->sa_family != AF_INET6 && addr->sa_family != AF_INET)
- continue;
-
- result = false;
- break;
- }
- freeifaddrs(interface_addr);
- return result;
-#elif defined(OS_WIN)
- // TODO(wtc): implement with the GetAdaptersAddresses function.
- NOTIMPLEMENTED();
- return false;
-#else
- NOTIMPLEMENTED();
- return false;
-#endif // defined(various platforms)
-}
-
-AddressFamily GetAddressFamily(const IPAddressNumber& address) {
- switch (address.size()) {
- case kIPv4AddressSize:
- return ADDRESS_FAMILY_IPV4;
- case kIPv6AddressSize:
- return ADDRESS_FAMILY_IPV6;
- default:
- return ADDRESS_FAMILY_UNSPECIFIED;
- }
-}
-
-int ConvertAddressFamily(AddressFamily address_family) {
- switch (address_family) {
- case ADDRESS_FAMILY_UNSPECIFIED:
- return AF_UNSPEC;
- case ADDRESS_FAMILY_IPV4:
- return AF_INET;
- case ADDRESS_FAMILY_IPV6:
- return AF_INET6;
- }
- NOTREACHED();
- return AF_UNSPEC;
-}
-
-bool ParseURLHostnameToNumber(const std::string& hostname,
- IPAddressNumber* ip_number) {
- // |hostname| is an already canoncalized hostname, conforming to RFC 3986.
- // For an IP address, this is defined in Section 3.2.2 of RFC 3986, with
- // the canonical form for IPv6 addresses defined in Section 4 of RFC 5952.
- url::Component host_comp(0, hostname.size());
-
- // If it has a bracket, try parsing it as an IPv6 address.
- if (hostname[0] == '[') {
- ip_number->resize(16); // 128 bits.
- return url::IPv6AddressToNumber(
- hostname.data(), host_comp, &(*ip_number)[0]);
- }
-
- // Otherwise, try IPv4.
- ip_number->resize(4); // 32 bits.
- int num_components;
- url::CanonHostInfo::Family family = url::IPv4AddressToNumber(
- hostname.data(), host_comp, &(*ip_number)[0], &num_components);
- return family == url::CanonHostInfo::IPV4;
-}
-
-bool ParseIPLiteralToNumber(const std::string& ip_literal,
- IPAddressNumber* ip_number) {
- // |ip_literal| could be either a IPv4 or an IPv6 literal. If it contains
- // a colon however, it must be an IPv6 address.
- if (ip_literal.find(':') != std::string::npos) {
- // GURL expects IPv6 hostnames to be surrounded with brackets.
- std::string host_brackets = "[" + ip_literal + "]";
- url::Component host_comp(0, host_brackets.size());
-
- // Try parsing the hostname as an IPv6 literal.
- ip_number->resize(16); // 128 bits.
- return url::IPv6AddressToNumber(host_brackets.data(), host_comp,
- &(*ip_number)[0]);
- }
-
- // Otherwise the string is an IPv4 address.
- ip_number->resize(4); // 32 bits.
- url::Component host_comp(0, ip_literal.size());
- int num_components;
- url::CanonHostInfo::Family family = url::IPv4AddressToNumber(
- ip_literal.data(), host_comp, &(*ip_number)[0], &num_components);
- return family == url::CanonHostInfo::IPV4;
-}
-
-namespace {
-
-const unsigned char kIPv4MappedPrefix[] =
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF };
-}
-
-IPAddressNumber ConvertIPv4NumberToIPv6Number(
- const IPAddressNumber& ipv4_number) {
- DCHECK(ipv4_number.size() == 4);
-
- // IPv4-mapped addresses are formed by:
- // <80 bits of zeros> + <16 bits of ones> + <32-bit IPv4 address>.
- IPAddressNumber ipv6_number;
- ipv6_number.reserve(16);
- ipv6_number.insert(ipv6_number.end(),
- kIPv4MappedPrefix,
- kIPv4MappedPrefix + arraysize(kIPv4MappedPrefix));
- ipv6_number.insert(ipv6_number.end(), ipv4_number.begin(), ipv4_number.end());
- return ipv6_number;
-}
-
-bool IsIPv4Mapped(const IPAddressNumber& address) {
- if (address.size() != kIPv6AddressSize)
- return false;
- return std::equal(address.begin(),
- address.begin() + arraysize(kIPv4MappedPrefix),
- kIPv4MappedPrefix);
-}
-
-IPAddressNumber ConvertIPv4MappedToIPv4(const IPAddressNumber& address) {
- DCHECK(IsIPv4Mapped(address));
- return IPAddressNumber(address.begin() + arraysize(kIPv4MappedPrefix),
- address.end());
-}
-
-bool ParseCIDRBlock(const std::string& cidr_literal,
- IPAddressNumber* ip_number,
- size_t* prefix_length_in_bits) {
- // We expect CIDR notation to match one of these two templates:
- // <IPv4-literal> "/" <number of bits>
- // <IPv6-literal> "/" <number of bits>
-
- std::vector<std::string> parts;
- base::SplitString(cidr_literal, '/', &parts);
- if (parts.size() != 2)
- return false;
-
- // Parse the IP address.
- if (!ParseIPLiteralToNumber(parts[0], ip_number))
- return false;
-
- // Parse the prefix length.
- int number_of_bits = -1;
- if (!base::StringToInt(parts[1], &number_of_bits))
- return false;
-
- // Make sure the prefix length is in a valid range.
- if (number_of_bits < 0 ||
- number_of_bits > static_cast<int>(ip_number->size() * 8))
- return false;
-
- *prefix_length_in_bits = static_cast<size_t>(number_of_bits);
- return true;
-}
-
-bool IPNumberMatchesPrefix(const IPAddressNumber& ip_number,
- const IPAddressNumber& ip_prefix,
- size_t prefix_length_in_bits) {
- // Both the input IP address and the prefix IP address should be
- // either IPv4 or IPv6.
- DCHECK(ip_number.size() == 4 || ip_number.size() == 16);
- DCHECK(ip_prefix.size() == 4 || ip_prefix.size() == 16);
-
- DCHECK_LE(prefix_length_in_bits, ip_prefix.size() * 8);
-
- // In case we have an IPv6 / IPv4 mismatch, convert the IPv4 addresses to
- // IPv6 addresses in order to do the comparison.
- if (ip_number.size() != ip_prefix.size()) {
- if (ip_number.size() == 4) {
- return IPNumberMatchesPrefix(ConvertIPv4NumberToIPv6Number(ip_number),
- ip_prefix, prefix_length_in_bits);
- }
- return IPNumberMatchesPrefix(ip_number,
- ConvertIPv4NumberToIPv6Number(ip_prefix),
- 96 + prefix_length_in_bits);
- }
-
- return IPNumberPrefixCheck(ip_number, &ip_prefix[0], prefix_length_in_bits);
-}
-
-const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address,
- socklen_t address_len) {
- if (address->sa_family == AF_INET) {
- DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len));
- const struct sockaddr_in* sockaddr =
- reinterpret_cast<const struct sockaddr_in*>(address);
- return &sockaddr->sin_port;
- } else if (address->sa_family == AF_INET6) {
- DCHECK_LE(sizeof(sockaddr_in6), static_cast<size_t>(address_len));
- const struct sockaddr_in6* sockaddr =
- reinterpret_cast<const struct sockaddr_in6*>(address);
- return &sockaddr->sin6_port;
- } else {
- NOTREACHED();
- return NULL;
- }
-}
-
-int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
- const uint16* port_field = GetPortFieldFromSockaddr(address, address_len);
- if (!port_field)
- return -1;
- return base::NetToHost16(*port_field);
-}
-
-bool IsLocalhost(const std::string& host) {
- if (host == "localhost" ||
- host == "localhost.localdomain" ||
- host == "localhost6" ||
- host == "localhost6.localdomain6")
- return true;
-
- IPAddressNumber ip_number;
- if (ParseIPLiteralToNumber(host, &ip_number)) {
- size_t size = ip_number.size();
- switch (size) {
- case kIPv4AddressSize: {
- IPAddressNumber localhost_prefix;
- localhost_prefix.push_back(127);
- for (int i = 0; i < 3; ++i) {
- localhost_prefix.push_back(0);
- }
- return IPNumberMatchesPrefix(ip_number, localhost_prefix, 8);
- }
-
- case kIPv6AddressSize: {
- struct in6_addr sin6_addr;
- memcpy(&sin6_addr, &ip_number[0], kIPv6AddressSize);
- return !!IN6_IS_ADDR_LOOPBACK(&sin6_addr);
- }
-
- default:
- NOTREACHED();
- }
- }
-
- return false;
-}
-
-NetworkInterface::NetworkInterface()
- : type(NetworkChangeNotifier::CONNECTION_UNKNOWN), prefix_length(0) {
-}
-
-NetworkInterface::NetworkInterface(const std::string& name,
- const std::string& friendly_name,
- uint32 interface_index,
- NetworkChangeNotifier::ConnectionType type,
- const IPAddressNumber& address,
- uint32 prefix_length,
- int ip_address_attributes)
- : name(name),
- friendly_name(friendly_name),
- interface_index(interface_index),
- type(type),
- address(address),
- prefix_length(prefix_length),
- ip_address_attributes(ip_address_attributes) {
-}
-
-NetworkInterface::~NetworkInterface() {
-}
-
-unsigned CommonPrefixLength(const IPAddressNumber& a1,
- const IPAddressNumber& a2) {
- DCHECK_EQ(a1.size(), a2.size());
- for (size_t i = 0; i < a1.size(); ++i) {
- unsigned diff = a1[i] ^ a2[i];
- if (!diff)
- continue;
- for (unsigned j = 0; j < CHAR_BIT; ++j) {
- if (diff & (1 << (CHAR_BIT - 1)))
- return i * CHAR_BIT + j;
- diff <<= 1;
- }
- NOTREACHED();
- }
- return a1.size() * CHAR_BIT;
-}
-
-unsigned MaskPrefixLength(const IPAddressNumber& mask) {
- IPAddressNumber all_ones(mask.size(), 0xFF);
- return CommonPrefixLength(mask, all_ones);
-}
-
-ScopedWifiOptions::~ScopedWifiOptions() {
-}
-
-} // namespace net
« no previous file with comments | « net/base/net_util.h ('k') | net/base/net_util_icu.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698