summaryrefslogtreecommitdiff
path: root/chromium/net/base
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@theqtcompany.com>2014-12-05 15:04:29 +0100
committerAndras Becsi <andras.becsi@theqtcompany.com>2014-12-09 10:49:28 +0100
commitaf6588f8d723931a298c995fa97259bb7f7deb55 (patch)
tree060ca707847ba1735f01af2372e0d5e494dc0366 /chromium/net/base
parent2fff84d821cc7b1c785f6404e0f8091333283e74 (diff)
downloadqtwebengine-chromium-af6588f8d723931a298c995fa97259bb7f7deb55.tar.gz
BASELINE: Update chromium to 40.0.2214.28 and ninja to 1.5.3.
Change-Id: I759465284fd64d59ad120219cbe257f7402c4181 Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/net/base')
-rw-r--r--chromium/net/base/address_list_unittest.cc4
-rw-r--r--chromium/net/base/address_tracker_linux.cc110
-rw-r--r--chromium/net/base/address_tracker_linux.h49
-rw-r--r--chromium/net/base/address_tracker_linux_unittest.cc111
-rw-r--r--chromium/net/base/backoff_entry_unittest.cc6
-rw-r--r--chromium/net/base/capturing_net_log.h6
-rw-r--r--chromium/net/base/chunked_upload_data_stream.cc103
-rw-r--r--chromium/net/base/chunked_upload_data_stream.h63
-rw-r--r--chromium/net/base/chunked_upload_data_stream_unittest.cc308
-rw-r--r--chromium/net/base/data_url.cc17
-rw-r--r--chromium/net/base/data_url.h19
-rw-r--r--chromium/net/base/data_url_unittest.cc75
-rw-r--r--chromium/net/base/directory_lister.cc8
-rw-r--r--chromium/net/base/directory_lister_unittest.cc14
-rw-r--r--chromium/net/base/dns_reloader.cc6
-rw-r--r--chromium/net/base/dns_util_unittest.cc8
-rw-r--r--chromium/net/base/elements_upload_data_stream.cc166
-rw-r--r--chromium/net/base/elements_upload_data_stream.h85
-rw-r--r--chromium/net/base/elements_upload_data_stream_unittest.cc (renamed from chromium/net/base/upload_data_stream_unittest.cc)369
-rw-r--r--chromium/net/base/escape.cc102
-rw-r--r--chromium/net/base/escape.h9
-rw-r--r--chromium/net/base/escape_unittest.cc65
-rw-r--r--chromium/net/base/file_stream.cc18
-rw-r--r--chromium/net/base/file_stream.h3
-rw-r--r--chromium/net/base/file_stream_context.cc46
-rw-r--r--chromium/net/base/file_stream_context.h70
-rw-r--r--chromium/net/base/file_stream_context_posix.cc59
-rw-r--r--chromium/net/base/file_stream_context_win.cc48
-rw-r--r--chromium/net/base/file_stream_unittest.cc116
-rw-r--r--chromium/net/base/file_stream_whence.h20
-rw-r--r--chromium/net/base/filename_util.cc2
-rw-r--r--chromium/net/base/filename_util_icu.cc8
-rw-r--r--chromium/net/base/filename_util_internal.cc23
-rw-r--r--chromium/net/base/filename_util_unittest.cc65
-rw-r--r--chromium/net/base/host_mapping_rules.cc4
-rw-r--r--chromium/net/base/io_buffer.cc7
-rw-r--r--chromium/net/base/io_buffer.h13
-rw-r--r--chromium/net/base/ip_endpoint_unittest.cc4
-rw-r--r--chromium/net/base/keygen_handler_nss.cc20
-rw-r--r--chromium/net/base/keygen_handler_openssl.cc5
-rw-r--r--chromium/net/base/keygen_handler_unittest.cc72
-rw-r--r--chromium/net/base/keygen_handler_win.cc19
-rw-r--r--chromium/net/base/linked_hash_map.h22
-rw-r--r--chromium/net/base/load_flags_list.h53
-rw-r--r--chromium/net/base/mime_sniffer.cc8
-rw-r--r--chromium/net/base/mime_util.cc516
-rw-r--r--chromium/net/base/mime_util.h44
-rw-r--r--chromium/net/base/mime_util_certificate_type_list.h13
-rw-r--r--chromium/net/base/mime_util_unittest.cc31
-rw-r--r--chromium/net/base/mock_file_stream.cc2
-rw-r--r--chromium/net/base/mock_file_stream.h21
-rw-r--r--chromium/net/base/net_error_list.h20
-rw-r--r--chromium/net/base/net_errors.cc37
-rw-r--r--chromium/net/base/net_errors.h20
-rw-r--r--chromium/net/base/net_info_source_list.h22
-rw-r--r--chromium/net/base/net_log.cc24
-rw-r--r--chromium/net/base/net_log.h8
-rw-r--r--chromium/net/base/net_log_event_type_list.h37
-rw-r--r--chromium/net/base/net_log_logger.cc179
-rw-r--r--chromium/net/base/net_log_logger.h9
-rw-r--r--chromium/net/base/net_log_logger_unittest.cc111
-rw-r--r--chromium/net/base/net_log_source_type_list.h1
-rw-r--r--chromium/net/base/net_log_unittest.cc22
-rw-r--r--chromium/net/base/net_log_util.cc461
-rw-r--r--chromium/net/base/net_log_util.h43
-rw-r--r--chromium/net/base/net_log_util_unittest.cc54
-rw-r--r--chromium/net/base/net_string_util_icu_alternatives_android.cc21
-rw-r--r--chromium/net/base/net_util.cc69
-rw-r--r--chromium/net/base/net_util.h73
-rw-r--r--chromium/net/base/net_util_icu.cc8
-rw-r--r--chromium/net/base/net_util_icu_unittest.cc6
-rw-r--r--chromium/net/base/net_util_posix.cc269
-rw-r--r--chromium/net/base/net_util_posix.h31
-rw-r--r--chromium/net/base/net_util_unittest.cc396
-rw-r--r--chromium/net/base/net_util_win.cc214
-rw-r--r--chromium/net/base/net_util_win.h85
-rw-r--r--chromium/net/base/network_change_notifier.cc125
-rw-r--r--chromium/net/base/network_change_notifier.h33
-rw-r--r--chromium/net/base/network_change_notifier_linux.cc6
-rw-r--r--chromium/net/base/network_change_notifier_linux.h8
-rw-r--r--chromium/net/base/network_change_notifier_mac.cc10
-rw-r--r--chromium/net/base/network_change_notifier_mac.h13
-rw-r--r--chromium/net/base/network_change_notifier_unittest.cc60
-rw-r--r--chromium/net/base/network_change_notifier_win.cc10
-rw-r--r--chromium/net/base/network_change_notifier_win.h10
-rw-r--r--chromium/net/base/network_change_notifier_win_unittest.cc2
-rw-r--r--chromium/net/base/network_config_watcher_mac.cc6
-rw-r--r--chromium/net/base/network_delegate.cc140
-rw-r--r--chromium/net/base/network_delegate.h49
-rw-r--r--chromium/net/base/openssl_private_key_store_android.cc6
-rw-r--r--chromium/net/base/openssl_private_key_store_memory.cc2
-rw-r--r--chromium/net/base/prioritized_dispatcher_unittest.cc2
-rw-r--r--chromium/net/base/priority_queue_unittest.cc2
-rw-r--r--chromium/net/base/proxy_delegate.h76
-rw-r--r--chromium/net/base/registry_controlled_domains/OWNERS1
-rw-r--r--chromium/net/base/registry_controlled_domains/effective_tld_names.dat2266
-rw-r--r--chromium/net/base/registry_controlled_domains/effective_tld_names.gperf270
-rw-r--r--chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc2
-rw-r--r--chromium/net/base/request_priority.h4
-rw-r--r--chromium/net/base/sdch_dictionary_fetcher.cc105
-rw-r--r--chromium/net/base/sdch_dictionary_fetcher.h99
-rw-r--r--chromium/net/base/sdch_manager.cc359
-rw-r--r--chromium/net/base/sdch_manager.h155
-rw-r--r--chromium/net/base/sdch_manager_unittest.cc263
-rw-r--r--chromium/net/base/sdch_observer.cc14
-rw-r--r--chromium/net/base/sdch_observer.h34
-rw-r--r--chromium/net/base/test_completion_callback.cc14
-rw-r--r--chromium/net/base/test_completion_callback.h29
-rw-r--r--chromium/net/base/test_completion_callback_unittest.cc31
-rw-r--r--chromium/net/base/trace_net_log_observer.cc112
-rw-r--r--chromium/net/base/trace_net_log_observer.h49
-rw-r--r--chromium/net/base/trace_net_log_observer_unittest.cc378
-rw-r--r--chromium/net/base/upload_bytes_element_reader.h20
-rw-r--r--chromium/net/base/upload_bytes_element_reader_unittest.cc2
-rw-r--r--chromium/net/base/upload_data_stream.cc276
-rw-r--r--chromium/net/base/upload_data_stream.h151
-rw-r--r--chromium/net/base/upload_element.cc25
-rw-r--r--chromium/net/base/upload_element.h110
-rw-r--r--chromium/net/base/upload_element_reader.h4
-rw-r--r--chromium/net/base/upload_file_element_reader.cc16
-rw-r--r--chromium/net/base/upload_file_element_reader.h22
-rw-r--r--chromium/net/base/upload_file_element_reader_unittest.cc6
122 files changed, 7367 insertions, 3265 deletions
diff --git a/chromium/net/base/address_list_unittest.cc b/chromium/net/base/address_list_unittest.cc
index 32c3e521642..e5597885bdc 100644
--- a/chromium/net/base/address_list_unittest.cc
+++ b/chromium/net/base/address_list_unittest.cc
@@ -121,7 +121,7 @@ TEST(AddressListTest, CreateFromIPAddressList) {
// Construct a list of ip addresses.
IPAddressList ip_list;
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
IPAddressNumber ip_number;
ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number));
ip_list.push_back(ip_number);
@@ -131,7 +131,7 @@ TEST(AddressListTest, CreateFromIPAddressList) {
kCanonicalName);
std::string canonical_name;
EXPECT_EQ(kCanonicalName, test_list.canonical_name());
- EXPECT_EQ(ARRAYSIZE_UNSAFE(tests), test_list.size());
+ EXPECT_EQ(arraysize(tests), test_list.size());
}
} // namespace
diff --git a/chromium/net/base/address_tracker_linux.cc b/chromium/net/base/address_tracker_linux.cc
index 36738136695..27dd2019ab0 100644
--- a/chromium/net/base/address_tracker_linux.cc
+++ b/chromium/net/base/address_tracker_linux.cc
@@ -97,6 +97,18 @@ const char* GetInterfaceName(int interface_index) {
} // namespace
+AddressTrackerLinux::AddressTrackerLinux()
+ : get_interface_name_(GetInterfaceName),
+ address_callback_(base::Bind(&base::DoNothing)),
+ link_callback_(base::Bind(&base::DoNothing)),
+ tunnel_callback_(base::Bind(&base::DoNothing)),
+ netlink_fd_(-1),
+ is_offline_(true),
+ is_offline_initialized_(false),
+ is_offline_initialized_cv_(&is_offline_lock_),
+ tracking_(false) {
+}
+
AddressTrackerLinux::AddressTrackerLinux(const base::Closure& address_callback,
const base::Closure& link_callback,
const base::Closure& tunnel_callback)
@@ -107,7 +119,8 @@ AddressTrackerLinux::AddressTrackerLinux(const base::Closure& address_callback,
netlink_fd_(-1),
is_offline_(true),
is_offline_initialized_(false),
- is_offline_initialized_cv_(&is_offline_lock_) {
+ is_offline_initialized_cv_(&is_offline_lock_),
+ tracking_(true) {
DCHECK(!address_callback.is_null());
DCHECK(!link_callback.is_null());
}
@@ -124,20 +137,24 @@ void AddressTrackerLinux::Init() {
return;
}
- // Request notifications.
- struct sockaddr_nl addr = {};
- addr.nl_family = AF_NETLINK;
- addr.nl_pid = getpid();
- // TODO(szym): Track RTMGRP_LINK as well for ifi_type, http://crbug.com/113993
- addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY |
- RTMGRP_LINK;
- int rv = bind(netlink_fd_,
- reinterpret_cast<struct sockaddr*>(&addr),
- sizeof(addr));
- if (rv < 0) {
- PLOG(ERROR) << "Could not bind NETLINK socket";
- AbortAndForceOnline();
- return;
+ int rv;
+
+ if (tracking_) {
+ // Request notifications.
+ struct sockaddr_nl addr = {};
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pid = getpid();
+ // TODO(szym): Track RTMGRP_LINK as well for ifi_type,
+ // http://crbug.com/113993
+ addr.nl_groups =
+ RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NOTIFY | RTMGRP_LINK;
+ rv = bind(
+ netlink_fd_, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
+ if (rv < 0) {
+ PLOG(ERROR) << "Could not bind NETLINK socket";
+ AbortAndForceOnline();
+ return;
+ }
}
// Request dump of addresses.
@@ -186,38 +203,45 @@ void AddressTrackerLinux::Init() {
// Consume pending message to populate links_online_, but don't notify.
ReadMessages(&address_changed, &link_changed, &tunnel_changed);
{
- base::AutoLock lock(is_offline_lock_);
+ AddressTrackerAutoLock lock(*this, is_offline_lock_);
is_offline_initialized_ = true;
is_offline_initialized_cv_.Signal();
}
- rv = base::MessageLoopForIO::current()->WatchFileDescriptor(
- netlink_fd_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
- if (rv < 0) {
- PLOG(ERROR) << "Could not watch NETLINK socket";
- AbortAndForceOnline();
- return;
+ if (tracking_) {
+ rv = base::MessageLoopForIO::current()->WatchFileDescriptor(
+ netlink_fd_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
+ if (rv < 0) {
+ PLOG(ERROR) << "Could not watch NETLINK socket";
+ AbortAndForceOnline();
+ return;
+ }
}
}
void AddressTrackerLinux::AbortAndForceOnline() {
CloseSocket();
- base::AutoLock lock(is_offline_lock_);
+ AddressTrackerAutoLock lock(*this, is_offline_lock_);
is_offline_ = false;
is_offline_initialized_ = true;
is_offline_initialized_cv_.Signal();
}
AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const {
- base::AutoLock lock(address_map_lock_);
+ AddressTrackerAutoLock lock(*this, address_map_lock_);
return address_map_;
}
+base::hash_set<int> AddressTrackerLinux::GetOnlineLinks() const {
+ AddressTrackerAutoLock lock(*this, online_links_lock_);
+ return online_links_;
+}
+
NetworkChangeNotifier::ConnectionType
AddressTrackerLinux::GetCurrentConnectionType() {
// http://crbug.com/125097
base::ThreadRestrictions::ScopedAllowWait allow_wait;
- base::AutoLock lock(is_offline_lock_);
+ AddressTrackerAutoLock lock(*this, is_offline_lock_);
// Make sure the initial offline state is set before returning.
while (!is_offline_initialized_) {
is_offline_initialized_cv_.Wait();
@@ -254,10 +278,15 @@ void AddressTrackerLinux::ReadMessages(bool* address_changed,
return;
}
HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
- };
+ }
if (*link_changed) {
- base::AutoLock lock(is_offline_lock_);
- is_offline_ = online_links_.empty();
+ bool is_offline;
+ {
+ AddressTrackerAutoLock lock(*this, online_links_lock_);
+ is_offline = online_links_.empty();
+ }
+ AddressTrackerAutoLock lock(*this, is_offline_lock_);
+ is_offline_ = is_offline;
}
}
@@ -282,7 +311,7 @@ void AddressTrackerLinux::HandleMessage(char* buffer,
IPAddressNumber address;
bool really_deprecated;
if (GetAddress(header, &address, &really_deprecated)) {
- base::AutoLock lock(address_map_lock_);
+ AddressTrackerAutoLock lock(*this, address_map_lock_);
struct ifaddrmsg* msg =
reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(header));
// Routers may frequently (every few seconds) output the IPv6 ULA
@@ -309,7 +338,7 @@ void AddressTrackerLinux::HandleMessage(char* buffer,
case RTM_DELADDR: {
IPAddressNumber address;
if (GetAddress(header, &address, NULL)) {
- base::AutoLock lock(address_map_lock_);
+ AddressTrackerAutoLock lock(*this, address_map_lock_);
if (address_map_.erase(address))
*address_changed = true;
}
@@ -319,12 +348,14 @@ void AddressTrackerLinux::HandleMessage(char* buffer,
reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header));
if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) &&
(msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) {
+ AddressTrackerAutoLock lock(*this, online_links_lock_);
if (online_links_.insert(msg->ifi_index).second) {
*link_changed = true;
if (IsTunnelInterface(msg))
*tunnel_changed = true;
}
} else {
+ AddressTrackerAutoLock lock(*this, online_links_lock_);
if (online_links_.erase(msg->ifi_index)) {
*link_changed = true;
if (IsTunnelInterface(msg))
@@ -335,6 +366,7 @@ void AddressTrackerLinux::HandleMessage(char* buffer,
case RTM_DELLINK: {
const struct ifinfomsg* msg =
reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header));
+ AddressTrackerAutoLock lock(*this, online_links_lock_);
if (online_links_.erase(msg->ifi_index)) {
*link_changed = true;
if (IsTunnelInterface(msg))
@@ -374,5 +406,23 @@ bool AddressTrackerLinux::IsTunnelInterface(const struct ifinfomsg* msg) const {
return strncmp(get_interface_name_(msg->ifi_index), "tun", 3) == 0;
}
+AddressTrackerLinux::AddressTrackerAutoLock::AddressTrackerAutoLock(
+ const AddressTrackerLinux& tracker,
+ base::Lock& lock)
+ : tracker_(tracker), lock_(lock) {
+ if (tracker_.tracking_) {
+ lock_.Acquire();
+ } else {
+ DCHECK(tracker_.thread_checker_.CalledOnValidThread());
+ }
+}
+
+AddressTrackerLinux::AddressTrackerAutoLock::~AddressTrackerAutoLock() {
+ if (tracker_.tracking_) {
+ lock_.AssertAcquired();
+ lock_.Release();
+ }
+}
+
} // namespace internal
} // namespace net
diff --git a/chromium/net/base/address_tracker_linux.h b/chromium/net/base/address_tracker_linux.h
index 415e8c89e9d..a960287d4ad 100644
--- a/chromium/net/base/address_tracker_linux.h
+++ b/chromium/net/base/address_tracker_linux.h
@@ -20,6 +20,7 @@
#include "base/message_loop/message_loop.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
#include "net/base/net_util.h"
#include "net/base/network_change_notifier.h"
@@ -33,20 +34,33 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
public:
typedef std::map<IPAddressNumber, struct ifaddrmsg> AddressMap;
- // Will run |address_callback| when the AddressMap changes, |link_callback|
- // when the list of online links changes, and |tunnel_callback| when the list
- // of online tunnels changes.
+ // Non-tracking version constructor: it takes a snapshot of the
+ // current system configuration. Once Init() returns, the
+ // configuration is available through GetOnlineLinks() and
+ // GetAddressMap().
+ AddressTrackerLinux();
+
+ // Tracking version constructor: it will run |address_callback| when
+ // the AddressMap changes, |link_callback| when the list of online
+ // links changes, and |tunnel_callback| when the list of online
+ // tunnels changes.
AddressTrackerLinux(const base::Closure& address_callback,
const base::Closure& link_callback,
const base::Closure& tunnel_callback);
- virtual ~AddressTrackerLinux();
+ ~AddressTrackerLinux() override;
- // Starts watching system configuration for changes. The current thread must
- // have a MessageLoopForIO.
+ // In tracking mode, it starts watching the system configuration for
+ // changes. The current thread must have a MessageLoopForIO. In
+ // non-tracking mode, once Init() returns, a snapshot of the system
+ // configuration is available through GetOnlineLinks() and
+ // GetAddressMap().
void Init();
AddressMap GetAddressMap() const;
+ // Returns set of interface indicies for online interfaces.
+ base::hash_set<int> GetOnlineLinks() const;
+
// Implementation of NetworkChangeNotifierLinux::GetCurrentConnectionType().
// Safe to call from any thread, but will block until Init() has completed.
NetworkChangeNotifier::ConnectionType GetCurrentConnectionType();
@@ -54,6 +68,20 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
private:
friend class AddressTrackerLinuxTest;
+ // In tracking mode, holds |lock| while alive. In non-tracking mode,
+ // enforces single-threaded access.
+ class AddressTrackerAutoLock {
+ public:
+ AddressTrackerAutoLock(const AddressTrackerLinux& tracker,
+ base::Lock& lock);
+ ~AddressTrackerAutoLock();
+
+ private:
+ const AddressTrackerLinux& tracker_;
+ base::Lock& lock_;
+ DISALLOW_COPY_AND_ASSIGN(AddressTrackerAutoLock);
+ };
+
// A function that returns the name of an interface given the interface index
// in |interface_index|.
typedef const char* (*GetInterfaceNameFunction)(int interface_index);
@@ -80,8 +108,8 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
void AbortAndForceOnline();
// MessageLoopForIO::Watcher:
- virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
- virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE;
+ void OnFileCanReadWithoutBlocking(int fd) override;
+ void OnFileCanWriteWithoutBlocking(int /* fd */) override;
// Close |netlink_fd_|
void CloseSocket();
@@ -105,12 +133,17 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
AddressMap address_map_;
// Set of interface indices for links that are currently online.
+ mutable base::Lock online_links_lock_;
base::hash_set<int> online_links_;
base::Lock is_offline_lock_;
bool is_offline_;
bool is_offline_initialized_;
base::ConditionVariable is_offline_initialized_cv_;
+ bool tracking_;
+
+ // Used to verify single-threaded access in non-tracking mode.
+ base::ThreadChecker thread_checker_;
};
} // namespace internal
diff --git a/chromium/net/base/address_tracker_linux_unittest.cc b/chromium/net/base/address_tracker_linux_unittest.cc
index 1223d04f2ef..641220731b7 100644
--- a/chromium/net/base/address_tracker_linux_unittest.cc
+++ b/chromium/net/base/address_tracker_linux_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/memory/scoped_ptr.h"
#include "net/base/address_tracker_linux.h"
#include <linux/if.h>
@@ -33,12 +34,18 @@ typedef std::vector<char> Buffer;
class AddressTrackerLinuxTest : public testing::Test {
protected:
- AddressTrackerLinuxTest()
- : tracker_(base::Bind(&base::DoNothing),
- base::Bind(&base::DoNothing),
- base::Bind(&base::DoNothing)),
- original_get_interface_name_(tracker_.get_interface_name_) {
- tracker_.get_interface_name_ = TestGetInterfaceName;
+ AddressTrackerLinuxTest() {}
+
+ void InitializeAddressTracker(bool tracking) {
+ if (tracking) {
+ tracker_.reset(new AddressTrackerLinux(base::Bind(&base::DoNothing),
+ base::Bind(&base::DoNothing),
+ base::Bind(&base::DoNothing)));
+ } else {
+ tracker_.reset(new AddressTrackerLinux());
+ }
+ original_get_interface_name_ = tracker_->get_interface_name_;
+ tracker_->get_interface_name_ = TestGetInterfaceName;
}
bool HandleAddressMessage(const Buffer& buf) {
@@ -46,7 +53,7 @@ class AddressTrackerLinuxTest : public testing::Test {
bool address_changed = false;
bool link_changed = false;
bool tunnel_changed = false;
- tracker_.HandleMessage(&writable_buf[0], buf.size(),
+ tracker_->HandleMessage(&writable_buf[0], buf.size(),
&address_changed, &link_changed, &tunnel_changed);
EXPECT_FALSE(link_changed);
return address_changed;
@@ -57,7 +64,7 @@ class AddressTrackerLinuxTest : public testing::Test {
bool address_changed = false;
bool link_changed = false;
bool tunnel_changed = false;
- tracker_.HandleMessage(&writable_buf[0], buf.size(),
+ tracker_->HandleMessage(&writable_buf[0], buf.size(),
&address_changed, &link_changed, &tunnel_changed);
EXPECT_FALSE(address_changed);
return link_changed;
@@ -68,21 +75,21 @@ class AddressTrackerLinuxTest : public testing::Test {
bool address_changed = false;
bool link_changed = false;
bool tunnel_changed = false;
- tracker_.HandleMessage(&writable_buf[0], buf.size(),
+ tracker_->HandleMessage(&writable_buf[0], buf.size(),
&address_changed, &link_changed, &tunnel_changed);
EXPECT_FALSE(address_changed);
return tunnel_changed;
}
AddressTrackerLinux::AddressMap GetAddressMap() {
- return tracker_.GetAddressMap();
+ return tracker_->GetAddressMap();
}
- const base::hash_set<int>* GetOnlineLinks() const {
- return &tracker_.online_links_;
+ const base::hash_set<int> GetOnlineLinks() const {
+ return tracker_->GetOnlineLinks();
}
- AddressTrackerLinux tracker_;
+ scoped_ptr<AddressTrackerLinux> tracker_;
AddressTrackerLinux::GetInterfaceNameFunction original_get_interface_name_;
};
@@ -190,6 +197,8 @@ const unsigned char kAddress3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1 };
TEST_F(AddressTrackerLinuxTest, NewAddress) {
+ InitializeAddressTracker(true);
+
const IPAddressNumber kEmpty;
const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
const IPAddressNumber kAddr1(kAddress1, kAddress1 + arraysize(kAddress1));
@@ -224,6 +233,8 @@ TEST_F(AddressTrackerLinuxTest, NewAddress) {
}
TEST_F(AddressTrackerLinuxTest, NewAddressChange) {
+ InitializeAddressTracker(true);
+
const IPAddressNumber kEmpty;
const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
@@ -258,6 +269,8 @@ TEST_F(AddressTrackerLinuxTest, NewAddressChange) {
}
TEST_F(AddressTrackerLinuxTest, NewAddressDuplicate) {
+ InitializeAddressTracker(true);
+
const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
Buffer buffer;
@@ -276,6 +289,8 @@ TEST_F(AddressTrackerLinuxTest, NewAddressDuplicate) {
}
TEST_F(AddressTrackerLinuxTest, DeleteAddress) {
+ InitializeAddressTracker(true);
+
const IPAddressNumber kEmpty;
const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
const IPAddressNumber kAddr1(kAddress1, kAddress1 + arraysize(kAddress1));
@@ -311,6 +326,8 @@ TEST_F(AddressTrackerLinuxTest, DeleteAddress) {
}
TEST_F(AddressTrackerLinuxTest, DeprecatedLifetime) {
+ InitializeAddressTracker(true);
+
const IPAddressNumber kEmpty;
const IPAddressNumber kAddr3(kAddress3, kAddress3 + arraysize(kAddress3));
@@ -351,6 +368,8 @@ TEST_F(AddressTrackerLinuxTest, DeprecatedLifetime) {
}
TEST_F(AddressTrackerLinuxTest, IgnoredMessage) {
+ InitializeAddressTracker(true);
+
const IPAddressNumber kEmpty;
const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
const IPAddressNumber kAddr3(kAddress3, kAddress3 + arraysize(kAddress3));
@@ -381,6 +400,8 @@ TEST_F(AddressTrackerLinuxTest, IgnoredMessage) {
}
TEST_F(AddressTrackerLinuxTest, AddInterface) {
+ InitializeAddressTracker(true);
+
Buffer buffer;
// Ignores loopback.
@@ -388,69 +409,73 @@ TEST_F(AddressTrackerLinuxTest, AddInterface) {
IFF_LOOPBACK | IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
0, &buffer);
EXPECT_FALSE(HandleLinkMessage(buffer));
- EXPECT_TRUE(GetOnlineLinks()->empty());
+ EXPECT_TRUE(GetOnlineLinks().empty());
// Ignores not IFF_LOWER_UP.
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
EXPECT_FALSE(HandleLinkMessage(buffer));
- EXPECT_TRUE(GetOnlineLinks()->empty());
+ EXPECT_TRUE(GetOnlineLinks().empty());
// Ignores deletion.
MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
EXPECT_FALSE(HandleLinkMessage(buffer));
- EXPECT_TRUE(GetOnlineLinks()->empty());
+ EXPECT_TRUE(GetOnlineLinks().empty());
// Verify success.
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
EXPECT_TRUE(HandleLinkMessage(buffer));
- EXPECT_EQ(1u, GetOnlineLinks()->count(0));
- EXPECT_EQ(1u, GetOnlineLinks()->size());
+ EXPECT_EQ(1u, GetOnlineLinks().count(0));
+ EXPECT_EQ(1u, GetOnlineLinks().size());
// Ignores redundant enables.
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
EXPECT_FALSE(HandleLinkMessage(buffer));
- EXPECT_EQ(1u, GetOnlineLinks()->count(0));
- EXPECT_EQ(1u, GetOnlineLinks()->size());
+ EXPECT_EQ(1u, GetOnlineLinks().count(0));
+ EXPECT_EQ(1u, GetOnlineLinks().size());
// Verify adding another online device (e.g. VPN) is considered a change.
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 1, &buffer);
EXPECT_TRUE(HandleLinkMessage(buffer));
- EXPECT_EQ(1u, GetOnlineLinks()->count(0));
- EXPECT_EQ(1u, GetOnlineLinks()->count(1));
- EXPECT_EQ(2u, GetOnlineLinks()->size());
+ EXPECT_EQ(1u, GetOnlineLinks().count(0));
+ EXPECT_EQ(1u, GetOnlineLinks().count(1));
+ EXPECT_EQ(2u, GetOnlineLinks().size());
}
TEST_F(AddressTrackerLinuxTest, RemoveInterface) {
+ InitializeAddressTracker(true);
+
Buffer buffer;
// Should disappear when not IFF_LOWER_UP.
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
EXPECT_TRUE(HandleLinkMessage(buffer));
- EXPECT_FALSE(GetOnlineLinks()->empty());
+ EXPECT_FALSE(GetOnlineLinks().empty());
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
EXPECT_TRUE(HandleLinkMessage(buffer));
- EXPECT_TRUE(GetOnlineLinks()->empty());
+ EXPECT_TRUE(GetOnlineLinks().empty());
// Ignores redundant disables.
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
EXPECT_FALSE(HandleLinkMessage(buffer));
- EXPECT_TRUE(GetOnlineLinks()->empty());
+ EXPECT_TRUE(GetOnlineLinks().empty());
// Ignores deleting down interfaces.
MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
EXPECT_FALSE(HandleLinkMessage(buffer));
- EXPECT_TRUE(GetOnlineLinks()->empty());
+ EXPECT_TRUE(GetOnlineLinks().empty());
// Should disappear when deleted.
MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
EXPECT_TRUE(HandleLinkMessage(buffer));
- EXPECT_FALSE(GetOnlineLinks()->empty());
+ EXPECT_FALSE(GetOnlineLinks().empty());
MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
EXPECT_TRUE(HandleLinkMessage(buffer));
- EXPECT_TRUE(GetOnlineLinks()->empty());
+ EXPECT_TRUE(GetOnlineLinks().empty());
}
TEST_F(AddressTrackerLinuxTest, TunnelInterface) {
+ InitializeAddressTracker(true);
+
Buffer buffer;
// Ignores without "tun" prefixed name.
@@ -493,10 +518,38 @@ TEST_F(AddressTrackerLinuxTest, TunnelInterface) {
// Check AddressTrackerLinux::get_interface_name_ original implementation
// doesn't crash or return NULL.
TEST_F(AddressTrackerLinuxTest, GetInterfaceName) {
+ InitializeAddressTracker(true);
+
for (int i = 0; i < 10; i++)
EXPECT_NE((const char*)NULL, original_get_interface_name_(i));
}
+TEST_F(AddressTrackerLinuxTest, NonTrackingMode) {
+ InitializeAddressTracker(false);
+
+ const IPAddressNumber kEmpty;
+ const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
+
+ Buffer buffer;
+ MakeAddrMessage(
+ RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty, &buffer);
+ EXPECT_TRUE(HandleAddressMessage(buffer));
+ AddressTrackerLinux::AddressMap map = GetAddressMap();
+ EXPECT_EQ(1u, map.size());
+ EXPECT_EQ(1u, map.count(kAddr0));
+ EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
+
+ MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
+ EXPECT_TRUE(HandleLinkMessage(buffer));
+ EXPECT_EQ(1u, GetOnlineLinks().count(0));
+ EXPECT_EQ(1u, GetOnlineLinks().size());
+}
+
+TEST_F(AddressTrackerLinuxTest, NonTrackingModeInit) {
+ AddressTrackerLinux tracker;
+ tracker.Init();
+}
+
} // namespace
} // namespace internal
diff --git a/chromium/net/base/backoff_entry_unittest.cc b/chromium/net/base/backoff_entry_unittest.cc
index 560b2133db1..89ec2c4d2f1 100644
--- a/chromium/net/base/backoff_entry_unittest.cc
+++ b/chromium/net/base/backoff_entry_unittest.cc
@@ -23,11 +23,9 @@ class TestBackoffEntry : public BackoffEntry {
SetCustomReleaseTime(TimeTicks());
}
- virtual ~TestBackoffEntry() {}
+ ~TestBackoffEntry() override {}
- virtual TimeTicks ImplGetTimeNow() const OVERRIDE {
- return now_;
- }
+ TimeTicks ImplGetTimeNow() const override { return now_; }
void set_now(const TimeTicks& now) {
now_ = now;
diff --git a/chromium/net/base/capturing_net_log.h b/chromium/net/base/capturing_net_log.h
index 06bc976eeaa..5977533525e 100644
--- a/chromium/net/base/capturing_net_log.h
+++ b/chromium/net/base/capturing_net_log.h
@@ -72,7 +72,7 @@ class CapturingNetLog : public NetLog {
typedef std::vector<CapturedEntry> CapturedEntryList;
CapturingNetLog();
- virtual ~CapturingNetLog();
+ ~CapturingNetLog() override;
void SetLogLevel(LogLevel log_level);
@@ -89,7 +89,7 @@ class CapturingNetLog : public NetLog {
class Observer : public NetLog::ThreadSafeObserver {
public:
Observer();
- virtual ~Observer();
+ ~Observer() override;
// Returns the list of all entries in the log.
void GetEntries(CapturedEntryList* entry_list) const;
@@ -105,7 +105,7 @@ class CapturingNetLog : public NetLog {
private:
// ThreadSafeObserver implementation:
- virtual void OnAddEntry(const Entry& entry) OVERRIDE;
+ void OnAddEntry(const Entry& entry) override;
// Needs to be "mutable" so can use it in GetEntries().
mutable base::Lock lock_;
diff --git a/chromium/net/base/chunked_upload_data_stream.cc b/chromium/net/base/chunked_upload_data_stream.cc
new file mode 100644
index 00000000000..f1fbf0822c8
--- /dev/null
+++ b/chromium/net/base/chunked_upload_data_stream.cc
@@ -0,0 +1,103 @@
+// Copyright 2014 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/chunked_upload_data_stream.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+
+namespace net {
+
+ChunkedUploadDataStream::ChunkedUploadDataStream(int64 identifier)
+ : UploadDataStream(true, identifier),
+ read_index_(0),
+ read_offset_(0),
+ all_data_appended_(false),
+ read_buffer_len_(0) {
+}
+
+ChunkedUploadDataStream::~ChunkedUploadDataStream() {
+}
+
+void ChunkedUploadDataStream::AppendData(
+ const char* data, int data_len, bool is_done) {
+ DCHECK(!all_data_appended_);
+ DCHECK(data_len > 0 || is_done);
+ if (data_len > 0) {
+ DCHECK(data);
+ upload_data_.push_back(new std::vector<char>(data, data + data_len));
+ }
+ all_data_appended_ = is_done;
+
+ if (!read_buffer_.get())
+ return;
+
+ int result = ReadChunk(read_buffer_.get(), read_buffer_len_);
+ // Shouldn't get an error or ERR_IO_PENDING.
+ DCHECK_GE(result, 0);
+ read_buffer_ = NULL;
+ read_buffer_len_ = 0;
+ OnReadCompleted(result);
+}
+
+int ChunkedUploadDataStream::InitInternal() {
+ // ResetInternal should already have been called.
+ DCHECK(!read_buffer_.get());
+ DCHECK_EQ(0u, read_index_);
+ DCHECK_EQ(0u, read_offset_);
+ return OK;
+}
+
+int ChunkedUploadDataStream::ReadInternal(IOBuffer* buf, int buf_len) {
+ DCHECK_LT(0, buf_len);
+ DCHECK(!read_buffer_.get());
+
+ int result = ReadChunk(buf, buf_len);
+ if (result == ERR_IO_PENDING) {
+ read_buffer_ = buf;
+ read_buffer_len_ = buf_len;
+ }
+ return result;
+}
+
+void ChunkedUploadDataStream::ResetInternal() {
+ read_buffer_ = NULL;
+ read_buffer_len_ = 0;
+ read_index_ = 0;
+ read_offset_ = 0;
+}
+
+int ChunkedUploadDataStream::ReadChunk(IOBuffer* buf, int buf_len) {
+ // Copy as much data as possible from |upload_data_| to |buf|.
+ int bytes_read = 0;
+ while (read_index_ < upload_data_.size() && bytes_read < buf_len) {
+ std::vector<char>* data = upload_data_[read_index_];
+ size_t bytes_to_read =
+ std::min(static_cast<size_t>(buf_len - bytes_read),
+ data->size() - read_offset_);
+ memcpy(buf->data() + bytes_read,
+ vector_as_array(data) + read_offset_,
+ bytes_to_read);
+ bytes_read += bytes_to_read;
+ read_offset_ += bytes_to_read;
+ if (read_offset_ == data->size()) {
+ read_index_++;
+ read_offset_ = 0;
+ }
+ }
+ DCHECK_LE(bytes_read, buf_len);
+
+ // If no data was written, and not all data has been appended, return
+ // ERR_IO_PENDING. The read will be completed in the next call to AppendData.
+ if (bytes_read == 0 && !all_data_appended_)
+ return ERR_IO_PENDING;
+
+ if (read_index_ == upload_data_.size() && all_data_appended_)
+ SetIsFinalChunk();
+ return bytes_read;
+}
+
+} // namespace net
diff --git a/chromium/net/base/chunked_upload_data_stream.h b/chromium/net/base/chunked_upload_data_stream.h
new file mode 100644
index 00000000000..d17c8da3269
--- /dev/null
+++ b/chromium/net/base/chunked_upload_data_stream.h
@@ -0,0 +1,63 @@
+// Copyright 2014 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.
+
+#ifndef NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
+#define NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+#include "net/base/upload_data_stream.h"
+
+namespace net {
+
+class IOBuffer;
+
+// Class with a push-based interface for uploading data. Buffers all data until
+// the request is completed. Not recommended for uploading large amounts of
+// seekable data, due to this buffering behavior.
+class NET_EXPORT ChunkedUploadDataStream : public UploadDataStream {
+ public:
+ ChunkedUploadDataStream(int64 identifier);
+
+ ~ChunkedUploadDataStream() override;
+
+ // Adds data to the stream. |is_done| should be true if this is the last
+ // data to be appended. |data_len| must not be 0 unless |is_done| is true.
+ // Once called with |is_done| being true, must never be called again.
+ // TODO(mmenke): Consider using IOBuffers instead, to reduce data copies.
+ void AppendData(const char* data, int data_len, bool is_done);
+
+ private:
+ // UploadDataStream implementation.
+ int InitInternal() override;
+ int ReadInternal(IOBuffer* buf, int buf_len) override;
+ void ResetInternal() override;
+
+ int ReadChunk(IOBuffer* buf, int buf_len);
+
+ // Index and offset of next element of |upload_data_| to be read.
+ size_t read_index_;
+ size_t read_offset_;
+
+ // True once all data has been appended to the stream.
+ bool all_data_appended_;
+
+ ScopedVector<std::vector<char>> upload_data_;
+
+ // Buffer to write the next read's data to. Only set when a call to
+ // ReadInternal reads no data.
+ scoped_refptr<IOBuffer> read_buffer_;
+ int read_buffer_len_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChunkedUploadDataStream);
+};
+
+} // namespace net
+
+#endif // NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
diff --git a/chromium/net/base/chunked_upload_data_stream_unittest.cc b/chromium/net/base/chunked_upload_data_stream_unittest.cc
new file mode 100644
index 00000000000..334e9a39428
--- /dev/null
+++ b/chromium/net/base/chunked_upload_data_stream_unittest.cc
@@ -0,0 +1,308 @@
+// Copyright 2014 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/chunked_upload_data_stream.h"
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "net/base/upload_data_stream.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+const char kTestData[] = "0123456789";
+const size_t kTestDataSize = arraysize(kTestData) - 1;
+const size_t kTestBufferSize = 1 << 14; // 16KB.
+
+} // namespace
+
+// Reads data once from the upload data stream, and returns the data as string.
+// Expects the read to succeed synchronously.
+std::string ReadSync(UploadDataStream* stream, int buffer_size) {
+ scoped_refptr<IOBuffer> buf = new IOBuffer(buffer_size);
+ int result = stream->Read(buf.get(),
+ buffer_size,
+ TestCompletionCallback().callback());
+ EXPECT_GE(result, 0);
+ return std::string(buf->data(), result);
+}
+
+// Check the case data is added after the first read attempt.
+TEST(ChunkedUploadDataStreamTest, AppendOnce) {
+ ChunkedUploadDataStream stream(0);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ TestCompletionCallback callback;
+ scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
+ int result = stream.Read(buf.get(), kTestBufferSize, callback.callback());
+ ASSERT_EQ(ERR_IO_PENDING, result);
+
+ stream.AppendData(kTestData, kTestDataSize, true);
+ int read = callback.WaitForResult();
+ ASSERT_GE(read, 0);
+ EXPECT_EQ(kTestData, std::string(buf->data(), read));
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(kTestDataSize, stream.position());
+ EXPECT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, AppendOnceBeforeRead) {
+ ChunkedUploadDataStream stream(0);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ stream.AppendData(kTestData, kTestDataSize, true);
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ std::string data = ReadSync(&stream, kTestBufferSize);
+ EXPECT_EQ(kTestData, data);
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(kTestDataSize, stream.position());
+ EXPECT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, AppendOnceBeforeInit) {
+ ChunkedUploadDataStream stream(0);
+
+ stream.AppendData(kTestData, kTestDataSize, true);
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ std::string data = ReadSync(&stream, kTestBufferSize);
+ EXPECT_EQ(kTestData, data);
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(kTestDataSize, stream.position());
+ EXPECT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, MultipleAppends) {
+ ChunkedUploadDataStream stream(0);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size());
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ TestCompletionCallback callback;
+ scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
+ for (size_t i = 0; i < kTestDataSize; ++i) {
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(i, stream.position());
+ ASSERT_FALSE(stream.IsEOF());
+ int bytes_read = stream.Read(buf.get(),
+ kTestBufferSize,
+ callback.callback());
+ ASSERT_EQ(ERR_IO_PENDING, bytes_read);
+ stream.AppendData(&kTestData[i], 1, i == kTestDataSize - 1);
+ ASSERT_EQ(1, callback.WaitForResult());
+ EXPECT_EQ(kTestData[i], buf->data()[0]);
+ }
+
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(kTestDataSize, stream.position());
+ ASSERT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, MultipleAppendsBetweenReads) {
+ ChunkedUploadDataStream stream(0);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
+ for (size_t i = 0; i < kTestDataSize; ++i) {
+ EXPECT_EQ(i, stream.position());
+ ASSERT_FALSE(stream.IsEOF());
+ stream.AppendData(&kTestData[i], 1, i == kTestDataSize - 1);
+ int bytes_read = stream.Read(buf.get(),
+ kTestBufferSize,
+ TestCompletionCallback().callback());
+ ASSERT_EQ(1, bytes_read);
+ EXPECT_EQ(kTestData[i], buf->data()[0]);
+ }
+
+ EXPECT_EQ(kTestDataSize, stream.position());
+ ASSERT_TRUE(stream.IsEOF());
+}
+
+// Checks that multiple reads can be merged.
+TEST(ChunkedUploadDataStreamTest, MultipleAppendsBeforeInit) {
+ ChunkedUploadDataStream stream(0);
+ stream.AppendData(kTestData, 1, false);
+ stream.AppendData(kTestData + 1, 1, false);
+ stream.AppendData(kTestData + 2, kTestDataSize - 2, true);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ std::string data = ReadSync(&stream, kTestBufferSize);
+ EXPECT_EQ(kTestData, data);
+ EXPECT_EQ(kTestDataSize, stream.position());
+ ASSERT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, MultipleReads) {
+ // Use a read size different from the write size to test bounds checking.
+ const size_t kReadSize = kTestDataSize + 3;
+
+ ChunkedUploadDataStream stream(0);
+ stream.AppendData(kTestData, kTestDataSize, false);
+ stream.AppendData(kTestData, kTestDataSize, false);
+ stream.AppendData(kTestData, kTestDataSize, false);
+ stream.AppendData(kTestData, kTestDataSize, true);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ std::string data = ReadSync(&stream, kReadSize);
+ EXPECT_EQ("0123456789012", data);
+ EXPECT_EQ(kReadSize, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ data = ReadSync(&stream, kReadSize);
+ EXPECT_EQ("3456789012345", data);
+ EXPECT_EQ(2 * kReadSize, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ data = ReadSync(&stream, kReadSize);
+ EXPECT_EQ("6789012345678", data);
+ EXPECT_EQ(3 * kReadSize, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ data = ReadSync(&stream, kReadSize);
+ EXPECT_EQ("9", data);
+ EXPECT_EQ(4 * kTestDataSize, stream.position());
+ EXPECT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, EmptyUpload) {
+ ChunkedUploadDataStream stream(0);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ TestCompletionCallback callback;
+ scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
+ int result = stream.Read(buf.get(), kTestBufferSize, callback.callback());
+ ASSERT_EQ(ERR_IO_PENDING, result);
+
+ stream.AppendData(NULL, 0, true);
+ int read = callback.WaitForResult();
+ EXPECT_EQ(0, read);
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, EmptyUploadEndedBeforeInit) {
+ ChunkedUploadDataStream stream(0);
+ stream.AppendData(NULL, 0, true);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ std::string data = ReadSync(&stream, kTestBufferSize);
+ ASSERT_EQ("", data);
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, RewindAfterComplete) {
+ ChunkedUploadDataStream stream(0);
+ stream.AppendData(kTestData, 1, false);
+ stream.AppendData(kTestData + 1, kTestDataSize - 1, true);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ std::string data = ReadSync(&stream, kTestBufferSize);
+ EXPECT_EQ(kTestData, data);
+ EXPECT_EQ(kTestDataSize, stream.position());
+ ASSERT_TRUE(stream.IsEOF());
+
+ // Rewind stream and repeat.
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ data = ReadSync(&stream, kTestBufferSize);
+ EXPECT_EQ(kTestData, data);
+ EXPECT_EQ(kTestDataSize, stream.position());
+ ASSERT_TRUE(stream.IsEOF());
+}
+
+TEST(ChunkedUploadDataStreamTest, RewindWhileReading) {
+ ChunkedUploadDataStream stream(0);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ TestCompletionCallback callback;
+ scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
+ int result = stream.Read(buf.get(), kTestBufferSize, callback.callback());
+ ASSERT_EQ(ERR_IO_PENDING, result);
+
+ ASSERT_EQ(OK, stream.Init(TestCompletionCallback().callback()));
+ EXPECT_FALSE(stream.IsInMemory());
+ EXPECT_EQ(0u, stream.size()); // Content-Length is 0 for chunked data.
+ EXPECT_EQ(0u, stream.position());
+ EXPECT_FALSE(stream.IsEOF());
+
+ // Adding data now should not result in calling the original read callback,
+ // since the stream was re-initialized for reuse, which cancels all pending
+ // reads.
+ stream.AppendData(kTestData, kTestDataSize, true);
+ EXPECT_FALSE(callback.have_result());
+
+ std::string data = ReadSync(&stream, kTestBufferSize);
+ EXPECT_EQ(kTestData, data);
+ EXPECT_EQ(kTestDataSize, stream.position());
+ ASSERT_TRUE(stream.IsEOF());
+ EXPECT_FALSE(callback.have_result());
+}
+
+} // namespace net
diff --git a/chromium/net/base/data_url.cc b/chromium/net/base/data_url.cc
index 9699136c85f..58036c6a369 100644
--- a/chromium/net/base/data_url.cc
+++ b/chromium/net/base/data_url.cc
@@ -14,6 +14,7 @@
#include "base/strings/string_util.h"
#include "net/base/escape.h"
#include "net/base/mime_util.h"
+#include "net/http/http_util.h"
#include "url/gurl.h"
namespace net {
@@ -42,7 +43,7 @@ bool DataURL::Parse(const GURL& url, std::string* mime_type,
std::vector<std::string>::iterator iter = meta_data.begin();
if (iter != meta_data.end()) {
mime_type->swap(*iter);
- StringToLowerASCII(mime_type);
+ base::StringToLowerASCII(mime_type);
++iter;
}
@@ -57,14 +58,24 @@ bool DataURL::Parse(const GURL& url, std::string* mime_type,
} else if (charset->empty() &&
iter->compare(0, kCharsetTagLength, kCharsetTag) == 0) {
charset->assign(iter->substr(kCharsetTagLength));
+ // The grammar for charset is not specially defined in RFC2045 and
+ // RFC2397. It just needs to be a token.
+ if (!net::HttpUtil::IsToken(*charset))
+ return false;
}
}
if (mime_type->empty()) {
- // fallback to defaults if nothing specified in the URL:
+ // Fallback to the default if nothing specified in the mediatype part as
+ // specified in RFC2045. As specified in RFC2397, we use |charset| even if
+ // |mime_type| is empty.
mime_type->assign("text/plain");
} else if (!ParseMimeTypeWithoutParameter(*mime_type, NULL, NULL)) {
- return false;
+ // Fallback to the default as recommended in RFC2045 when the mediatype
+ // value is invalid. For this case, we don't respect |charset| but force it
+ // set to "US-ASCII".
+ mime_type->assign("text/plain");
+ charset->assign("US-ASCII");
}
if (charset->empty())
charset->assign("US-ASCII");
diff --git a/chromium/net/base/data_url.h b/chromium/net/base/data_url.h
index 3c1e3033dc6..ee9c6d31dbf 100644
--- a/chromium/net/base/data_url.h
+++ b/chromium/net/base/data_url.h
@@ -35,8 +35,23 @@ class NET_EXPORT DataURL {
// decoded data (e.g.., if the data URL specifies base64 encoding, then the
// returned data is base64 decoded, and any %-escaped bytes are unescaped).
//
- // If the URL is malformed, then this method will return false, and its
- // output variables will remain unchanged. On success, true is returned.
+ // If the media type value doesn't match the media-type production defined in
+ // RFC 7231, mime_type will be set to the default value "text/plain". We
+ // don't simply fail for this grammar violation since Chromium had been
+ // accepting such invalid values. For example, <img> element with the src
+ // attribute set to a data URL with an invalid media type "image" (without a
+ // slash and subtype) had been displayed. However, the value this method will
+ // store in mime_type argument can be used for generating other headers, etc.
+ // This could lead to security vulnerability. We don't want to accept
+ // arbitrary value and ask each caller to validate the return value.
+ //
+ // If the charset parameter is specified but its value doesn't match the
+ // token production defined in RFC 7230, this method simply fails and returns
+ // false.
+ //
+ // If there's any other grammar violation in the URL, then this method will
+ // return false. Output variables may be changed and contain invalid data. On
+ // success, true is returned.
//
// OPTIONAL: If |data| is NULL, then the <data> section will not be parsed
// or validated.
diff --git a/chromium/net/base/data_url_unittest.cc b/chromium/net/base/data_url_unittest.cc
index 43f881f7084..bcb2b49ad6c 100644
--- a/chromium/net/base/data_url_unittest.cc
+++ b/chromium/net/base/data_url_unittest.cc
@@ -40,10 +40,10 @@ TEST(DataURLTest, Parse) {
"" },
{ "data:;charset=,test",
- true,
- "text/plain",
- "US-ASCII",
- "test" },
+ false,
+ "",
+ "",
+ "" },
{ "data:TeXt/HtMl,<b>x</b>",
true,
@@ -63,6 +63,28 @@ TEST(DataURLTest, Parse) {
"US-ASCII",
"hello world" },
+ // Allow invalid mediatype for backward compatibility but set mime_type to
+ // "text/plain" instead of the invalid mediatype.
+ { "data:foo,boo",
+ true,
+ "text/plain",
+ "US-ASCII",
+ "boo" },
+
+ // When accepting an invalid mediatype, override charset with "US-ASCII"
+ { "data:foo;charset=UTF-8,boo",
+ true,
+ "text/plain",
+ "US-ASCII",
+ "boo" },
+
+ // Invalid mediatype. Includes a slash but the type part is not a token.
+ { "data:f(oo/bar;baz=1;charset=kk,boo",
+ true,
+ "text/plain",
+ "US-ASCII",
+ "boo" },
+
{ "data:foo/bar;baz=1;charset=kk,boo",
true,
"foo/bar",
@@ -88,13 +110,6 @@ TEST(DataURLTest, Parse) {
"US-ASCII",
"<html><body><b>hello world</b></body></html>" },
- // Bad mime type
- { "data:f(oo/bar;baz=1;charset=kk,boo",
- false,
- "",
- "",
- "" },
-
// the comma cannot be url-escaped!
{ "data:%2Cblah",
false,
@@ -169,6 +184,44 @@ TEST(DataURLTest, Parse) {
"",
"" },
+ // BiDi control characters should be unescaped and preserved as is, and
+ // should not be replaced with % versions. In the below case, \xE2\x80\x8F
+ // is the RTL mark and the parsed text should preserve it as is.
+ {
+ "data:text/plain;charset=utf-8,\xE2\x80\x8Ftest",
+ true,
+ "text/plain",
+ "utf-8",
+ "\xE2\x80\x8Ftest"},
+
+ // Same as above but with Arabic text after RTL mark.
+ {
+ "data:text/plain;charset=utf-8,"
+ "\xE2\x80\x8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1",
+ true,
+ "text/plain",
+ "utf-8",
+ "\xE2\x80\x8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1"},
+
+ // RTL mark encoded as %E2%80%8F should be unescaped too. Note that when
+ // wrapped in a GURL, this URL and the next effectively become the same as
+ // the previous two URLs.
+ {
+ "data:text/plain;charset=utf-8,%E2%80%8Ftest",
+ true,
+ "text/plain",
+ "utf-8",
+ "\xE2\x80\x8Ftest"},
+
+ // Same as above but with Arabic text after RTL mark.
+ {
+ "data:text/plain;charset=utf-8,"
+ "%E2%80%8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1",
+ true,
+ "text/plain",
+ "utf-8",
+ "\xE2\x80\x8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1"}
+
// TODO(darin): add more interesting tests
};
diff --git a/chromium/net/base/directory_lister.cc b/chromium/net/base/directory_lister.cc
index e75e9f808dc..841f454c814 100644
--- a/chromium/net/base/directory_lister.cc
+++ b/chromium/net/base/directory_lister.cc
@@ -8,8 +8,8 @@
#include <vector>
#include "base/bind.h"
-#include "base/file_util.h"
#include "base/files/file_enumerator.h"
+#include "base/files/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_restrictions.h"
@@ -41,8 +41,8 @@ bool CompareAlphaDirsFirst(const DirectoryLister::DirectoryListerData& a,
if (a_is_directory != b_is_directory)
return a_is_directory;
- return file_util::LocaleAwareCompareFilenames(a.info.GetName(),
- b.info.GetName());
+ return base::i18n::LocaleAwareCompareFilenames(a.info.GetName(),
+ b.info.GetName());
}
bool CompareDate(const DirectoryLister::DirectoryListerData& a,
@@ -66,7 +66,7 @@ bool CompareDate(const DirectoryLister::DirectoryListerData& a,
// Static.
bool CompareFullPath(const DirectoryLister::DirectoryListerData& a,
const DirectoryLister::DirectoryListerData& b) {
- return file_util::LocaleAwareCompareFilenames(a.path, b.path);
+ return base::i18n::LocaleAwareCompareFilenames(a.path, b.path);
}
void SortData(std::vector<DirectoryLister::DirectoryListerData>* data,
diff --git a/chromium/net/base/directory_lister_unittest.cc b/chromium/net/base/directory_lister_unittest.cc
index 005ce0d5128..869e4f688b9 100644
--- a/chromium/net/base/directory_lister_unittest.cc
+++ b/chromium/net/base/directory_lister_unittest.cc
@@ -5,8 +5,8 @@
#include <list>
#include <utility>
-#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/i18n/file_util_icu.h"
#include "base/message_loop/message_loop.h"
@@ -27,15 +27,14 @@ class ListerDelegate : public DirectoryLister::DirectoryListerDelegate {
quit_loop_after_each_file_(quit_loop_after_each_file) {
}
- virtual void OnListFile(
- const DirectoryLister::DirectoryListerData& data) OVERRIDE {
+ void OnListFile(const DirectoryLister::DirectoryListerData& data) override {
file_list_.push_back(data.info);
paths_.push_back(data.path);
if (quit_loop_after_each_file_)
base::MessageLoop::current()->Quit();
}
- virtual void OnListDone(int error) OVERRIDE {
+ void OnListDone(int error) override {
error_ = error;
base::MessageLoop::current()->Quit();
if (recursive_)
@@ -50,7 +49,7 @@ class ListerDelegate : public DirectoryLister::DirectoryListerDelegate {
for (size_t previous = 0, current = 1;
current < file_list_.size();
previous++, current++) {
- EXPECT_TRUE(file_util::LocaleAwareCompareFilenames(
+ EXPECT_TRUE(base::i18n::LocaleAwareCompareFilenames(
paths_[previous], paths_[current]));
}
}
@@ -71,7 +70,7 @@ class ListerDelegate : public DirectoryLister::DirectoryListerDelegate {
file_list_[current].GetName().BaseName().value());
EXPECT_EQ(file_list_[previous].IsDirectory(),
file_list_[current].IsDirectory());
- EXPECT_TRUE(file_util::LocaleAwareCompareFilenames(
+ EXPECT_TRUE(base::i18n::LocaleAwareCompareFilenames(
file_list_[previous].GetName(),
file_list_[current].GetName()));
}
@@ -92,8 +91,7 @@ class ListerDelegate : public DirectoryLister::DirectoryListerDelegate {
class DirectoryListerTest : public PlatformTest {
public:
-
- virtual void SetUp() OVERRIDE {
+ void SetUp() override {
const int kMaxDepth = 3;
const int kBranchingFactor = 4;
const int kFilesPerDirectory = 5;
diff --git a/chromium/net/base/dns_reloader.cc b/chromium/net/base/dns_reloader.cc
index 04abcb18552..e0e0b76483a 100644
--- a/chromium/net/base/dns_reloader.cc
+++ b/chromium/net/base/dns_reloader.cc
@@ -46,7 +46,7 @@ class DnsReloader : public net::NetworkChangeNotifier::DNSObserver {
};
// NetworkChangeNotifier::DNSObserver:
- virtual void OnDNSChanged() OVERRIDE {
+ void OnDNSChanged() override {
DCHECK(base::MessageLoopForIO::IsCurrent());
base::AutoLock l(lock_);
resolver_generation_++;
@@ -84,7 +84,7 @@ class DnsReloader : public net::NetworkChangeNotifier::DNSObserver {
net::NetworkChangeNotifier::AddDNSObserver(this);
}
- virtual ~DnsReloader() {
+ ~DnsReloader() override {
NOTREACHED(); // LeakyLazyInstance is not destructed.
}
@@ -110,7 +110,7 @@ base::LazyInstance<DnsReloader>::Leaky
namespace net {
void EnsureDnsReloaderInit() {
- DnsReloader* t ALLOW_UNUSED = g_dns_reloader.Pointer();
+ g_dns_reloader.Pointer();
}
void DnsReloaderMaybeReload() {
diff --git a/chromium/net/base/dns_util_unittest.cc b/chromium/net/base/dns_util_unittest.cc
index d91753f4f73..06f1fb25877 100644
--- a/chromium/net/base/dns_util_unittest.cc
+++ b/chromium/net/base/dns_util_unittest.cc
@@ -31,15 +31,15 @@ TEST_F(DNSUtilTest, DNSDomainFromDot) {
EXPECT_EQ(out, IncludeNUL("\003www\006google\003com"));
// Label is 63 chars: still valid
- EXPECT_TRUE(DNSDomainFromDot("123456789a123456789a123456789a123456789a123456789a123456789a123", &out));
- EXPECT_EQ(out, IncludeNUL("\077123456789a123456789a123456789a123456789a123456789a123456789a123"));
+ EXPECT_TRUE(DNSDomainFromDot("z23456789a123456789a123456789a123456789a123456789a123456789a123", &out));
+ EXPECT_EQ(out, IncludeNUL("\077z23456789a123456789a123456789a123456789a123456789a123456789a123"));
// Label is too long: invalid
EXPECT_FALSE(DNSDomainFromDot("123456789a123456789a123456789a123456789a123456789a123456789a1234", &out));
// 253 characters in the name: still valid
- EXPECT_TRUE(DNSDomainFromDot("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123", &out));
- EXPECT_EQ(out, IncludeNUL("\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\011123456789\003123"));
+ EXPECT_TRUE(DNSDomainFromDot("abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.abc", &out));
+ EXPECT_EQ(out, IncludeNUL("\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\011abcdefghi\003abc"));
// 254 characters in the name: invalid
EXPECT_FALSE(DNSDomainFromDot("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.1234", &out));
diff --git a/chromium/net/base/elements_upload_data_stream.cc b/chromium/net/base/elements_upload_data_stream.cc
new file mode 100644
index 00000000000..86ea28c7213
--- /dev/null
+++ b/chromium/net/base/elements_upload_data_stream.cc
@@ -0,0 +1,166 @@
+// 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/elements_upload_data_stream.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/base/upload_bytes_element_reader.h"
+#include "net/base/upload_element_reader.h"
+
+namespace net {
+
+ElementsUploadDataStream::ElementsUploadDataStream(
+ ScopedVector<UploadElementReader> element_readers,
+ int64 identifier)
+ : UploadDataStream(false, identifier),
+ element_readers_(element_readers.Pass()),
+ element_index_(0),
+ read_failed_(false),
+ weak_ptr_factory_(this) {
+}
+
+ElementsUploadDataStream::~ElementsUploadDataStream() {
+}
+
+scoped_ptr<UploadDataStream> ElementsUploadDataStream::CreateWithReader(
+ scoped_ptr<UploadElementReader> reader,
+ int64 identifier) {
+ ScopedVector<UploadElementReader> readers;
+ readers.push_back(reader.release());
+ return scoped_ptr<UploadDataStream>(
+ new ElementsUploadDataStream(readers.Pass(), identifier));
+}
+
+int ElementsUploadDataStream::InitInternal() {
+ return InitElements(0);
+}
+
+int ElementsUploadDataStream::ReadInternal(
+ IOBuffer* buf,
+ int buf_len) {
+ DCHECK_GT(buf_len, 0);
+ return ReadElements(new DrainableIOBuffer(buf, buf_len));
+}
+
+bool ElementsUploadDataStream::IsInMemory() const {
+ for (size_t i = 0; i < element_readers_.size(); ++i) {
+ if (!element_readers_[i]->IsInMemory())
+ return false;
+ }
+ return true;
+}
+
+const ScopedVector<UploadElementReader>*
+ElementsUploadDataStream::GetElementReaders() const {
+ return &element_readers_;
+}
+
+void ElementsUploadDataStream::ResetInternal() {
+ weak_ptr_factory_.InvalidateWeakPtrs();
+ read_failed_ = false;
+ element_index_ = 0;
+}
+
+int ElementsUploadDataStream::InitElements(size_t start_index) {
+ // Call Init() for all elements.
+ for (size_t i = start_index; i < element_readers_.size(); ++i) {
+ UploadElementReader* reader = element_readers_[i];
+ // When new_result is ERR_IO_PENDING, InitInternal() will be called
+ // with start_index == i + 1 when reader->Init() finishes.
+ int result = reader->Init(
+ base::Bind(&ElementsUploadDataStream::OnInitElementCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ i));
+ DCHECK(result != ERR_IO_PENDING || !reader->IsInMemory());
+ DCHECK_LE(result, OK);
+ if (result != OK)
+ return result;
+ }
+
+ uint64 total_size = 0;
+ for (size_t i = 0; i < element_readers_.size(); ++i) {
+ total_size += element_readers_[i]->GetContentLength();
+ }
+ SetSize(total_size);
+ return OK;
+}
+
+void ElementsUploadDataStream::OnInitElementCompleted(size_t index,
+ int result) {
+ DCHECK_NE(ERR_IO_PENDING, result);
+
+ // Check the last result.
+ if (result == OK)
+ result = InitElements(index + 1);
+
+ if (result != ERR_IO_PENDING)
+ OnInitCompleted(result);
+}
+
+int ElementsUploadDataStream::ReadElements(
+ const scoped_refptr<DrainableIOBuffer>& buf) {
+ while (!read_failed_ && element_index_ < element_readers_.size()) {
+ UploadElementReader* reader = element_readers_[element_index_];
+
+ if (reader->BytesRemaining() == 0) {
+ ++element_index_;
+ continue;
+ }
+
+ if (buf->BytesRemaining() == 0)
+ break;
+
+ int result = reader->Read(
+ buf.get(),
+ buf->BytesRemaining(),
+ base::Bind(&ElementsUploadDataStream::OnReadElementCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ buf));
+ if (result == ERR_IO_PENDING)
+ return ERR_IO_PENDING;
+ ProcessReadResult(buf, result);
+ }
+
+ if (read_failed_) {
+ // If an error occured during read operation, then pad with zero.
+ // Otherwise the server will hang waiting for the rest of the data.
+ int num_bytes_to_fill = std::min(
+ static_cast<uint64>(buf->BytesRemaining()),
+ size() - position() - buf->BytesConsumed());
+ DCHECK_LE(0, num_bytes_to_fill);
+ memset(buf->data(), 0, num_bytes_to_fill);
+ buf->DidConsume(num_bytes_to_fill);
+ }
+
+ return buf->BytesConsumed();
+}
+
+void ElementsUploadDataStream::OnReadElementCompleted(
+ const scoped_refptr<DrainableIOBuffer>& buf,
+ int result) {
+ ProcessReadResult(buf, result);
+
+ result = ReadElements(buf);
+ if (result != ERR_IO_PENDING)
+ OnReadCompleted(result);
+}
+
+void ElementsUploadDataStream::ProcessReadResult(
+ const scoped_refptr<DrainableIOBuffer>& buf,
+ int result) {
+ DCHECK_NE(ERR_IO_PENDING, result);
+ DCHECK(!read_failed_);
+
+ if (result >= 0) {
+ buf->DidConsume(result);
+ } else {
+ read_failed_ = true;
+ }
+}
+
+} // namespace net
diff --git a/chromium/net/base/elements_upload_data_stream.h b/chromium/net/base/elements_upload_data_stream.h
new file mode 100644
index 00000000000..5101114a3cc
--- /dev/null
+++ b/chromium/net/base/elements_upload_data_stream.h
@@ -0,0 +1,85 @@
+// 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.
+
+#ifndef NET_BASE_ELEMENTS_UPLOAD_DATA_STREAM_H_
+#define NET_BASE_ELEMENTS_UPLOAD_DATA_STREAM_H_
+
+#include "base/basictypes.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
+#include "net/base/net_export.h"
+#include "net/base/upload_data_stream.h"
+
+namespace net {
+
+class DrainableIOBuffer;
+class IOBuffer;
+class UploadElementReader;
+
+// A non-chunked UploadDataStream consisting of one or more UploadElements.
+class NET_EXPORT ElementsUploadDataStream : public UploadDataStream {
+ public:
+ ElementsUploadDataStream(ScopedVector<UploadElementReader> element_readers,
+ int64 identifier);
+
+ ~ElementsUploadDataStream() override;
+
+ // Creates an ElementsUploadDataStream with a single reader. Returns a
+ // scoped_ptr<UploadDataStream> for ease of use.
+ static scoped_ptr<UploadDataStream> CreateWithReader(
+ scoped_ptr<UploadElementReader> reader,
+ int64 identifier);
+
+ private:
+ // UploadDataStream implementation.
+ bool IsInMemory() const override;
+ const ScopedVector<UploadElementReader>* GetElementReaders() const override;
+ int InitInternal() override;
+ int ReadInternal(IOBuffer* buf, int buf_len) override;
+ void ResetInternal() override;
+
+ // Runs Init() for all element readers.
+ // This method is used to implement InitInternal().
+ int InitElements(size_t start_index);
+
+ // Called when the |index| element finishes initialization. If it succeeded,
+ // continues with the |index + 1| element. Calls OnInitCompleted on error or
+ // when all elements have been initialized.
+ void OnInitElementCompleted(size_t index, int result);
+
+ // Reads data from the element readers.
+ // This method is used to implement Read().
+ int ReadElements(const scoped_refptr<DrainableIOBuffer>& buf);
+
+ // Resumes pending read and calls OnReadCompleted with a result when
+ // necessary.
+ void OnReadElementCompleted(const scoped_refptr<DrainableIOBuffer>& buf,
+ int result);
+
+ // Processes result of UploadElementReader::Read(). If |result| indicates
+ // success, updates |buf|'s offset. Otherwise, sets |read_failed_| to true.
+ void ProcessReadResult(const scoped_refptr<DrainableIOBuffer>& buf,
+ int result);
+
+ ScopedVector<UploadElementReader> element_readers_;
+
+ // Index of the current upload element (i.e. the element currently being
+ // read). The index is used as a cursor to iterate over elements in
+ // |upload_data_|.
+ size_t element_index_;
+
+ // True if an error occcured during read operation.
+ bool read_failed_;
+
+ base::WeakPtrFactory<ElementsUploadDataStream> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElementsUploadDataStream);
+};
+
+} // namespace net
+
+#endif // NET_BASE_ELEMENTS_UPLOAD_DATA_STREAM_H_
diff --git a/chromium/net/base/upload_data_stream_unittest.cc b/chromium/net/base/elements_upload_data_stream_unittest.cc
index 90a78d24b52..1882e9a9224 100644
--- a/chromium/net/base/upload_data_stream_unittest.cc
+++ b/chromium/net/base/elements_upload_data_stream_unittest.cc
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/base/upload_data_stream.h"
+#include "net/base/elements_upload_data_stream.h"
#include <algorithm>
#include <vector>
#include "base/basictypes.h"
#include "base/bind.h"
-#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
@@ -20,6 +20,7 @@
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.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 "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -67,9 +68,9 @@ class MockUploadElementReader : public UploadElementReader {
// UploadElementReader overrides.
MOCK_METHOD1(Init, int(const CompletionCallback& callback));
- virtual uint64 GetContentLength() const OVERRIDE { return content_length_; }
- virtual uint64 BytesRemaining() const OVERRIDE { return bytes_remaining_; }
- virtual bool IsInMemory() const OVERRIDE { return is_in_memory_; }
+ virtual uint64 GetContentLength() const override { return content_length_; }
+ virtual uint64 BytesRemaining() const override { return bytes_remaining_; }
+ virtual bool IsInMemory() const override { return is_in_memory_; }
MOCK_METHOD3(Read, int(IOBuffer* buf,
int buf_length,
const CompletionCallback& callback));
@@ -122,13 +123,13 @@ class MockUploadElementReader : public UploadElementReader {
} // namespace
-class UploadDataStreamTest : public PlatformTest {
+class ElementsUploadDataStreamTest : public PlatformTest {
public:
- virtual void SetUp() {
+ void SetUp() override {
PlatformTest::SetUp();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
}
- virtual ~UploadDataStreamTest() {
+ ~ElementsUploadDataStreamTest() override {
element_readers_.clear();
base::RunLoop().RunUntilIdle();
}
@@ -141,35 +142,37 @@ class UploadDataStreamTest : public PlatformTest {
ScopedVector<UploadElementReader> element_readers_;
};
-TEST_F(UploadDataStreamTest, EmptyUploadData) {
- UploadDataStream stream(element_readers_.Pass(), 0);
- ASSERT_EQ(OK, stream.Init(CompletionCallback()));
- EXPECT_TRUE(stream.IsInMemory());
- EXPECT_EQ(0U, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_TRUE(stream.IsEOF());
+TEST_F(ElementsUploadDataStreamTest, EmptyUploadData) {
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ ASSERT_EQ(OK, stream->Init(CompletionCallback()));
+ EXPECT_TRUE(stream->IsInMemory());
+ EXPECT_EQ(0U, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_TRUE(stream->IsEOF());
}
-TEST_F(UploadDataStreamTest, ConsumeAllBytes) {
+TEST_F(ElementsUploadDataStreamTest, ConsumeAllBytes) {
element_readers_.push_back(new UploadBytesElementReader(
kTestData, kTestDataSize));
- UploadDataStream stream(element_readers_.Pass(), 0);
- ASSERT_EQ(OK, stream.Init(CompletionCallback()));
- EXPECT_TRUE(stream.IsInMemory());
- EXPECT_EQ(kTestDataSize, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ ASSERT_EQ(OK, stream->Init(CompletionCallback()));
+ EXPECT_TRUE(stream->IsInMemory());
+ EXPECT_EQ(kTestDataSize, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_FALSE(stream->IsEOF());
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
- while (!stream.IsEOF()) {
+ while (!stream->IsEOF()) {
int bytes_read =
- stream.Read(buf.get(), kTestBufferSize, CompletionCallback());
+ stream->Read(buf.get(), kTestBufferSize, CompletionCallback());
ASSERT_LE(0, bytes_read); // Not an error.
}
- EXPECT_EQ(kTestDataSize, stream.position());
- ASSERT_TRUE(stream.IsEOF());
+ EXPECT_EQ(kTestDataSize, stream->position());
+ ASSERT_TRUE(stream->IsEOF());
}
-TEST_F(UploadDataStreamTest, File) {
+TEST_F(ElementsUploadDataStreamTest, File) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -184,26 +187,27 @@ TEST_F(UploadDataStreamTest, File) {
base::Time()));
TestCompletionCallback init_callback;
- UploadDataStream stream(element_readers_.Pass(), 0);
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
ASSERT_EQ(OK, init_callback.WaitForResult());
- EXPECT_FALSE(stream.IsInMemory());
- EXPECT_EQ(kTestDataSize, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
+ EXPECT_FALSE(stream->IsInMemory());
+ EXPECT_EQ(kTestDataSize, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_FALSE(stream->IsEOF());
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
- while (!stream.IsEOF()) {
+ while (!stream->IsEOF()) {
TestCompletionCallback read_callback;
ASSERT_EQ(
ERR_IO_PENDING,
- stream.Read(buf.get(), kTestBufferSize, read_callback.callback()));
+ stream->Read(buf.get(), kTestBufferSize, read_callback.callback()));
ASSERT_LE(0, read_callback.WaitForResult()); // Not an error.
}
- EXPECT_EQ(kTestDataSize, stream.position());
- ASSERT_TRUE(stream.IsEOF());
+ EXPECT_EQ(kTestDataSize, stream->position());
+ ASSERT_TRUE(stream->IsEOF());
}
-TEST_F(UploadDataStreamTest, FileSmallerThanLength) {
+TEST_F(ElementsUploadDataStreamTest, FileSmallerThanLength) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -222,32 +226,33 @@ TEST_F(UploadDataStreamTest, FileSmallerThanLength) {
base::Time()));
TestCompletionCallback init_callback;
- UploadDataStream stream(element_readers_.Pass(), 0);
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
ASSERT_EQ(OK, init_callback.WaitForResult());
- EXPECT_FALSE(stream.IsInMemory());
- EXPECT_EQ(kFakeSize, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
+ EXPECT_FALSE(stream->IsInMemory());
+ EXPECT_EQ(kFakeSize, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_FALSE(stream->IsEOF());
uint64 read_counter = 0;
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
- while (!stream.IsEOF()) {
+ while (!stream->IsEOF()) {
TestCompletionCallback read_callback;
ASSERT_EQ(
ERR_IO_PENDING,
- stream.Read(buf.get(), kTestBufferSize, read_callback.callback()));
+ stream->Read(buf.get(), kTestBufferSize, read_callback.callback()));
int bytes_read = read_callback.WaitForResult();
ASSERT_LE(0, bytes_read); // Not an error.
read_counter += bytes_read;
- EXPECT_EQ(read_counter, stream.position());
+ EXPECT_EQ(read_counter, stream->position());
}
// UpdateDataStream will pad out the file with 0 bytes so that the HTTP
// transaction doesn't hang. Therefore we expected the full size.
EXPECT_EQ(kFakeSize, read_counter);
- EXPECT_EQ(read_counter, stream.position());
+ EXPECT_EQ(read_counter, stream->position());
}
-TEST_F(UploadDataStreamTest, ReadErrorSync) {
+TEST_F(ElementsUploadDataStreamTest, ReadErrorSync) {
// This element cannot be read.
MockUploadElementReader* reader =
new MockUploadElementReader(kTestDataSize, true);
@@ -259,13 +264,14 @@ TEST_F(UploadDataStreamTest, ReadErrorSync) {
element_readers_.push_back(new UploadBytesElementReader(
kTestData, kTestDataSize));
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
// Run Init().
- ASSERT_EQ(OK, stream.Init(CompletionCallback()));
- EXPECT_EQ(kTestDataSize*2, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
+ ASSERT_EQ(OK, stream->Init(CompletionCallback()));
+ EXPECT_EQ(kTestDataSize*2, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_FALSE(stream->IsEOF());
// Prepare a buffer filled with non-zero data.
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
@@ -273,16 +279,16 @@ TEST_F(UploadDataStreamTest, ReadErrorSync) {
// Read() results in success even when the reader returns error.
EXPECT_EQ(static_cast<int>(kTestDataSize * 2),
- stream.Read(buf.get(), kTestBufferSize, CompletionCallback()));
- EXPECT_EQ(kTestDataSize * 2, stream.position());
- EXPECT_TRUE(stream.IsEOF());
+ stream->Read(buf.get(), kTestBufferSize, CompletionCallback()));
+ EXPECT_EQ(kTestDataSize * 2, stream->position());
+ EXPECT_TRUE(stream->IsEOF());
// The buffer is filled with zero.
EXPECT_EQ(static_cast<int>(kTestDataSize*2),
std::count(buf->data(), buf->data() + kTestBufferSize, 0));
}
-TEST_F(UploadDataStreamTest, ReadErrorAsync) {
+TEST_F(ElementsUploadDataStreamTest, ReadErrorAsync) {
// This element cannot be read.
MockUploadElementReader* reader =
new MockUploadElementReader(kTestDataSize, false);
@@ -294,15 +300,16 @@ TEST_F(UploadDataStreamTest, ReadErrorAsync) {
element_readers_.push_back(new UploadBytesElementReader(
kTestData, kTestDataSize));
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
// Run Init().
TestCompletionCallback init_callback;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
EXPECT_EQ(OK, init_callback.WaitForResult());
- EXPECT_EQ(kTestDataSize*2, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_FALSE(stream->IsEOF());
// Prepare a buffer filled with non-zero data.
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
@@ -311,17 +318,17 @@ TEST_F(UploadDataStreamTest, ReadErrorAsync) {
// Read() results in success even when the reader returns error.
TestCompletionCallback read_callback;
ASSERT_EQ(ERR_IO_PENDING,
- stream.Read(buf.get(), kTestBufferSize, read_callback.callback()));
+ stream->Read(buf.get(), kTestBufferSize, read_callback.callback()));
EXPECT_EQ(static_cast<int>(kTestDataSize * 2), read_callback.WaitForResult());
- EXPECT_EQ(kTestDataSize*2, stream.position());
- EXPECT_TRUE(stream.IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->position());
+ EXPECT_TRUE(stream->IsEOF());
// The buffer is filled with zero.
EXPECT_EQ(static_cast<int>(kTestDataSize*2),
std::count(buf->data(), buf->data() + kTestBufferSize, 0));
}
-TEST_F(UploadDataStreamTest, FileAndBytes) {
+TEST_F(ElementsUploadDataStreamTest, FileAndBytes) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -342,49 +349,29 @@ TEST_F(UploadDataStreamTest, FileAndBytes) {
const uint64 kStreamSize = kTestDataSize + kFileRangeLength;
TestCompletionCallback init_callback;
- UploadDataStream stream(element_readers_.Pass(), 0);
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
ASSERT_EQ(OK, init_callback.WaitForResult());
- EXPECT_FALSE(stream.IsInMemory());
- EXPECT_EQ(kStreamSize, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
+ EXPECT_FALSE(stream->IsInMemory());
+ EXPECT_EQ(kStreamSize, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_FALSE(stream->IsEOF());
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
- while (!stream.IsEOF()) {
+ while (!stream->IsEOF()) {
TestCompletionCallback read_callback;
const int result =
- stream.Read(buf.get(), kTestBufferSize, read_callback.callback());
+ stream->Read(buf.get(), kTestBufferSize, read_callback.callback());
const int bytes_read =
result != ERR_IO_PENDING ? result : read_callback.WaitForResult();
ASSERT_LE(0, bytes_read); // Not an error.
}
- EXPECT_EQ(kStreamSize, stream.position());
- ASSERT_TRUE(stream.IsEOF());
-}
-
-TEST_F(UploadDataStreamTest, Chunk) {
- const uint64 kStreamSize = kTestDataSize*2;
- UploadDataStream stream(UploadDataStream::CHUNKED, 0);
- stream.AppendChunk(kTestData, kTestDataSize, false);
- stream.AppendChunk(kTestData, kTestDataSize, true);
-
- ASSERT_EQ(OK, stream.Init(CompletionCallback()));
- EXPECT_FALSE(stream.IsInMemory());
- EXPECT_EQ(0U, stream.size()); // Content-Length is 0 for chunked data.
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
- scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
- while (!stream.IsEOF()) {
- int bytes_read =
- stream.Read(buf.get(), kTestBufferSize, CompletionCallback());
- ASSERT_LE(0, bytes_read); // Not an error.
- }
- EXPECT_EQ(kStreamSize, stream.position());
- ASSERT_TRUE(stream.IsEOF());
+ EXPECT_EQ(kStreamSize, stream->position());
+ ASSERT_TRUE(stream->IsEOF());
}
// Init() with on-memory and not-on-memory readers.
-TEST_F(UploadDataStreamTest, InitAsync) {
+TEST_F(ElementsUploadDataStreamTest, InitAsync) {
// Create UploadDataStream with mock readers.
MockUploadElementReader* reader = NULL;
@@ -408,16 +395,17 @@ TEST_F(UploadDataStreamTest, InitAsync) {
EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
element_readers_.push_back(reader);
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
// Run Init().
TestCompletionCallback callback;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(callback.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(callback.callback()));
EXPECT_EQ(OK, callback.WaitForResult());
}
// Init() of a reader fails asynchronously.
-TEST_F(UploadDataStreamTest, InitAsyncFailureAsync) {
+TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureAsync) {
// Create UploadDataStream with a mock reader.
MockUploadElementReader* reader = NULL;
@@ -425,16 +413,17 @@ TEST_F(UploadDataStreamTest, InitAsyncFailureAsync) {
reader->SetAsyncInitExpectation(ERR_FAILED);
element_readers_.push_back(reader);
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
// Run Init().
TestCompletionCallback callback;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(callback.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(callback.callback()));
EXPECT_EQ(ERR_FAILED, callback.WaitForResult());
}
// Init() of a reader fails synchronously.
-TEST_F(UploadDataStreamTest, InitAsyncFailureSync) {
+TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureSync) {
// Create UploadDataStream with mock readers.
MockUploadElementReader* reader = NULL;
@@ -446,34 +435,36 @@ TEST_F(UploadDataStreamTest, InitAsyncFailureSync) {
EXPECT_CALL(*reader, Init(_)).WillOnce(Return(ERR_FAILED));
element_readers_.push_back(reader);
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
// Run Init().
TestCompletionCallback callback;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(callback.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(callback.callback()));
EXPECT_EQ(ERR_FAILED, callback.WaitForResult());
}
// Read with a buffer whose size is same as the data.
-TEST_F(UploadDataStreamTest, ReadAsyncWithExactSizeBuffer) {
+TEST_F(ElementsUploadDataStreamTest, ReadAsyncWithExactSizeBuffer) {
element_readers_.push_back(new UploadBytesElementReader(
kTestData, kTestDataSize));
- UploadDataStream stream(element_readers_.Pass(), 0);
-
- ASSERT_EQ(OK, stream.Init(CompletionCallback()));
- EXPECT_TRUE(stream.IsInMemory());
- EXPECT_EQ(kTestDataSize, stream.size());
- EXPECT_EQ(0U, stream.position());
- EXPECT_FALSE(stream.IsEOF());
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
+
+ ASSERT_EQ(OK, stream->Init(CompletionCallback()));
+ EXPECT_TRUE(stream->IsInMemory());
+ EXPECT_EQ(kTestDataSize, stream->size());
+ EXPECT_EQ(0U, stream->position());
+ EXPECT_FALSE(stream->IsEOF());
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestDataSize);
- int bytes_read = stream.Read(buf.get(), kTestDataSize, CompletionCallback());
+ int bytes_read = stream->Read(buf.get(), kTestDataSize, CompletionCallback());
ASSERT_EQ(static_cast<int>(kTestDataSize), bytes_read); // Not an error.
- EXPECT_EQ(kTestDataSize, stream.position());
- ASSERT_TRUE(stream.IsEOF());
+ EXPECT_EQ(kTestDataSize, stream->position());
+ ASSERT_TRUE(stream->IsEOF());
}
// Async Read() with on-memory and not-on-memory readers.
-TEST_F(UploadDataStreamTest, ReadAsync) {
+TEST_F(ElementsUploadDataStreamTest, ReadAsync) {
// Create UploadDataStream with mock readers.
MockUploadElementReader* reader = NULL;
@@ -497,11 +488,12 @@ TEST_F(UploadDataStreamTest, ReadAsync) {
reader->SetReadExpectation(kTestDataSize);
element_readers_.push_back(reader);
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
// Run Init().
TestCompletionCallback init_callback;
- EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
EXPECT_EQ(OK, init_callback.WaitForResult());
scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
@@ -509,28 +501,29 @@ TEST_F(UploadDataStreamTest, ReadAsync) {
// Consume the first element.
TestCompletionCallback read_callback1;
EXPECT_EQ(static_cast<int>(kTestDataSize),
- stream.Read(buf.get(), kTestDataSize, read_callback1.callback()));
+ stream->Read(buf.get(), kTestDataSize, read_callback1.callback()));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(read_callback1.have_result());
// Consume the second element.
TestCompletionCallback read_callback2;
ASSERT_EQ(ERR_IO_PENDING,
- stream.Read(buf.get(), kTestDataSize, read_callback2.callback()));
+ stream->Read(buf.get(), kTestDataSize, read_callback2.callback()));
EXPECT_EQ(static_cast<int>(kTestDataSize), read_callback2.WaitForResult());
// Consume the third and the fourth elements.
TestCompletionCallback read_callback3;
ASSERT_EQ(
ERR_IO_PENDING,
- stream.Read(buf.get(), kTestDataSize * 2, read_callback3.callback()));
+ stream->Read(buf.get(), kTestDataSize * 2, read_callback3.callback()));
EXPECT_EQ(static_cast<int>(kTestDataSize * 2),
read_callback3.WaitForResult());
}
-void UploadDataStreamTest::FileChangedHelper(const base::FilePath& file_path,
- const base::Time& time,
- bool error_expected) {
+void ElementsUploadDataStreamTest::FileChangedHelper(
+ const base::FilePath& file_path,
+ const base::Time& time,
+ bool error_expected) {
// Don't use element_readers_ here, as this function is called twice, and
// reusing element_readers_ is wrong.
ScopedVector<UploadElementReader> element_readers;
@@ -538,8 +531,9 @@ void UploadDataStreamTest::FileChangedHelper(const base::FilePath& file_path,
base::MessageLoopProxy::current().get(), file_path, 1, 2, time));
TestCompletionCallback init_callback;
- UploadDataStream stream(element_readers.Pass(), 0);
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers.Pass(), 0));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
int error_code = init_callback.WaitForResult();
if (error_expected)
ASSERT_EQ(ERR_UPLOAD_FILE_CHANGED, error_code);
@@ -547,7 +541,7 @@ void UploadDataStreamTest::FileChangedHelper(const base::FilePath& file_path,
ASSERT_EQ(OK, error_code);
}
-TEST_F(UploadDataStreamTest, FileChanged) {
+TEST_F(ElementsUploadDataStreamTest, FileChanged) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -566,7 +560,7 @@ TEST_F(UploadDataStreamTest, FileChanged) {
true);
}
-TEST_F(UploadDataStreamTest, MultipleInit) {
+TEST_F(ElementsUploadDataStreamTest, MultipleInit) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -582,35 +576,36 @@ TEST_F(UploadDataStreamTest, MultipleInit) {
0,
kuint64max,
base::Time()));
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
std::string expected_data(kTestData, kTestData + kTestDataSize);
expected_data += expected_data;
// Call Init().
TestCompletionCallback init_callback1;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback()));
ASSERT_EQ(OK, init_callback1.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read.
- EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
- EXPECT_TRUE(stream.IsEOF());
+ EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get()));
+ EXPECT_TRUE(stream->IsEOF());
// Call Init() again to reset.
TestCompletionCallback init_callback2;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback()));
ASSERT_EQ(OK, init_callback2.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read again.
- EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
- EXPECT_TRUE(stream.IsEOF());
+ EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get()));
+ EXPECT_TRUE(stream->IsEOF());
}
-TEST_F(UploadDataStreamTest, MultipleInitAsync) {
+TEST_F(ElementsUploadDataStreamTest, MultipleInitAsync) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -627,33 +622,34 @@ TEST_F(UploadDataStreamTest, MultipleInitAsync) {
0,
kuint64max,
base::Time()));
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
std::string expected_data(kTestData, kTestData + kTestDataSize);
expected_data += expected_data;
// Call Init().
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(test_callback.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(test_callback.callback()));
EXPECT_EQ(OK, test_callback.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read.
- EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
- EXPECT_TRUE(stream.IsEOF());
+ EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get()));
+ EXPECT_TRUE(stream->IsEOF());
// Call Init() again to reset.
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(test_callback.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(test_callback.callback()));
EXPECT_EQ(OK, test_callback.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read again.
- EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
- EXPECT_TRUE(stream.IsEOF());
+ EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get()));
+ EXPECT_TRUE(stream->IsEOF());
}
-TEST_F(UploadDataStreamTest, InitToReset) {
+TEST_F(ElementsUploadDataStreamTest, InitToReset) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -669,7 +665,8 @@ TEST_F(UploadDataStreamTest, InitToReset) {
0,
kuint64max,
base::Time()));
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
expected_data.insert(expected_data.end(), expected_data.begin(),
@@ -677,10 +674,10 @@ TEST_F(UploadDataStreamTest, InitToReset) {
// Call Init().
TestCompletionCallback init_callback1;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback()));
EXPECT_EQ(OK, init_callback1.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read some.
TestCompletionCallback read_callback1;
@@ -688,29 +685,30 @@ TEST_F(UploadDataStreamTest, InitToReset) {
scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
EXPECT_EQ(
ERR_IO_PENDING,
- stream.Read(wrapped_buffer.get(), buf.size(), read_callback1.callback()));
+ stream->Read(wrapped_buffer.get(), buf.size(),
+ read_callback1.callback()));
EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
- EXPECT_EQ(buf.size(), stream.position());
+ EXPECT_EQ(buf.size(), stream->position());
// Call Init to reset the state.
TestCompletionCallback init_callback2;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback()));
EXPECT_EQ(OK, init_callback2.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read.
TestCompletionCallback read_callback2;
std::vector<char> buf2(kTestDataSize*2);
scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
EXPECT_EQ(ERR_IO_PENDING,
- stream.Read(
+ stream->Read(
wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
EXPECT_EQ(expected_data, buf2);
}
-TEST_F(UploadDataStreamTest, InitDuringAsyncInit) {
+TEST_F(ElementsUploadDataStreamTest, InitDuringAsyncInit) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -726,7 +724,8 @@ TEST_F(UploadDataStreamTest, InitDuringAsyncInit) {
0,
kuint64max,
base::Time()));
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
expected_data.insert(expected_data.end(), expected_data.begin(),
@@ -734,31 +733,31 @@ TEST_F(UploadDataStreamTest, InitDuringAsyncInit) {
// Start Init.
TestCompletionCallback init_callback1;
- EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback()));
// Call Init again to cancel the previous init.
TestCompletionCallback init_callback2;
- EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback()));
EXPECT_EQ(OK, init_callback2.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read.
TestCompletionCallback read_callback2;
std::vector<char> buf2(kTestDataSize*2);
scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
EXPECT_EQ(ERR_IO_PENDING,
- stream.Read(
+ stream->Read(
wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
EXPECT_EQ(expected_data, buf2);
- EXPECT_TRUE(stream.IsEOF());
+ EXPECT_TRUE(stream->IsEOF());
// Make sure callbacks are not called for cancelled operations.
EXPECT_FALSE(init_callback1.have_result());
}
-TEST_F(UploadDataStreamTest, InitDuringAsyncRead) {
+TEST_F(ElementsUploadDataStreamTest, InitDuringAsyncRead) {
base::FilePath temp_file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&temp_file_path));
@@ -774,7 +773,8 @@ TEST_F(UploadDataStreamTest, InitDuringAsyncRead) {
0,
kuint64max,
base::Time()));
- UploadDataStream stream(element_readers_.Pass(), 0);
+ scoped_ptr<UploadDataStream> stream(
+ new ElementsUploadDataStream(element_readers_.Pass(), 0));
std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
expected_data.insert(expected_data.end(), expected_data.begin(),
@@ -782,10 +782,10 @@ TEST_F(UploadDataStreamTest, InitDuringAsyncRead) {
// Call Init().
TestCompletionCallback init_callback1;
- ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
+ ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback()));
EXPECT_EQ(OK, init_callback1.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Start reading.
TestCompletionCallback read_callback1;
@@ -793,25 +793,26 @@ TEST_F(UploadDataStreamTest, InitDuringAsyncRead) {
scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
EXPECT_EQ(
ERR_IO_PENDING,
- stream.Read(wrapped_buffer.get(), buf.size(), read_callback1.callback()));
+ stream->Read(wrapped_buffer.get(), buf.size(),
+ read_callback1.callback()));
// Call Init to cancel the previous read.
TestCompletionCallback init_callback2;
- EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback()));
EXPECT_EQ(OK, init_callback2.WaitForResult());
- EXPECT_FALSE(stream.IsEOF());
- EXPECT_EQ(kTestDataSize*2, stream.size());
+ EXPECT_FALSE(stream->IsEOF());
+ EXPECT_EQ(kTestDataSize*2, stream->size());
// Read.
TestCompletionCallback read_callback2;
std::vector<char> buf2(kTestDataSize*2);
scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
EXPECT_EQ(ERR_IO_PENDING,
- stream.Read(
+ stream->Read(
wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
EXPECT_EQ(expected_data, buf2);
- EXPECT_TRUE(stream.IsEOF());
+ EXPECT_TRUE(stream->IsEOF());
// Make sure callbacks are not called for cancelled operations.
EXPECT_FALSE(read_callback1.have_result());
diff --git a/chromium/net/base/escape.cc b/chromium/net/base/escape.cc
index ab70f1db301..7a068f87ee5 100644
--- a/chromium/net/base/escape.cc
+++ b/chromium/net/base/escape.cc
@@ -39,15 +39,21 @@ struct Charmap {
// Given text to escape and a Charmap defining which values to escape,
// return an escaped string. If use_plus is true, spaces are converted
// to +, otherwise, if spaces are in the charmap, they are converted to
-// %20.
-std::string Escape(const std::string& text, const Charmap& charmap,
- bool use_plus) {
+// %20. And if keep_escaped is true, %XX will be kept as it is, otherwise, if
+// '%' is in the charmap, it is converted to %25.
+std::string Escape(const std::string& text,
+ const Charmap& charmap,
+ bool use_plus,
+ bool keep_escaped = false) {
std::string escaped;
escaped.reserve(text.length() * 3);
for (unsigned int i = 0; i < text.length(); ++i) {
unsigned char c = static_cast<unsigned char>(text[i]);
if (use_plus && ' ' == c) {
escaped.push_back('+');
+ } else if (keep_escaped && '%' == c && i + 2 < text.length() &&
+ IsHexDigit(text[i + 1]) && IsHexDigit(text[i + 2])) {
+ escaped.push_back('%');
} else if (charmap.Contains(c)) {
escaped.push_back('%');
escaped.push_back(IntToHex(c >> 4));
@@ -114,12 +120,50 @@ bool UnescapeUnsignedCharAtIndex(const STR& escaped_text,
static_cast<typename STR::value_type>(escaped_text[index + 2]));
if (IsHexDigit(most_sig_digit) && IsHexDigit(least_sig_digit)) {
*value = HexDigitToInt(most_sig_digit) * 16 +
- HexDigitToInt(least_sig_digit);
+ HexDigitToInt(least_sig_digit);
return true;
}
return false;
}
+// Returns true if there is an Arabic Language Mark at |index|. |first_byte|
+// is the byte at |index|.
+template<typename STR>
+bool HasArabicLanguageMarkAtIndex(const STR& escaped_text,
+ unsigned char first_byte,
+ size_t index) {
+ if (first_byte != 0xD8)
+ return false;
+ unsigned char second_byte;
+ if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 3, &second_byte))
+ return false;
+ return second_byte == 0x9c;
+}
+
+// Returns true if there is a BiDi control char at |index|. |first_byte| is the
+// byte at |index|.
+template<typename STR>
+bool HasThreeByteBidiControlCharAtIndex(const STR& escaped_text,
+ unsigned char first_byte,
+ size_t index) {
+ if (first_byte != 0xE2)
+ return false;
+ unsigned char second_byte;
+ if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 3, &second_byte))
+ return false;
+ if (second_byte != 0x80 && second_byte != 0x81)
+ return false;
+ unsigned char third_byte;
+ if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 6, &third_byte))
+ return false;
+ if (second_byte == 0x80) {
+ return third_byte == 0x8E ||
+ third_byte == 0x8F ||
+ (third_byte >= 0xAA && third_byte <= 0xAE);
+ }
+ return third_byte >= 0xA6 && third_byte <= 0xA9;
+}
+
// Unescapes |escaped_text| according to |rules|, returning the resulting
// string. Fills in an |adjustments| parameter, if non-NULL, so it reflects
// the alterations done to the string that are not one-character-to-one-
@@ -172,27 +216,21 @@ STR UnescapeURLWithAdjustmentsImpl(
// U+2067 RIGHT-TO-LEFT ISOLATE (%E2%81%A7)
// U+2068 FIRST STRONG ISOLATE (%E2%81%A8)
// U+2069 POP DIRECTIONAL ISOLATE (%E2%81%A9)
-
- unsigned char second_byte;
- // Check for ALM.
- if ((first_byte == 0xD8) &&
- UnescapeUnsignedCharAtIndex(escaped_text, i + 3, &second_byte) &&
- (second_byte == 0x9c)) {
- result.append(escaped_text, i, 6);
- i += 5;
- continue;
- }
-
- // Check for other BiDi control characters.
- if ((first_byte == 0xE2) &&
- UnescapeUnsignedCharAtIndex(escaped_text, i + 3, &second_byte) &&
- ((second_byte == 0x80) || (second_byte == 0x81))) {
- unsigned char third_byte;
- if (UnescapeUnsignedCharAtIndex(escaped_text, i + 6, &third_byte) &&
- ((second_byte == 0x80) ?
- ((third_byte == 0x8E) || (third_byte == 0x8F) ||
- ((third_byte >= 0xAA) && (third_byte <= 0xAE))) :
- ((third_byte >= 0xA6) && (third_byte <= 0xA9)))) {
+ //
+ // However, some schemes such as data: and file: need to parse the exact
+ // binary data when loading the URL. For that reason, CONTROL_CHARS allows
+ // unescaping BiDi control characters.
+ // DO NOT use CONTROL_CHARS if the parsed URL is going to be displayed
+ // in the UI.
+ if (!(rules & UnescapeRule::CONTROL_CHARS)) {
+ if (HasArabicLanguageMarkAtIndex(escaped_text, first_byte, i)) {
+ // Keep Arabic Language Mark escaped.
+ result.append(escaped_text, i, 6);
+ i += 5;
+ continue;
+ }
+ if (HasThreeByteBidiControlCharAtIndex(escaped_text, first_byte, i)) {
+ // Keep BiDi control char escaped.
result.append(escaped_text, i, 9);
i += 8;
continue;
@@ -244,7 +282,7 @@ void AppendEscapedCharForHTMLImpl(typename str::value_type c, str* output) {
{ '\'', "&#39;" },
};
size_t k;
- for (k = 0; k < ARRAYSIZE_UNSAFE(kCharsToEscape); ++k) {
+ for (k = 0; k < arraysize(kCharsToEscape); ++k) {
if (c == kCharsToEscape[k].key) {
const char* p = kCharsToEscape[k].replacement;
while (*p)
@@ -252,7 +290,7 @@ void AppendEscapedCharForHTMLImpl(typename str::value_type c, str* output) {
break;
}
}
- if (k == ARRAYSIZE_UNSAFE(kCharsToEscape))
+ if (k == arraysize(kCharsToEscape))
output->push_back(c);
}
@@ -293,9 +331,9 @@ static const Charmap kNonASCIICharmap = {{
}};
// Everything except alphanumerics, the reserved characters(;/?:@&=+$,) and
-// !'()*-._~%
+// !'()*-._~#[]
static const Charmap kExternalHandlerCharmap = {{
- 0xffffffffL, 0x5000080dL, 0x68000000L, 0xb8000001L,
+ 0xffffffffL, 0x50000025L, 0x50000000L, 0xb8000001L,
0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
}};
@@ -318,7 +356,7 @@ std::string EscapeNonASCII(const std::string& input) {
}
std::string EscapeExternalHandlerValue(const std::string& text) {
- return Escape(text, kExternalHandlerCharmap, false);
+ return Escape(text, kExternalHandlerCharmap, false, true);
}
void AppendEscapedCharForHTML(char c, std::string* output) {
@@ -385,14 +423,14 @@ base::string16 UnescapeForHTML(const base::string16& input) {
if (input.find(base::ASCIIToUTF16("&")) == std::string::npos)
return input;
- base::string16 ampersand_chars[ARRAYSIZE_UNSAFE(kEscapeToChars)];
+ base::string16 ampersand_chars[arraysize(kEscapeToChars)];
base::string16 text(input);
for (base::string16::iterator iter = text.begin();
iter != text.end(); ++iter) {
if (*iter == '&') {
// Potential ampersand encode char.
size_t index = iter - text.begin();
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kEscapeToChars); i++) {
+ for (size_t i = 0; i < arraysize(kEscapeToChars); i++) {
if (ampersand_chars[i].empty()) {
ampersand_chars[i] =
base::ASCIIToUTF16(kEscapeToChars[i].ampersand_code);
diff --git a/chromium/net/base/escape.h b/chromium/net/base/escape.h
index 1915d244188..6c92333ba3d 100644
--- a/chromium/net/base/escape.h
+++ b/chromium/net/base/escape.h
@@ -42,8 +42,8 @@ NET_EXPORT std::string EscapeNonASCII(const std::string& input);
// Escapes characters in text suitable for use as an external protocol handler
// command.
-// We %XX everything except alphanumerics and %-_.!~*'() and the restricted
-// chracters (;/?:@&=+$,).
+// We %XX everything except alphanumerics and -_.!~*'() and the restricted
+// chracters (;/?:@&=+$,#[]) and a valid percent escape sequence (%XX).
NET_EXPORT std::string EscapeExternalHandlerValue(const std::string& text);
// Appends the given character to the output string, escaping the character if
@@ -88,7 +88,10 @@ class UnescapeRule {
// Unescapes control characters such as %01. This INCLUDES NULLs. This is
// used for rare cases such as data: URL decoding where the result is binary
- // data. You should not use this for normal URLs!
+ // data. This flag also unescapes BiDi control characters.
+ //
+ // DO NOT use CONTROL_CHARS if the URL is going to be displayed in the UI
+ // for security reasons.
CONTROL_CHARS = 8,
// URL queries use "+" for space. This flag controls that replacement.
diff --git a/chromium/net/base/escape_unittest.cc b/chromium/net/base/escape_unittest.cc
index 74ae29336d8..4d3bcbdd40c 100644
--- a/chromium/net/base/escape_unittest.cc
+++ b/chromium/net/base/escape_unittest.cc
@@ -232,7 +232,8 @@ TEST(EscapeTest, UnescapeURLComponent) {
{L"Some%20random text %25%E2%80%84OK", UnescapeRule::NORMAL,
L"Some%20random text %25\xE2\x80\x84OK"},
- // BiDi Control characters should not be unescaped.
+ // BiDi Control characters should not be unescaped unless explicity told to
+ // do so with UnescapeRule::CONTROL_CHARS
{L"Some%20random text %25%D8%9COK", UnescapeRule::NORMAL,
L"Some%20random text %25%D8%9COK"},
{L"Some%20random text %25%E2%80%8EOK", UnescapeRule::NORMAL,
@@ -249,6 +250,31 @@ TEST(EscapeTest, UnescapeURLComponent) {
L"Some%20random text %25%E2%81%A6OK"},
{L"Some%20random text %25%E2%81%A9OK", UnescapeRule::NORMAL,
L"Some%20random text %25%E2%81%A9OK"},
+ // UnescapeRule::CONTROL_CHARS should unescape BiDi Control characters.
+ {L"Some%20random text %25%D8%9COK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xD8\x9COK"},
+ {L"Some%20random text %25%E2%80%8EOK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xE2\x80\x8EOK"},
+ {L"Some%20random text %25%E2%80%8FOK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xE2\x80\x8FOK"},
+ {L"Some%20random text %25%E2%80%AAOK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xE2\x80\xAAOK"},
+ {L"Some%20random text %25%E2%80%ABOK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xE2\x80\xABOK"},
+ {L"Some%20random text %25%E2%80%AEOK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xE2\x80\xAEOK"},
+ {L"Some%20random text %25%E2%81%A6OK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xE2\x81\xA6OK"},
+ {L"Some%20random text %25%E2%81%A9OK",
+ UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+ L"Some%20random text %25\xE2\x81\xA9OK"},
{L"Some%20random text %25%2dOK", UnescapeRule::SPACES,
L"Some random text %25-OK"},
@@ -453,6 +479,43 @@ TEST(EscapeTest, UnescapeForHTML) {
}
}
+TEST(EscapeTest, EscapeExternalHandlerValue) {
+ ASSERT_EQ(
+ // Escaped
+ "%02%0A%1D%20!%22#$%25&'()*+,-./0123456789:;"
+ "%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz"
+ "%7B%7C%7D~%7F%80%FF",
+ // Most of the character space we care about, un-escaped
+ EscapeExternalHandlerValue(
+ "\x02\n\x1d !\"#$%&'()*+,-./0123456789:;"
+ "<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "[\\]^_`abcdefghijklmnopqrstuvwxyz"
+ "{|}~\x7f\x80\xff"));
+
+ ASSERT_EQ(
+ "!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_"
+ "abcdefghijklmnopqrstuvwxyz~",
+ EscapeExternalHandlerValue(
+ "!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_"
+ "abcdefghijklmnopqrstuvwxyz~"));
+
+ ASSERT_EQ("%258k", EscapeExternalHandlerValue("%8k"));
+ ASSERT_EQ("a%25", EscapeExternalHandlerValue("a%"));
+ ASSERT_EQ("%25a", EscapeExternalHandlerValue("%a"));
+ ASSERT_EQ("a%258", EscapeExternalHandlerValue("a%8"));
+ ASSERT_EQ("%ab", EscapeExternalHandlerValue("%ab"));
+ ASSERT_EQ("%AB", EscapeExternalHandlerValue("%AB"));
+
+ ASSERT_EQ("http://example.com/path/sub?q=a%7Cb%7Cc&q=1%7C2%7C3#ref%7C",
+ EscapeExternalHandlerValue(
+ "http://example.com/path/sub?q=a|b|c&q=1|2|3#ref|"));
+ ASSERT_EQ("http://example.com/path/sub?q=a%7Cb%7Cc&q=1%7C2%7C3#ref%7C",
+ EscapeExternalHandlerValue(
+ "http://example.com/path/sub?q=a%7Cb%7Cc&q=1%7C2%7C3#ref%7C"));
+ ASSERT_EQ("http://[2001:db8:0:1]:80",
+ EscapeExternalHandlerValue("http://[2001:db8:0:1]:80"));
+}
} // namespace
} // namespace net
diff --git a/chromium/net/base/file_stream.cc b/chromium/net/base/file_stream.cc
index bf56a49e8c0..cadbaed663e 100644
--- a/chromium/net/base/file_stream.cc
+++ b/chromium/net/base/file_stream.cc
@@ -30,12 +30,12 @@ int FileStream::Open(const base::FilePath& path, int open_flags,
}
DCHECK(open_flags & base::File::FLAG_ASYNC);
- context_->OpenAsync(path, open_flags, callback);
+ context_->Open(path, open_flags, callback);
return ERR_IO_PENDING;
}
int FileStream::Close(const CompletionCallback& callback) {
- context_->CloseAsync(callback);
+ context_->Close(callback);
return ERR_IO_PENDING;
}
@@ -43,13 +43,13 @@ bool FileStream::IsOpen() const {
return context_->file().IsValid();
}
-int FileStream::Seek(Whence whence,
+int FileStream::Seek(base::File::Whence whence,
int64 offset,
const Int64CompletionCallback& callback) {
if (!IsOpen())
return ERR_UNEXPECTED;
- context_->SeekAsync(whence, offset, callback);
+ context_->Seek(whence, offset, callback);
return ERR_IO_PENDING;
}
@@ -62,7 +62,7 @@ int FileStream::Read(IOBuffer* buf,
// read(..., 0) will return 0, which indicates end-of-file.
DCHECK_GT(buf_len, 0);
- return context_->ReadAsync(buf, buf_len, callback);
+ return context_->Read(buf, buf_len, callback);
}
int FileStream::Write(IOBuffer* buf,
@@ -71,17 +71,15 @@ int FileStream::Write(IOBuffer* buf,
if (!IsOpen())
return ERR_UNEXPECTED;
- // write(..., 0) will return 0, which indicates end-of-file.
- DCHECK_GT(buf_len, 0);
-
- return context_->WriteAsync(buf, buf_len, callback);
+ DCHECK_GE(buf_len, 0);
+ return context_->Write(buf, buf_len, callback);
}
int FileStream::Flush(const CompletionCallback& callback) {
if (!IsOpen())
return ERR_UNEXPECTED;
- context_->FlushAsync(callback);
+ context_->Flush(callback);
return ERR_IO_PENDING;
}
diff --git a/chromium/net/base/file_stream.h b/chromium/net/base/file_stream.h
index 57011b77dec..89db65e15b5 100644
--- a/chromium/net/base/file_stream.h
+++ b/chromium/net/base/file_stream.h
@@ -12,7 +12,6 @@
#include "base/files/file.h"
#include "net/base/completion_callback.h"
-#include "net/base/file_stream_whence.h"
#include "net/base/net_export.h"
namespace base {
@@ -69,7 +68,7 @@ class NET_EXPORT FileStream {
// relative to the start of the file. Otherwise, an error code is returned.
// It is invalid to request any asynchronous operations while there is an
// in-flight asynchronous operation.
- virtual int Seek(Whence whence, int64 offset,
+ virtual int Seek(base::File::Whence whence, int64 offset,
const Int64CompletionCallback& callback);
// Call this method to read data from the current stream position
diff --git a/chromium/net/base/file_stream_context.cc b/chromium/net/base/file_stream_context.cc
index fbfe5368dd8..8909b2ccefd 100644
--- a/chromium/net/base/file_stream_context.cc
+++ b/chromium/net/base/file_stream_context.cc
@@ -7,6 +7,7 @@
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
@@ -78,13 +79,15 @@ void FileStream::Context::Orphan() {
if (!async_in_progress_) {
CloseAndDelete();
} else if (file_.IsValid()) {
+#if defined(OS_WIN)
CancelIo(file_.GetPlatformFile());
+#endif
}
}
-void FileStream::Context::OpenAsync(const base::FilePath& path,
- int open_flags,
- const CompletionCallback& callback) {
+void FileStream::Context::Open(const base::FilePath& path,
+ int open_flags,
+ const CompletionCallback& callback) {
DCHECK(!async_in_progress_);
bool posted = base::PostTaskAndReplyWithResult(
@@ -98,7 +101,7 @@ void FileStream::Context::OpenAsync(const base::FilePath& path,
async_in_progress_ = true;
}
-void FileStream::Context::CloseAsync(const CompletionCallback& callback) {
+void FileStream::Context::Close(const CompletionCallback& callback) {
DCHECK(!async_in_progress_);
bool posted = base::PostTaskAndReplyWithResult(
task_runner_.get(),
@@ -112,9 +115,9 @@ void FileStream::Context::CloseAsync(const CompletionCallback& callback) {
async_in_progress_ = true;
}
-void FileStream::Context::SeekAsync(Whence whence,
- int64 offset,
- const Int64CompletionCallback& callback) {
+void FileStream::Context::Seek(base::File::Whence whence,
+ int64 offset,
+ const Int64CompletionCallback& callback) {
DCHECK(!async_in_progress_);
bool posted = base::PostTaskAndReplyWithResult(
@@ -130,7 +133,7 @@ void FileStream::Context::SeekAsync(Whence whence,
async_in_progress_ = true;
}
-void FileStream::Context::FlushAsync(const CompletionCallback& callback) {
+void FileStream::Context::Flush(const CompletionCallback& callback) {
DCHECK(!async_in_progress_);
bool posted = base::PostTaskAndReplyWithResult(
@@ -147,6 +150,11 @@ void FileStream::Context::FlushAsync(const CompletionCallback& callback) {
FileStream::Context::OpenResult FileStream::Context::OpenFileImpl(
const base::FilePath& path, int open_flags) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 FileStream::Context::OpenFileImpl"));
+
#if defined(OS_POSIX)
// Always use blocking IO.
open_flags &= ~base::File::FLAG_ASYNC;
@@ -172,7 +180,8 @@ FileStream::Context::OpenResult FileStream::Context::OpenFileImpl(
}
#endif // defined(OS_ANDROID)
if (!file.IsValid())
- return OpenResult(base::File(), IOResult::FromOSError(GetLastErrno()));
+ return OpenResult(base::File(),
+ IOResult::FromOSError(logging::GetLastSystemErrorCode()));
return OpenResult(file.Pass(), IOResult(OK, 0));
}
@@ -182,11 +191,24 @@ FileStream::Context::IOResult FileStream::Context::CloseFileImpl() {
return IOResult(OK, 0);
}
+FileStream::Context::IOResult FileStream::Context::FlushFileImpl() {
+ if (file_.Flush())
+ return IOResult(OK, 0);
+
+ return IOResult::FromOSError(logging::GetLastSystemErrorCode());
+}
+
void FileStream::Context::OnOpenCompleted(const CompletionCallback& callback,
OpenResult open_result) {
file_ = open_result.file.Pass();
- if (file_.IsValid() && !orphaned_)
- OnAsyncFileOpened();
+ if (file_.IsValid() && !orphaned_) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 FileStream::Context::OnOpenCompleted"));
+
+ OnFileOpened();
+ }
OnAsyncCompleted(IntToInt64(callback), open_result.error_code);
}
@@ -214,7 +236,7 @@ void FileStream::Context::OnAsyncCompleted(
const Int64CompletionCallback& callback,
const IOResult& result) {
// Reset this before Run() as Run() may issue a new async operation. Also it
- // should be reset before CloseAsync() because it shouldn't run if any async
+ // should be reset before Close() because it shouldn't run if any async
// operation is in progress.
async_in_progress_ = false;
if (orphaned_)
diff --git a/chromium/net/base/file_stream_context.h b/chromium/net/base/file_stream_context.h
index c4a06ee1de6..5493e251c66 100644
--- a/chromium/net/base/file_stream_context.h
+++ b/chromium/net/base/file_stream_context.h
@@ -33,7 +33,6 @@
#include "base/task_runner.h"
#include "net/base/completion_callback.h"
#include "net/base/file_stream.h"
-#include "net/base/file_stream_whence.h"
#if defined(OS_POSIX)
#include <errno.h>
@@ -66,17 +65,13 @@ class FileStream::Context {
~Context();
#endif
- int ReadAsync(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback);
+ int Read(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback);
- int WriteAsync(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback);
-
- ////////////////////////////////////////////////////////////////////////////
- // Inline methods.
- ////////////////////////////////////////////////////////////////////////////
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback);
const base::File& file() const { return file_; }
bool async_in_progress() const { return async_in_progress_; }
@@ -90,23 +85,19 @@ class FileStream::Context {
// not closed yet.
void Orphan();
- void OpenAsync(const base::FilePath& path,
- int open_flags,
- const CompletionCallback& callback);
+ void Open(const base::FilePath& path,
+ int open_flags,
+ const CompletionCallback& callback);
- void CloseAsync(const CompletionCallback& callback);
+ void Close(const CompletionCallback& callback);
- void SeekAsync(Whence whence,
- int64 offset,
- const Int64CompletionCallback& callback);
+ void Seek(base::File::Whence whence,
+ int64 offset,
+ const Int64CompletionCallback& callback);
- void FlushAsync(const CompletionCallback& callback);
+ void Flush(const CompletionCallback& callback);
private:
- ////////////////////////////////////////////////////////////////////////////
- // Platform-independent methods implemented in file_stream_context.cc.
- ////////////////////////////////////////////////////////////////////////////
-
struct IOResult {
IOResult();
IOResult(int64 result, int os_error);
@@ -129,10 +120,16 @@ class FileStream::Context {
IOResult error_code;
};
+ ////////////////////////////////////////////////////////////////////////////
+ // Platform-independent methods implemented in file_stream_context.cc.
+ ////////////////////////////////////////////////////////////////////////////
+
OpenResult OpenFileImpl(const base::FilePath& path, int open_flags);
IOResult CloseFileImpl();
+ IOResult FlushFileImpl();
+
void OnOpenCompleted(const CompletionCallback& callback,
OpenResult open_result);
@@ -140,37 +137,20 @@ class FileStream::Context {
Int64CompletionCallback IntToInt64(const CompletionCallback& callback);
- // Called when asynchronous Open() or Seek()
- // is completed. |result| contains the result or a network error code.
+ // Called when Open() or Seek() completes. |result| contains the result or a
+ // network error code.
void OnAsyncCompleted(const Int64CompletionCallback& callback,
const IOResult& result);
////////////////////////////////////////////////////////////////////////////
- // Helper stuff which is platform-dependent but is used in the platform-
- // independent code implemented in file_stream_context.cc. These helpers were
- // introduced solely to implement as much of the Context methods as
- // possible independently from platform.
- ////////////////////////////////////////////////////////////////////////////
-
-#if defined(OS_WIN)
- int GetLastErrno() { return GetLastError(); }
- void OnAsyncFileOpened();
-#elif defined(OS_POSIX)
- int GetLastErrno() { return errno; }
- void OnAsyncFileOpened() {}
- void CancelIo(base::PlatformFile) {}
-#endif
-
- ////////////////////////////////////////////////////////////////////////////
// Platform-dependent methods implemented in
// file_stream_context_{win,posix}.cc.
////////////////////////////////////////////////////////////////////////////
// Adjusts the position from where the data is read.
- IOResult SeekFileImpl(Whence whence, int64 offset);
+ IOResult SeekFileImpl(base::File::Whence whence, int64 offset);
- // Flushes all data written to the stream.
- IOResult FlushFileImpl();
+ void OnFileOpened();
#if defined(OS_WIN)
void IOCompletionIsPending(const CompletionCallback& callback, IOBuffer* buf);
@@ -178,7 +158,7 @@ class FileStream::Context {
// Implementation of MessageLoopForIO::IOHandler.
virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
DWORD bytes_read,
- DWORD error) OVERRIDE;
+ DWORD error) override;
#elif defined(OS_POSIX)
// ReadFileImpl() is a simple wrapper around read() that handles EINTR
// signals and calls RecordAndMapError() to map errno to net error codes.
diff --git a/chromium/net/base/file_stream_context_posix.cc b/chromium/net/base/file_stream_context_posix.cc
index 9f3d060822f..44f59b1ef3b 100644
--- a/chromium/net/base/file_stream_context_posix.cc
+++ b/chromium/net/base/file_stream_context_posix.cc
@@ -2,16 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// For 64-bit file access (off_t = off64_t, lseek64, etc).
-#define _FILE_OFFSET_BITS 64
-
#include "net/base/file_stream_context.h"
#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
#include "base/basictypes.h"
#include "base/bind.h"
@@ -27,24 +20,8 @@
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
-#if defined(OS_ANDROID)
-// Android's bionic libc only supports the LFS transitional API.
-#define off_t off64_t
-#define lseek lseek64
-#define stat stat64
-#define fstat fstat64
-#endif
-
namespace net {
-// We cast back and forth, so make sure it's the size we're expecting.
-COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit);
-
-// Make sure our Whence mappings match the system headers.
-COMPILE_ASSERT(FROM_BEGIN == SEEK_SET &&
- FROM_CURRENT == SEEK_CUR &&
- FROM_END == SEEK_END, whence_matches_system);
-
FileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
: async_in_progress_(false),
orphaned_(false),
@@ -62,9 +39,9 @@ FileStream::Context::Context(base::File file,
FileStream::Context::~Context() {
}
-int FileStream::Context::ReadAsync(IOBuffer* in_buf,
- int buf_len,
- const CompletionCallback& callback) {
+int FileStream::Context::Read(IOBuffer* in_buf,
+ int buf_len,
+ const CompletionCallback& callback) {
DCHECK(!async_in_progress_);
scoped_refptr<IOBuffer> buf = in_buf;
@@ -81,9 +58,9 @@ int FileStream::Context::ReadAsync(IOBuffer* in_buf,
return ERR_IO_PENDING;
}
-int FileStream::Context::WriteAsync(IOBuffer* in_buf,
- int buf_len,
- const CompletionCallback& callback) {
+int FileStream::Context::Write(IOBuffer* in_buf,
+ int buf_len,
+ const CompletionCallback& callback) {
DCHECK(!async_in_progress_);
scoped_refptr<IOBuffer> buf = in_buf;
@@ -100,30 +77,23 @@ int FileStream::Context::WriteAsync(IOBuffer* in_buf,
return ERR_IO_PENDING;
}
-FileStream::Context::IOResult FileStream::Context::SeekFileImpl(Whence whence,
- int64 offset) {
- off_t res = lseek(file_.GetPlatformFile(), static_cast<off_t>(offset),
- static_cast<int>(whence));
- if (res == static_cast<off_t>(-1))
+FileStream::Context::IOResult FileStream::Context::SeekFileImpl(
+ base::File::Whence whence,
+ int64 offset) {
+ int64 res = file_.Seek(whence, offset);
+ if (res == -1)
return IOResult::FromOSError(errno);
return IOResult(res, 0);
}
-FileStream::Context::IOResult FileStream::Context::FlushFileImpl() {
- ssize_t res = HANDLE_EINTR(fsync(file_.GetPlatformFile()));
- if (res == -1)
- return IOResult::FromOSError(errno);
-
- return IOResult(res, 0);
+void FileStream::Context::OnFileOpened() {
}
FileStream::Context::IOResult FileStream::Context::ReadFileImpl(
scoped_refptr<IOBuffer> buf,
int buf_len) {
- // Loop in the case of getting interrupted by a signal.
- ssize_t res = HANDLE_EINTR(read(file_.GetPlatformFile(), buf->data(),
- static_cast<size_t>(buf_len)));
+ int res = file_.ReadAtCurrentPosNoBestEffort(buf->data(), buf_len);
if (res == -1)
return IOResult::FromOSError(errno);
@@ -133,8 +103,7 @@ FileStream::Context::IOResult FileStream::Context::ReadFileImpl(
FileStream::Context::IOResult FileStream::Context::WriteFileImpl(
scoped_refptr<IOBuffer> buf,
int buf_len) {
- ssize_t res = HANDLE_EINTR(write(file_.GetPlatformFile(), buf->data(),
- buf_len));
+ int res = file_.WriteAtCurrentPosNoBestEffort(buf->data(), buf_len);
if (res == -1)
return IOResult::FromOSError(errno);
diff --git a/chromium/net/base/file_stream_context_win.cc b/chromium/net/base/file_stream_context_win.cc
index e906b6bb480..3b942d35edc 100644
--- a/chromium/net/base/file_stream_context_win.cc
+++ b/chromium/net/base/file_stream_context_win.cc
@@ -15,11 +15,6 @@
namespace net {
-// Ensure that we can just use our Whence values directly.
-COMPILE_ASSERT(FROM_BEGIN == FILE_BEGIN, bad_whence_begin);
-COMPILE_ASSERT(FROM_CURRENT == FILE_CURRENT, bad_whence_current);
-COMPILE_ASSERT(FROM_END == FILE_END, bad_whence_end);
-
namespace {
void SetOffset(OVERLAPPED* overlapped, const LARGE_INTEGER& offset) {
@@ -57,16 +52,16 @@ FileStream::Context::Context(base::File file,
memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped));
if (file_.IsValid()) {
// TODO(hashimoto): Check that file_ is async.
- OnAsyncFileOpened();
+ OnFileOpened();
}
}
FileStream::Context::~Context() {
}
-int FileStream::Context::ReadAsync(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int FileStream::Context::Read(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
DCHECK(!async_in_progress_);
DWORD bytes_read;
@@ -87,9 +82,9 @@ int FileStream::Context::ReadAsync(IOBuffer* buf,
return ERR_IO_PENDING;
}
-int FileStream::Context::WriteAsync(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int FileStream::Context::Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
DWORD bytes_written = 0;
if (!WriteFile(file_.GetPlatformFile(), buf->data(), buf_len,
&bytes_written, &io_context_.overlapped)) {
@@ -106,29 +101,22 @@ int FileStream::Context::WriteAsync(IOBuffer* buf,
return ERR_IO_PENDING;
}
-void FileStream::Context::OnAsyncFileOpened() {
- base::MessageLoopForIO::current()->RegisterIOHandler(file_.GetPlatformFile(),
- this);
-}
-
-FileStream::Context::IOResult FileStream::Context::SeekFileImpl(Whence whence,
- int64 offset) {
- LARGE_INTEGER distance, res;
- distance.QuadPart = offset;
- DWORD move_method = static_cast<DWORD>(whence);
- if (SetFilePointerEx(file_.GetPlatformFile(), distance, &res, move_method)) {
- SetOffset(&io_context_.overlapped, res);
- return IOResult(res.QuadPart, 0);
+FileStream::Context::IOResult FileStream::Context::SeekFileImpl(
+ base::File::Whence whence,
+ int64 offset) {
+ LARGE_INTEGER result;
+ result.QuadPart = file_.Seek(whence, offset);
+ if (result.QuadPart >= 0) {
+ SetOffset(&io_context_.overlapped, result);
+ return IOResult(result.QuadPart, 0);
}
return IOResult::FromOSError(GetLastError());
}
-FileStream::Context::IOResult FileStream::Context::FlushFileImpl() {
- if (FlushFileBuffers(file_.GetPlatformFile()))
- return IOResult(OK, 0);
-
- return IOResult::FromOSError(GetLastError());
+void FileStream::Context::OnFileOpened() {
+ base::MessageLoopForIO::current()->RegisterIOHandler(file_.GetPlatformFile(),
+ this);
}
void FileStream::Context::IOCompletionIsPending(
diff --git a/chromium/net/base/file_stream_unittest.cc b/chromium/net/base/file_stream_unittest.cc
index 292b0d207cf..fc9257e5d1c 100644
--- a/chromium/net/base/file_stream_unittest.cc
+++ b/chromium/net/base/file_stream_unittest.cc
@@ -6,12 +6,13 @@
#include "base/bind.h"
#include "base/callback.h"
-#include "base/file_util.h"
#include "base/files/file.h"
+#include "base/files/file_util.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/path_service.h"
#include "base/run_loop.h"
+#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/threading/sequenced_worker_pool.h"
@@ -45,13 +46,13 @@ IOBufferWithSize* CreateTestDataBuffer() {
class FileStreamTest : public PlatformTest {
public:
- virtual void SetUp() {
+ void SetUp() override {
PlatformTest::SetUp();
base::CreateTemporaryFile(&temp_file_path_);
base::WriteFile(temp_file_path_, kTestData, kTestDataSize);
}
- virtual void TearDown() {
+ void TearDown() override {
// FileStreamContexts must be asynchronously closed on the file task runner
// before they can be deleted. Pump the RunLoop to avoid leaks.
base::RunLoop().RunUntilIdle();
@@ -68,7 +69,7 @@ class FileStreamTest : public PlatformTest {
namespace {
-TEST_F(FileStreamTest, AsyncOpenExplicitClose) {
+TEST_F(FileStreamTest, OpenExplicitClose) {
TestCompletionCallback callback;
FileStream stream(base::MessageLoopProxy::current());
int flags = base::File::FLAG_OPEN |
@@ -85,7 +86,7 @@ TEST_F(FileStreamTest, AsyncOpenExplicitClose) {
EXPECT_FALSE(stream.GetFileForTesting().IsValid());
}
-TEST_F(FileStreamTest, AsyncOpenExplicitCloseOrphaned) {
+TEST_F(FileStreamTest, OpenExplicitCloseOrphaned) {
TestCompletionCallback callback;
scoped_ptr<FileStream> stream(new FileStream(
base::MessageLoopProxy::current()));
@@ -120,7 +121,8 @@ TEST_F(FileStreamTest, UseFileHandle) {
scoped_ptr<FileStream> read_stream(
new FileStream(file.Pass(), base::MessageLoopProxy::current()));
ASSERT_EQ(ERR_IO_PENDING,
- read_stream->Seek(FROM_BEGIN, 0, callback64.callback()));
+ read_stream->Seek(base::File::FROM_BEGIN, 0,
+ callback64.callback()));
ASSERT_EQ(0, callback64.WaitForResult());
// Read into buffer and compare.
scoped_refptr<IOBufferWithSize> read_buffer =
@@ -139,7 +141,8 @@ TEST_F(FileStreamTest, UseFileHandle) {
scoped_ptr<FileStream> write_stream(
new FileStream(file.Pass(), base::MessageLoopProxy::current()));
ASSERT_EQ(ERR_IO_PENDING,
- write_stream->Seek(FROM_BEGIN, 0, callback64.callback()));
+ write_stream->Seek(base::File::FROM_BEGIN, 0,
+ callback64.callback()));
ASSERT_EQ(0, callback64.WaitForResult());
scoped_refptr<IOBufferWithSize> write_buffer = CreateTestDataBuffer();
rv = write_stream->Write(write_buffer.get(), kTestDataSize,
@@ -164,16 +167,16 @@ TEST_F(FileStreamTest, UseClosedStream) {
EXPECT_FALSE(stream.IsOpen());
// Try seeking...
- rv = stream.Seek(FROM_BEGIN, 5, callback64.callback());
+ rv = stream.Seek(base::File::FROM_BEGIN, 5, callback64.callback());
EXPECT_EQ(ERR_UNEXPECTED, callback64.GetResult(rv));
// Try reading...
scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(10);
- rv = stream.Read(buf, buf->size(), callback.callback());
+ rv = stream.Read(buf.get(), buf->size(), callback.callback());
EXPECT_EQ(ERR_UNEXPECTED, callback.GetResult(rv));
}
-TEST_F(FileStreamTest, AsyncRead) {
+TEST_F(FileStreamTest, Read) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -182,8 +185,7 @@ TEST_F(FileStreamTest, AsyncRead) {
base::File::FLAG_ASYNC;
TestCompletionCallback callback;
int rv = stream.Open(temp_file_path(), flags, callback.callback());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, callback.WaitForResult());
+ EXPECT_EQ(OK, callback.GetResult(rv));
int total_bytes_read = 0;
@@ -191,8 +193,7 @@ TEST_F(FileStreamTest, AsyncRead) {
for (;;) {
scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
rv = stream.Read(buf.get(), buf->size(), callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
+ rv = callback.GetResult(rv);
EXPECT_LE(0, rv);
if (rv <= 0)
break;
@@ -203,7 +204,7 @@ TEST_F(FileStreamTest, AsyncRead) {
EXPECT_EQ(kTestData, data_read);
}
-TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
+TEST_F(FileStreamTest, Read_EarlyDelete) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -229,7 +230,7 @@ TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
}
}
-TEST_F(FileStreamTest, AsyncRead_FromOffset) {
+TEST_F(FileStreamTest, Read_FromOffset) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -243,7 +244,7 @@ TEST_F(FileStreamTest, AsyncRead_FromOffset) {
TestInt64CompletionCallback callback64;
const int64 kOffset = 3;
- rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
+ rv = stream.Seek(base::File::FROM_BEGIN, kOffset, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
int64 new_offset = callback64.WaitForResult();
EXPECT_EQ(kOffset, new_offset);
@@ -266,7 +267,7 @@ TEST_F(FileStreamTest, AsyncRead_FromOffset) {
EXPECT_EQ(kTestData + kOffset, data_read);
}
-TEST_F(FileStreamTest, AsyncSeekAround) {
+TEST_F(FileStreamTest, SeekAround) {
FileStream stream(base::MessageLoopProxy::current());
int flags = base::File::FLAG_OPEN | base::File::FLAG_ASYNC |
base::File::FLAG_READ;
@@ -278,63 +279,55 @@ TEST_F(FileStreamTest, AsyncSeekAround) {
TestInt64CompletionCallback callback64;
const int64 kOffset = 3;
- rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
+ rv = stream.Seek(base::File::FROM_BEGIN, kOffset, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
int64 new_offset = callback64.WaitForResult();
EXPECT_EQ(kOffset, new_offset);
- rv = stream.Seek(FROM_CURRENT, kOffset, callback64.callback());
+ rv = stream.Seek(base::File::FROM_CURRENT, kOffset, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
new_offset = callback64.WaitForResult();
EXPECT_EQ(2 * kOffset, new_offset);
- rv = stream.Seek(FROM_CURRENT, -kOffset, callback64.callback());
+ rv = stream.Seek(base::File::FROM_CURRENT, -kOffset, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
new_offset = callback64.WaitForResult();
EXPECT_EQ(kOffset, new_offset);
const int kTestDataLen = arraysize(kTestData) - 1;
- rv = stream.Seek(FROM_END, -kTestDataLen, callback64.callback());
+ rv = stream.Seek(base::File::FROM_END, -kTestDataLen, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
new_offset = callback64.WaitForResult();
EXPECT_EQ(0, new_offset);
}
-TEST_F(FileStreamTest, AsyncWrite) {
+TEST_F(FileStreamTest, Write) {
FileStream stream(base::MessageLoopProxy::current());
int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
base::File::FLAG_ASYNC;
TestCompletionCallback callback;
int rv = stream.Open(temp_file_path(), flags, callback.callback());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, callback.WaitForResult());
+ EXPECT_EQ(OK, callback.GetResult(rv));
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
EXPECT_EQ(0, file_size);
- int total_bytes_written = 0;
+ scoped_refptr<IOBuffer> buf = CreateTestDataBuffer();
+ rv = stream.Write(buf.get(), kTestDataSize, callback.callback());
+ rv = callback.GetResult(rv);
+ EXPECT_EQ(kTestDataSize, rv);
- scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
- scoped_refptr<DrainableIOBuffer> drainable =
- new DrainableIOBuffer(buf.get(), buf->size());
- while (total_bytes_written != kTestDataSize) {
- rv = stream.Write(drainable.get(), drainable->BytesRemaining(),
- callback.callback());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_LT(0, rv);
- if (rv <= 0)
- break;
- drainable->DidConsume(rv);
- total_bytes_written += rv;
- }
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
- EXPECT_EQ(file_size, total_bytes_written);
+ EXPECT_EQ(kTestDataSize, file_size);
+
+ std::string data_read;
+ EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &data_read));
+ EXPECT_EQ(kTestData, data_read);
}
-TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) {
+TEST_F(FileStreamTest, Write_EarlyDelete) {
scoped_ptr<FileStream> stream(
new FileStream(base::MessageLoopProxy::current()));
int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
@@ -362,7 +355,7 @@ TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) {
}
}
-TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
+TEST_F(FileStreamTest, Write_FromOffset) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -376,7 +369,7 @@ TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
TestInt64CompletionCallback callback64;
const int64 kOffset = 0;
- rv = stream.Seek(FROM_END, kOffset, callback64.callback());
+ rv = stream.Seek(base::File::FROM_END, kOffset, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
int64 new_offset = callback64.WaitForResult();
EXPECT_EQ(kTestDataSize, new_offset);
@@ -401,7 +394,7 @@ TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
EXPECT_EQ(file_size, kTestDataSize * 2);
}
-TEST_F(FileStreamTest, BasicAsyncReadWrite) {
+TEST_F(FileStreamTest, BasicReadWrite) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -454,7 +447,7 @@ TEST_F(FileStreamTest, BasicAsyncReadWrite) {
EXPECT_EQ(kTestDataSize * 2, file_size);
}
-TEST_F(FileStreamTest, BasicAsyncWriteRead) {
+TEST_F(FileStreamTest, BasicWriteRead) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -468,7 +461,7 @@ TEST_F(FileStreamTest, BasicAsyncWriteRead) {
EXPECT_EQ(OK, callback.WaitForResult());
TestInt64CompletionCallback callback64;
- rv = stream->Seek(FROM_END, 0, callback64.callback());
+ rv = stream->Seek(base::File::FROM_END, 0, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
int64 offset = callback64.WaitForResult();
EXPECT_EQ(offset, file_size);
@@ -492,7 +485,7 @@ TEST_F(FileStreamTest, BasicAsyncWriteRead) {
EXPECT_EQ(kTestDataSize, total_bytes_written);
- rv = stream->Seek(FROM_BEGIN, 0, callback64.callback());
+ rv = stream->Seek(base::File::FROM_BEGIN, 0, callback64.callback());
ASSERT_EQ(ERR_IO_PENDING, rv);
offset = callback64.WaitForResult();
EXPECT_EQ(0, offset);
@@ -577,7 +570,8 @@ class TestWriteReadCompletionCallback {
} else { // We're done writing all data. Start reading the data.
TestInt64CompletionCallback callback64;
EXPECT_EQ(ERR_IO_PENDING,
- stream_->Seek(FROM_BEGIN, 0, callback64.callback()));
+ stream_->Seek(base::File::FROM_BEGIN, 0,
+ callback64.callback()));
{
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
@@ -621,7 +615,7 @@ class TestWriteReadCompletionCallback {
DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
};
-TEST_F(FileStreamTest, AsyncWriteRead) {
+TEST_F(FileStreamTest, WriteRead) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -635,7 +629,8 @@ TEST_F(FileStreamTest, AsyncWriteRead) {
EXPECT_EQ(OK, open_callback.WaitForResult());
TestInt64CompletionCallback callback64;
- EXPECT_EQ(ERR_IO_PENDING, stream->Seek(FROM_END, 0, callback64.callback()));
+ EXPECT_EQ(ERR_IO_PENDING,
+ stream->Seek(base::File::FROM_END, 0, callback64.callback()));
EXPECT_EQ(file_size, callback64.WaitForResult());
int total_bytes_written = 0;
@@ -725,7 +720,7 @@ class TestWriteCloseCompletionCallback {
DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
};
-TEST_F(FileStreamTest, AsyncWriteClose) {
+TEST_F(FileStreamTest, WriteClose) {
int64 file_size;
EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
@@ -739,7 +734,8 @@ TEST_F(FileStreamTest, AsyncWriteClose) {
EXPECT_EQ(OK, open_callback.WaitForResult());
TestInt64CompletionCallback callback64;
- EXPECT_EQ(ERR_IO_PENDING, stream->Seek(FROM_END, 0, callback64.callback()));
+ EXPECT_EQ(ERR_IO_PENDING,
+ stream->Seek(base::File::FROM_END, 0, callback64.callback()));
EXPECT_EQ(file_size, callback64.WaitForResult());
int total_bytes_written = 0;
@@ -758,7 +754,7 @@ TEST_F(FileStreamTest, AsyncWriteClose) {
EXPECT_EQ(kTestDataSize * 2, file_size);
}
-TEST_F(FileStreamTest, AsyncOpenAndDelete) {
+TEST_F(FileStreamTest, OpenAndDelete) {
scoped_refptr<base::SequencedWorkerPool> pool(
new base::SequencedWorkerPool(1, "StreamTest"));
@@ -789,8 +785,8 @@ TEST_F(FileStreamTest, AsyncOpenAndDelete) {
base::ThreadRestrictions::SetIOAllowed(prev);
}
-// Verify that async Write() errors are mapped correctly.
-TEST_F(FileStreamTest, AsyncWriteError) {
+// Verify that Write() errors are mapped correctly.
+TEST_F(FileStreamTest, WriteError) {
// Try opening file as read-only and then writing to it using FileStream.
uint32 flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
base::File::FLAG_ASYNC;
@@ -814,8 +810,8 @@ TEST_F(FileStreamTest, AsyncWriteError) {
base::RunLoop().RunUntilIdle();
}
-// Verify that async Read() errors are mapped correctly.
-TEST_F(FileStreamTest, AsyncReadError) {
+// Verify that Read() errors are mapped correctly.
+TEST_F(FileStreamTest, ReadError) {
// Try opening file for write and then reading from it using FileStream.
uint32 flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
base::File::FLAG_ASYNC;
@@ -838,7 +834,7 @@ TEST_F(FileStreamTest, AsyncReadError) {
}
#if defined(OS_ANDROID)
-TEST_F(FileStreamTest, ContentUriAsyncRead) {
+TEST_F(FileStreamTest, ContentUriRead) {
base::FilePath test_dir;
PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
test_dir = test_dir.AppendASCII("net");
@@ -849,7 +845,7 @@ TEST_F(FileStreamTest, ContentUriAsyncRead) {
// Insert the image into MediaStore. MediaStore will do some conversions, and
// return the content URI.
- base::FilePath path = file_util::InsertImageIntoMediaStore(image_file);
+ base::FilePath path = base::InsertImageIntoMediaStore(image_file);
EXPECT_TRUE(path.IsContentUri());
EXPECT_TRUE(base::PathExists(path));
int64 file_size;
diff --git a/chromium/net/base/file_stream_whence.h b/chromium/net/base/file_stream_whence.h
deleted file mode 100644
index a962341f93d..00000000000
--- a/chromium/net/base/file_stream_whence.h
+++ /dev/null
@@ -1,20 +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.
-
-#ifndef NET_BASE_FILE_STREAM_WHENCE_H_
-#define NET_BASE_FILE_STREAM_WHENCE_H_
-
-namespace net {
-
-// TODO(darin): Move this to a more generic location.
-// This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.
-enum Whence {
- FROM_BEGIN = 0,
- FROM_CURRENT = 1,
- FROM_END = 2
-};
-
-} // namespace net
-
-#endif // NET_BASE_FILE_STREAM_WHENCE_H_
diff --git a/chromium/net/base/filename_util.cc b/chromium/net/base/filename_util.cc
index 31b5fe5ec70..6573c226161 100644
--- a/chromium/net/base/filename_util.cc
+++ b/chromium/net/base/filename_util.cc
@@ -4,8 +4,8 @@
#include "net/base/filename_util.h"
-#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
diff --git a/chromium/net/base/filename_util_icu.cc b/chromium/net/base/filename_util_icu.cc
index 72bce6e0c36..8c22eec9520 100644
--- a/chromium/net/base/filename_util_icu.cc
+++ b/chromium/net/base/filename_util_icu.cc
@@ -24,7 +24,7 @@ bool IsSafePortablePathComponent(const base::FilePath& component) {
return !component.empty() && (component == component.BaseName()) &&
(component == component.StripTrailingSeparators()) &&
FilePathToString16(component, &component16) &&
- file_util::IsFilenameLegal(component16) &&
+ base::i18n::IsFilenameLegal(component16) &&
!IsShellIntegratedExtension(extension) &&
(sanitized == component.value()) && !IsReservedName(component.value());
}
@@ -56,7 +56,7 @@ base::string16 GetSuggestedFilename(const GURL& url,
suggested_name,
mime_type,
default_name,
- base::Bind(&file_util::ReplaceIllegalCharactersInPath));
+ base::Bind(&base::i18n::ReplaceIllegalCharactersInPath));
}
base::FilePath GenerateFileName(const GURL& url,
@@ -72,14 +72,14 @@ base::FilePath GenerateFileName(const GURL& url,
suggested_name,
mime_type,
default_file_name,
- base::Bind(&file_util::ReplaceIllegalCharactersInPath)));
+ base::Bind(&base::i18n::ReplaceIllegalCharactersInPath)));
#if defined(OS_CHROMEOS)
// When doing file manager operations on ChromeOS, the file paths get
// normalized in WebKit layer, so let's ensure downloaded files have
// normalized names. Otherwise, we won't be able to handle files with NFD
// utf8 encoded characters in name.
- file_util::NormalizeFileNameEncoding(&generated_name);
+ base::i18n::NormalizeFileNameEncoding(&generated_name);
#endif
DCHECK(!generated_name.empty());
diff --git a/chromium/net/base/filename_util_internal.cc b/chromium/net/base/filename_util_internal.cc
index a59de0f50c9..be9139dfff5 100644
--- a/chromium/net/base/filename_util_internal.cc
+++ b/chromium/net/base/filename_util_internal.cc
@@ -4,9 +4,8 @@
#include "net/base/filename_util.h"
-#include "base/file_util.h"
#include "base/files/file_path.h"
-#include "base/path_service.h"
+#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
@@ -89,7 +88,8 @@ std::string GetFileNameFromURL(const GURL& url,
// Returns whether the specified extension is automatically integrated into the
// windows shell.
bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
- base::FilePath::StringType extension_lower = StringToLowerASCII(extension);
+ base::FilePath::StringType extension_lower =
+ base::StringToLowerASCII(extension);
// http://msdn.microsoft.com/en-us/library/ms811694.aspx
// Right-clicking on shortcuts can be magical.
@@ -119,9 +119,10 @@ bool IsReservedName(const base::FilePath::StringType& filename) {
"com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
"lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "clock$"};
#if defined(OS_WIN)
- std::string filename_lower = StringToLowerASCII(base::WideToUTF8(filename));
+ std::string filename_lower =
+ base::StringToLowerASCII(base::WideToUTF8(filename));
#elif defined(OS_POSIX)
- std::string filename_lower = StringToLowerASCII(filename);
+ std::string filename_lower = base::StringToLowerASCII(filename);
#endif
for (size_t i = 0; i < arraysize(known_devices); ++i) {
@@ -227,11 +228,13 @@ base::string16 GetSuggestedFilenameImpl(
FILE_PATH_LITERAL("download");
std::string filename; // In UTF-8
bool overwrite_extension = false;
-
+ bool is_name_from_content_disposition = false;
// Try to extract a filename from content-disposition first.
if (!content_disposition.empty()) {
HttpContentDisposition header(content_disposition, referrer_charset);
filename = header.filename();
+ if (!filename.empty())
+ is_name_from_content_disposition = true;
}
// Then try to use the suggested name.
@@ -273,7 +276,13 @@ base::string16 GetSuggestedFilenameImpl(
}
replace_illegal_characters_callback.Run(&result_str, '-');
base::FilePath result(result_str);
- GenerateSafeFileName(mime_type, overwrite_extension, &result);
+ // extension should not appended to filename derived from
+ // content-disposition, if it does not have one.
+ // Hence mimetype and overwrite_extension values are not used.
+ if (is_name_from_content_disposition)
+ GenerateSafeFileName("", false, &result);
+ else
+ GenerateSafeFileName(mime_type, overwrite_extension, &result);
base::string16 result16;
if (!FilePathToString16(result, &result16)) {
diff --git a/chromium/net/base/filename_util_unittest.cc b/chromium/net/base/filename_util_unittest.cc
index 0bd22500fe9..391baeb3312 100644
--- a/chromium/net/base/filename_util_unittest.cc
+++ b/chromium/net/base/filename_util_unittest.cc
@@ -4,8 +4,8 @@
#include "net/base/filename_util.h"
-#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_file_util.h"
@@ -32,14 +32,29 @@ struct GenerateFilenameCase {
const wchar_t* expected_filename;
};
+// The expected filenames are coded as wchar_t for convenience.
+std::wstring FilePathAsWString(const base::FilePath& path) {
+#if defined(OS_WIN)
+ return path.value();
+#else
+ return base::UTF8ToWide(path.value());
+#endif
+}
+base::FilePath WStringAsFilePath(const std::wstring& str) {
+#if defined(OS_WIN)
+ return base::FilePath(str);
+#else
+ return base::FilePath(base::WideToUTF8(str));
+#endif
+}
+
void RunGenerateFileNameTestCase(const GenerateFilenameCase* test_case) {
std::string default_filename(base::WideToUTF8(test_case->default_filename));
base::FilePath file_path = GenerateFileName(
GURL(test_case->url), test_case->content_disp_header,
test_case->referrer_charset, test_case->suggested_filename,
test_case->mime_type, default_filename);
- EXPECT_EQ(test_case->expected_filename,
- file_util::FilePathAsWString(file_path))
+ EXPECT_EQ(test_case->expected_filename, FilePathAsWString(file_path))
<< "test case at line number: " << test_case->lineno;
}
@@ -168,15 +183,15 @@ TEST(FilenameUtilTest, FileURLConversion) {
// First, we'll test that we can round-trip all of the above cases of URLs
base::FilePath output;
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(round_trip_cases); i++) {
+ for (size_t i = 0; i < arraysize(round_trip_cases); i++) {
// convert to the file URL
GURL file_url(FilePathToFileURL(
- file_util::WStringAsFilePath(round_trip_cases[i].file)));
+ WStringAsFilePath(round_trip_cases[i].file)));
EXPECT_EQ(round_trip_cases[i].url, file_url.spec());
// Back to the filename.
EXPECT_TRUE(FileURLToFilePath(file_url, &output));
- EXPECT_EQ(round_trip_cases[i].file, file_util::FilePathAsWString(output));
+ EXPECT_EQ(round_trip_cases[i].file, FilePathAsWString(output));
}
// Test that various file: URLs get decoded into the correct file type
@@ -213,9 +228,9 @@ TEST(FilenameUtilTest, FileURLConversion) {
//{L"/foo%5Cbar.txt", "file://foo\\bar.txt"},
#endif
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(url_cases); i++) {
+ for (size_t i = 0; i < arraysize(url_cases); i++) {
FileURLToFilePath(GURL(url_cases[i].url), &output);
- EXPECT_EQ(url_cases[i].file, file_util::FilePathAsWString(output));
+ EXPECT_EQ(url_cases[i].file, FilePathAsWString(output));
}
// Unfortunately, UTF8ToWide discards invalid UTF8 input.
@@ -394,7 +409,7 @@ TEST(FilenameUtilTest, GenerateSafeFileName) {
#endif // !defined(OS_WIN)
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(safe_tests); ++i) {
+ for (size_t i = 0; i < arraysize(safe_tests); ++i) {
base::FilePath file_path(safe_tests[i].filename);
GenerateSafeFileName(safe_tests[i].mime_type, false, &file_path);
EXPECT_EQ(safe_tests[i].expected_filename, file_path.value())
@@ -408,7 +423,7 @@ TEST(FilenameUtilTest, GenerateFileName) {
// string conversions fail. This is OK (we have the default value) but they
// don't match our expectations.
std::string locale = setlocale(LC_CTYPE, NULL);
- StringToLowerASCII(&locale);
+ base::StringToLowerASCII(&locale);
EXPECT_TRUE(locale.find("utf-8") != std::string::npos ||
locale.find("utf8") != std::string::npos)
<< "Your locale (" << locale << ") must be set to UTF-8 "
@@ -795,6 +810,16 @@ TEST(FilenameUtilTest, GenerateFileName) {
L"",
L"test.html"
},
+ {
+ __LINE__,
+ "http://www.google.com/test",
+ "attachment; filename=test",
+ "utf-8",
+ "",
+ "image/png",
+ L"",
+ L"test"
+ },
#if 0
{ // The filename encoding doesn't match the referrer charset, the system
// charset, or UTF-8.
@@ -1007,7 +1032,7 @@ TEST(FilenameUtilTest, GenerateFileName) {
"",
"text/plain",
L"default",
- L"-blink-Hello kitty--blink-" TXT_EXT
+ L"-blink-Hello kitty--blink-"
},
{ // A normal avi should get .avi and not .avi.avi
__LINE__,
@@ -1027,7 +1052,7 @@ TEST(FilenameUtilTest, GenerateFileName) {
"",
"image/jpeg",
L"download",
- L"my-cat" JPEG_EXT
+ L"my-cat"
},
{
__LINE__,
@@ -1037,7 +1062,7 @@ TEST(FilenameUtilTest, GenerateFileName) {
"",
"text/plain",
L"download",
- L"my-cat.txt"
+ L"my-cat"
},
{
__LINE__,
@@ -1047,7 +1072,7 @@ TEST(FilenameUtilTest, GenerateFileName) {
"",
"text/html",
L"download",
- L"my-cat" HTML_EXT
+ L"my-cat"
},
{ // Unknown MIME type
__LINE__,
@@ -1271,7 +1296,7 @@ TEST(FilenameUtilTest, GenerateFileName) {
"",
"text/plain",
L"download",
- L"hidden" TXT_EXT
+ L"hidden"
},
{
__LINE__,
@@ -1296,9 +1321,9 @@ TEST(FilenameUtilTest, GenerateFileName) {
"text/plain",
L"download",
#if defined(OS_WIN)
- L"trailing-" TXT_EXT
+ L"trailing-"
#else
- L"trailing" TXT_EXT
+ L"trailing"
#endif
},
{
@@ -1636,13 +1661,13 @@ TEST(FilenameUtilTest, GenerateFileName) {
#endif
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(selection_tests); ++i)
+ for (size_t i = 0; i < arraysize(selection_tests); ++i)
RunGenerateFileNameTestCase(&selection_tests[i]);
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(generation_tests); ++i)
+ for (size_t i = 0; i < arraysize(generation_tests); ++i)
RunGenerateFileNameTestCase(&generation_tests[i]);
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(generation_tests); ++i) {
+ for (size_t i = 0; i < arraysize(generation_tests); ++i) {
GenerateFilenameCase test_case = generation_tests[i];
test_case.referrer_charset = "GBK";
RunGenerateFileNameTestCase(&test_case);
diff --git a/chromium/net/base/host_mapping_rules.cc b/chromium/net/base/host_mapping_rules.cc
index 6ae475458b0..f91f3fd0b4e 100644
--- a/chromium/net/base/host_mapping_rules.cc
+++ b/chromium/net/base/host_mapping_rules.cc
@@ -74,7 +74,7 @@ bool HostMappingRules::AddRuleFromString(const std::string& rule_string) {
// Test for EXCLUSION rule.
if (parts.size() == 2 && LowerCaseEqualsASCII(parts[0], "exclude")) {
ExclusionRule rule;
- rule.hostname_pattern = StringToLowerASCII(parts[1]);
+ rule.hostname_pattern = base::StringToLowerASCII(parts[1]);
exclusion_rules_.push_back(rule);
return true;
}
@@ -82,7 +82,7 @@ bool HostMappingRules::AddRuleFromString(const std::string& rule_string) {
// Test for MAP rule.
if (parts.size() == 3 && LowerCaseEqualsASCII(parts[0], "map")) {
MapRule rule;
- rule.hostname_pattern = StringToLowerASCII(parts[1]);
+ rule.hostname_pattern = base::StringToLowerASCII(parts[1]);
if (!ParseHostAndPort(parts[2], &rule.replacement_hostname,
&rule.replacement_port)) {
diff --git a/chromium/net/base/io_buffer.cc b/chromium/net/base/io_buffer.cc
index dd1d4517eea..a375381bfd9 100644
--- a/chromium/net/base/io_buffer.cc
+++ b/chromium/net/base/io_buffer.cc
@@ -46,6 +46,13 @@ StringIOBuffer::StringIOBuffer(const std::string& s)
data_ = const_cast<char*>(string_data_.data());
}
+StringIOBuffer::StringIOBuffer(scoped_ptr<std::string> s)
+ : IOBuffer(static_cast<char*>(NULL)) {
+ CHECK_LT(s->size(), static_cast<size_t>(INT_MAX));
+ string_data_.swap(*s.get());
+ data_ = const_cast<char*>(string_data_.data());
+}
+
StringIOBuffer::~StringIOBuffer() {
// We haven't allocated the buffer, so remove it before the base class
// destructor tries to delete[] it.
diff --git a/chromium/net/base/io_buffer.h b/chromium/net/base/io_buffer.h
index 0ce52e8d79c..04bbc883e97 100644
--- a/chromium/net/base/io_buffer.h
+++ b/chromium/net/base/io_buffer.h
@@ -104,7 +104,7 @@ class NET_EXPORT IOBufferWithSize : public IOBuffer {
// constructor IOBuffer(char*) thus allowing subclass to use underlying
// memory it does not own.
IOBufferWithSize(char* data, int size);
- virtual ~IOBufferWithSize();
+ ~IOBufferWithSize() override;
int size_;
};
@@ -114,11 +114,12 @@ class NET_EXPORT IOBufferWithSize : public IOBuffer {
class NET_EXPORT StringIOBuffer : public IOBuffer {
public:
explicit StringIOBuffer(const std::string& s);
+ explicit StringIOBuffer(scoped_ptr<std::string> s);
int size() const { return static_cast<int>(string_data_.size()); }
private:
- virtual ~StringIOBuffer();
+ ~StringIOBuffer() override;
std::string string_data_;
};
@@ -161,7 +162,7 @@ class NET_EXPORT DrainableIOBuffer : public IOBuffer {
int size() const { return size_; }
private:
- virtual ~DrainableIOBuffer();
+ ~DrainableIOBuffer() override;
scoped_refptr<IOBuffer> base_;
int size_;
@@ -201,7 +202,7 @@ class NET_EXPORT GrowableIOBuffer : public IOBuffer {
char* StartOfBuffer();
private:
- virtual ~GrowableIOBuffer();
+ ~GrowableIOBuffer() override;
scoped_ptr<char, base::FreeDeleter> real_data_;
int capacity_;
@@ -221,7 +222,7 @@ class NET_EXPORT PickledIOBuffer : public IOBuffer {
void Done();
private:
- virtual ~PickledIOBuffer();
+ ~PickledIOBuffer() override;
Pickle pickle_;
};
@@ -236,7 +237,7 @@ class NET_EXPORT WrappedIOBuffer : public IOBuffer {
explicit WrappedIOBuffer(const char* data);
protected:
- virtual ~WrappedIOBuffer();
+ ~WrappedIOBuffer() override;
};
} // namespace net
diff --git a/chromium/net/base/ip_endpoint_unittest.cc b/chromium/net/base/ip_endpoint_unittest.cc
index f10e8e99737..5d709115207 100644
--- a/chromium/net/base/ip_endpoint_unittest.cc
+++ b/chromium/net/base/ip_endpoint_unittest.cc
@@ -29,11 +29,11 @@ struct TestData {
{ "::1", "[::1]", true },
{ "2001:db8:0::42", "[2001:db8::42]", true },
};
-int test_count = ARRAYSIZE_UNSAFE(tests);
+int test_count = arraysize(tests);
class IPEndPointTest : public PlatformTest {
public:
- virtual void SetUp() {
+ void SetUp() override {
// This is where we populate the TestData.
for (int index = 0; index < test_count; ++index) {
EXPECT_TRUE(ParseIPLiteralToNumber(tests[index].host,
diff --git a/chromium/net/base/keygen_handler_nss.cc b/chromium/net/base/keygen_handler_nss.cc
index ad0f0ebe672..661dabc7710 100644
--- a/chromium/net/base/keygen_handler_nss.cc
+++ b/chromium/net/base/keygen_handler_nss.cc
@@ -7,7 +7,6 @@
#include "base/logging.h"
#include "crypto/nss_crypto_module_delegate.h"
#include "crypto/nss_util.h"
-#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"
#include "net/third_party/mozilla_security_manager/nsKeygenHandler.h"
@@ -17,26 +16,21 @@ namespace psm = mozilla_security_manager;
namespace net {
std::string KeygenHandler::GenKeyAndSignChallenge() {
- // Ensure NSS is initialized.
crypto::EnsureNSSInit();
crypto::ScopedPK11Slot slot;
- if (crypto_module_delegate_)
+ if (crypto_module_delegate_) {
slot = crypto_module_delegate_->RequestSlot().Pass();
- else
- slot.reset(crypto::GetPrivateNSSKeySlot());
- if (!slot.get()) {
- LOG(ERROR) << "Couldn't get private key slot from NSS!";
+ } else {
+ LOG(ERROR) << "Could not get an NSS key slot.";
return std::string();
}
// Authenticate to the token.
- if (SECSuccess !=
- PK11_Authenticate(
- slot.get(),
- PR_TRUE,
- crypto_module_delegate_ ? crypto_module_delegate_->wincx() : NULL)) {
- LOG(ERROR) << "Couldn't authenticate to private key slot!";
+ if (SECSuccess != PK11_Authenticate(slot.get(),
+ PR_TRUE,
+ crypto_module_delegate_->wincx())) {
+ LOG(ERROR) << "Could not authenticate to the key slot.";
return std::string();
}
diff --git a/chromium/net/base/keygen_handler_openssl.cc b/chromium/net/base/keygen_handler_openssl.cc
index edd0eb110b4..aeb64a8b543 100644
--- a/chromium/net/base/keygen_handler_openssl.cc
+++ b/chromium/net/base/keygen_handler_openssl.cc
@@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "crypto/openssl_util.h"
#include "crypto/rsa_private_key.h"
+#include "crypto/scoped_openssl_types.h"
#include "net/base/openssl_private_key_store.h"
namespace net {
@@ -22,8 +23,8 @@ std::string KeygenHandler::GenKeyAndSignChallenge() {
if (stores_key_)
OpenSSLPrivateKeyStore::StoreKeyPair(url_, pkey);
- crypto::ScopedOpenSSL<NETSCAPE_SPKI, NETSCAPE_SPKI_free> spki(
- NETSCAPE_SPKI_new());
+ crypto::ScopedOpenSSL<NETSCAPE_SPKI, NETSCAPE_SPKI_free>::Type spki(
+ NETSCAPE_SPKI_new());
ASN1_STRING_set(spki.get()->spkac->challenge,
challenge_.data(), challenge_.size());
NETSCAPE_SPKI_set_pubkey(spki.get(), pkey);
diff --git a/chromium/net/base/keygen_handler_unittest.cc b/chromium/net/base/keygen_handler_unittest.cc
index 85c3844c067..2357328e42c 100644
--- a/chromium/net/base/keygen_handler_unittest.cc
+++ b/chromium/net/base/keygen_handler_unittest.cc
@@ -14,27 +14,60 @@
#include "base/threading/thread_restrictions.h"
#include "base/synchronization/waitable_event.h"
#include "build/build_config.h"
-#include "crypto/nss_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(USE_NSS)
#include <private/pprthred.h> // PR_DetachThread
+#include "crypto/nss_crypto_module_delegate.h"
+#include "crypto/scoped_test_nss_db.h"
#endif
namespace net {
namespace {
+#if defined(USE_NSS)
+class StubCryptoModuleDelegate : public crypto::NSSCryptoModuleDelegate {
+ public:
+ explicit StubCryptoModuleDelegate(crypto::ScopedPK11Slot slot)
+ : slot_(slot.Pass()) {}
+
+ std::string RequestPassword(const std::string& slot_name,
+ bool retry,
+ bool* cancelled) override {
+ return std::string();
+ }
+
+ crypto::ScopedPK11Slot RequestSlot() override {
+ return crypto::ScopedPK11Slot(PK11_ReferenceSlot(slot_.get()));
+ }
+
+ private:
+ crypto::ScopedPK11Slot slot_;
+};
+#endif
+
class KeygenHandlerTest : public ::testing::Test {
public:
KeygenHandlerTest() {}
- virtual ~KeygenHandlerTest() {}
+ ~KeygenHandlerTest() override {}
- virtual void SetUp() {
-#if defined(OS_CHROMEOS) && defined(USE_NSS)
- crypto::OpenPersistentNSSDB();
+ scoped_ptr<KeygenHandler> CreateKeygenHandler() {
+ scoped_ptr<KeygenHandler> handler(new KeygenHandler(
+ 768, "some challenge", GURL("http://www.example.com")));
+#if defined(USE_NSS)
+ handler->set_crypto_module_delegate(
+ scoped_ptr<crypto::NSSCryptoModuleDelegate>(
+ new StubCryptoModuleDelegate(crypto::ScopedPK11Slot(
+ PK11_ReferenceSlot(test_nss_db_.slot())))));
#endif
+ return handler.Pass();
}
+
+ private:
+#if defined(USE_NSS)
+ crypto::ScopedTestNSSDB test_nss_db_;
+#endif
};
// Assert that |result| is a valid output for KeygenHandler given challenge
@@ -74,22 +107,22 @@ void AssertValidSignedPublicKeyAndChallenge(const std::string& result,
}
TEST_F(KeygenHandlerTest, SmokeTest) {
- KeygenHandler handler(768, "some challenge", GURL("http://www.example.com"));
- handler.set_stores_key(false); // Don't leave the key-pair behind
- std::string result = handler.GenKeyAndSignChallenge();
+ scoped_ptr<KeygenHandler> handler(CreateKeygenHandler());
+ handler->set_stores_key(false); // Don't leave the key-pair behind
+ std::string result = handler->GenKeyAndSignChallenge();
VLOG(1) << "KeygenHandler produced: " << result;
AssertValidSignedPublicKeyAndChallenge(result, "some challenge");
}
-void ConcurrencyTestCallback(base::WaitableEvent* event,
- const std::string& challenge,
+void ConcurrencyTestCallback(const std::string& challenge,
+ base::WaitableEvent* event,
+ scoped_ptr<KeygenHandler> handler,
std::string* result) {
// We allow Singleton use on the worker thread here since we use a
// WaitableEvent to synchronize, so it's safe.
base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton;
- KeygenHandler handler(768, challenge, GURL("http://www.example.com"));
- handler.set_stores_key(false); // Don't leave the key-pair behind.
- *result = handler.GenKeyAndSignChallenge();
+ handler->set_stores_key(false); // Don't leave the key-pair behind.
+ *result = handler->GenKeyAndSignChallenge();
event->Signal();
#if defined(USE_NSS)
// Detach the thread from NSPR.
@@ -110,12 +143,15 @@ TEST_F(KeygenHandlerTest, ConcurrencyTest) {
base::WaitableEvent* events[NUM_HANDLERS] = { NULL };
std::string results[NUM_HANDLERS];
for (int i = 0; i < NUM_HANDLERS; i++) {
+ scoped_ptr<KeygenHandler> handler(CreateKeygenHandler());
events[i] = new base::WaitableEvent(false, false);
- base::WorkerPool::PostTask(
- FROM_HERE,
- base::Bind(ConcurrencyTestCallback, events[i], "some challenge",
- &results[i]),
- true);
+ base::WorkerPool::PostTask(FROM_HERE,
+ base::Bind(ConcurrencyTestCallback,
+ "some challenge",
+ events[i],
+ base::Passed(&handler),
+ &results[i]),
+ true);
}
for (int i = 0; i < NUM_HANDLERS; i++) {
diff --git a/chromium/net/base/keygen_handler_win.cc b/chromium/net/base/keygen_handler_win.cc
index 59dc69de54c..44365fa136d 100644
--- a/chromium/net/base/keygen_handler_win.cc
+++ b/chromium/net/base/keygen_handler_win.cc
@@ -5,10 +5,7 @@
#include "net/base/keygen_handler.h"
#include <windows.h>
-#include <wincrypt.h>
-#pragma comment(lib, "crypt32.lib")
#include <rpc.h>
-#pragma comment(lib, "rpcrt4.lib")
#include <list>
#include <string>
@@ -22,7 +19,10 @@
#include "base/strings/utf_string_conversions.h"
#include "crypto/capi_util.h"
#include "crypto/scoped_capi_types.h"
+#include "crypto/wincrypt_shim.h"
+#pragma comment(lib, "crypt32.lib")
+#pragma comment(lib, "rpcrt4.lib")
namespace net {
@@ -36,7 +36,8 @@ bool GetSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) {
// as a CERT_PUBLIC_KEY_INFO structure. Currently, only RSA public keys are
// supported.
ok = CryptExportPublicKeyInfoEx(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- szOID_RSA_RSA, 0, NULL, NULL, &size);
+ const_cast<char*>(szOID_RSA_RSA), 0, NULL,
+ NULL, &size);
DCHECK(ok);
if (!ok)
return false;
@@ -46,8 +47,8 @@ bool GetSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) {
PCERT_PUBLIC_KEY_INFO public_key_casted =
reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&(*output)[0]);
ok = CryptExportPublicKeyInfoEx(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- szOID_RSA_RSA, 0, NULL, public_key_casted,
- &size);
+ const_cast<char*>(szOID_RSA_RSA), 0, NULL,
+ public_key_casted, &size);
DCHECK(ok);
if (!ok)
return false;
@@ -64,7 +65,7 @@ bool GetSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) {
bool GetSignedPublicKeyAndChallenge(HCRYPTPROV prov,
const std::string& challenge,
std::string* output) {
- std::wstring wide_challenge = base::ASCIIToWide(challenge);
+ base::string16 challenge16 = base::ASCIIToUTF16(challenge);
std::vector<BYTE> spki;
if (!GetSubjectPublicKeyInfo(prov, &spki))
@@ -78,11 +79,11 @@ bool GetSignedPublicKeyAndChallenge(HCRYPTPROV prov,
pkac.dwVersion = CERT_KEYGEN_REQUEST_V1;
pkac.SubjectPublicKeyInfo =
*reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&spki[0]);
- pkac.pwszChallengeString = const_cast<wchar_t*>(wide_challenge.c_str());
+ pkac.pwszChallengeString = const_cast<base::char16*>(challenge16.c_str());
CRYPT_ALGORITHM_IDENTIFIER sig_alg;
memset(&sig_alg, 0, sizeof(sig_alg));
- sig_alg.pszObjId = szOID_RSA_MD5RSA;
+ sig_alg.pszObjId = const_cast<char*>(szOID_RSA_MD5RSA);
BOOL ok;
DWORD size = 0;
diff --git a/chromium/net/base/linked_hash_map.h b/chromium/net/base/linked_hash_map.h
index 7948647df05..b024ca1d536 100644
--- a/chromium/net/base/linked_hash_map.h
+++ b/chromium/net/base/linked_hash_map.h
@@ -79,6 +79,28 @@ class linked_hash_map {
return list_.rend();
}
+ // Front and back accessors common to many stl containers.
+
+ // Returns the earliest-inserted element
+ const value_type& front() const {
+ return list_.front();
+ }
+
+ // Returns the earliest-inserted element.
+ value_type& front() {
+ return list_.front();
+ }
+
+ // Returns the most-recently-inserted element.
+ const value_type& back() const {
+ return list_.back();
+ }
+
+ // Returns the most-recently-inserted element.
+ value_type& back() {
+ return list_.back();
+ }
+
// Clears the map of all values.
void clear() {
map_.clear();
diff --git a/chromium/net/base/load_flags_list.h b/chromium/net/base/load_flags_list.h
index 2d004886d1c..6e49bbbcc08 100644
--- a/chromium/net/base/load_flags_list.h
+++ b/chromium/net/base/load_flags_list.h
@@ -38,89 +38,90 @@ LOAD_FLAG(DISABLE_CACHE, 1 << 5)
// URLRequest::Interceptors.
LOAD_FLAG(DISABLE_INTERCEPT, 1 << 6)
-// If present, upload progress messages should be provided to initiator.
-LOAD_FLAG(ENABLE_UPLOAD_PROGRESS, 1 << 7)
-
-// If present, collect load timing for the request.
-LOAD_FLAG(ENABLE_LOAD_TIMING, 1 << 8)
-
// If present, ignores certificate mismatches with the domain name.
// (The default behavior is to trigger an OnSSLCertificateError callback.)
-LOAD_FLAG(IGNORE_CERT_COMMON_NAME_INVALID, 1 << 9)
+LOAD_FLAG(IGNORE_CERT_COMMON_NAME_INVALID, 1 << 7)
// If present, ignores certificate expiration dates
// (The default behavior is to trigger an OnSSLCertificateError callback).
-LOAD_FLAG(IGNORE_CERT_DATE_INVALID, 1 << 10)
+LOAD_FLAG(IGNORE_CERT_DATE_INVALID, 1 << 8)
// If present, trusts all certificate authorities
// (The default behavior is to trigger an OnSSLCertificateError callback).
-LOAD_FLAG(IGNORE_CERT_AUTHORITY_INVALID, 1 << 11)
+LOAD_FLAG(IGNORE_CERT_AUTHORITY_INVALID, 1 << 9)
// If present, causes certificate revocation checks to be skipped on secure
// connections.
-LOAD_FLAG(DISABLE_CERT_REVOCATION_CHECKING, 1 << 12)
+LOAD_FLAG(DISABLE_CERT_REVOCATION_CHECKING, 1 << 10)
// If present, ignores wrong key usage of the certificate
// (The default behavior is to trigger an OnSSLCertificateError callback).
-LOAD_FLAG(IGNORE_CERT_WRONG_USAGE, 1 << 13)
+LOAD_FLAG(IGNORE_CERT_WRONG_USAGE, 1 << 11)
// This load will not make any changes to cookies, including storing new
// cookies or updating existing ones.
-LOAD_FLAG(DO_NOT_SAVE_COOKIES, 1 << 14)
+LOAD_FLAG(DO_NOT_SAVE_COOKIES, 1 << 12)
// Do not resolve proxies. This override is used when downloading PAC files
// to avoid having a circular dependency.
-LOAD_FLAG(BYPASS_PROXY, 1 << 15)
+LOAD_FLAG(BYPASS_PROXY, 1 << 13)
// Indicate this request is for a download, as opposed to viewing.
-LOAD_FLAG(IS_DOWNLOAD, 1 << 16)
+LOAD_FLAG(IS_DOWNLOAD, 1 << 14)
// Requires EV certificate verification.
-LOAD_FLAG(VERIFY_EV_CERT, 1 << 17)
+LOAD_FLAG(VERIFY_EV_CERT, 1 << 15)
// This load will not send any cookies.
-LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 18)
+LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 16)
// This load will not send authentication data (user name/password)
// to the server (as opposed to the proxy).
-LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 19)
+LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 17)
// This should only be used for testing (set by HttpNetworkTransaction).
-LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 20)
+LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 18)
// Indicate that this is a top level frame, so that we don't assume it is a
// subresource and speculatively pre-connect or pre-resolve when a referring
// page is loaded.
-LOAD_FLAG(MAIN_FRAME, 1 << 21)
+LOAD_FLAG(MAIN_FRAME, 1 << 19)
// Indicate that this is a sub frame, and hence it might have subresources that
// should be speculatively resolved, or even speculatively preconnected.
-LOAD_FLAG(SUB_FRAME, 1 << 22)
+LOAD_FLAG(SUB_FRAME, 1 << 20)
// If present, intercept actual request/response headers from network stack
// and report them to renderer. This includes cookies, so the flag is only
// respected if renderer has CanReadRawCookies capability in the security
// policy.
-LOAD_FLAG(REPORT_RAW_HEADERS, 1 << 23)
+LOAD_FLAG(REPORT_RAW_HEADERS, 1 << 21)
// Indicates that this load was motivated by the rel=prefetch feature,
// and is (in theory) not intended for the current frame.
-LOAD_FLAG(PREFETCH, 1 << 24)
+LOAD_FLAG(PREFETCH, 1 << 22)
// Indicates that this is a load that ignores limits and should complete
// immediately.
-LOAD_FLAG(IGNORE_LIMITS, 1 << 25)
+LOAD_FLAG(IGNORE_LIMITS, 1 << 23)
// Suppress login prompts for this request. Cached credentials or
// default credentials may still be used for authentication.
-LOAD_FLAG(DO_NOT_PROMPT_FOR_LOGIN, 1 << 26)
+LOAD_FLAG(DO_NOT_PROMPT_FOR_LOGIN, 1 << 24)
// Indicates that the operation is somewhat likely to be due to an
// explicit user action. This can be used as a hint to treat the
// request with higher priority.
-LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 27)
+LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 25)
// Indicates that the username:password portion of the URL should not
// be honored, but that other forms of authority may be used.
-LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 28)
+LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 26)
+
+// Send request directly to the origin if the effective proxy is the data
+// reduction proxy.
+// TODO(rcs): Remove this flag as soon as http://crbug.com/339237 is resolved.
+LOAD_FLAG(BYPASS_DATA_REDUCTION_PROXY, 1 << 27)
+// Indicates the the request is an asynchronous revalidation.
+LOAD_FLAG(ASYNC_REVALIDATION, 1 << 28)
diff --git a/chromium/net/base/mime_sniffer.cc b/chromium/net/base/mime_sniffer.cc
index ef2e27030bb..61ef9482110 100644
--- a/chromium/net/base/mime_sniffer.cc
+++ b/chromium/net/base/mime_sniffer.cc
@@ -612,12 +612,14 @@ static bool SniffXML(const char* content,
if (!pos)
return false;
- if (base::strncasecmp(pos, "<?xml", sizeof("<?xml") - 1) == 0) {
+ if ((pos + sizeof("<?xml") - 1 <= end) &&
+ (base::strncasecmp(pos, "<?xml", sizeof("<?xml") - 1) == 0)) {
// Skip XML declarations.
++pos;
continue;
- } else if (base::strncasecmp(pos, "<!DOCTYPE",
- sizeof("<!DOCTYPE") - 1) == 0) {
+ } else if ((pos + sizeof("<!DOCTYPE") - 1 <= end) &&
+ (base::strncasecmp(pos, "<!DOCTYPE", sizeof("<!DOCTYPE") - 1) ==
+ 0)) {
// Skip DOCTYPE declarations.
++pos;
continue;
diff --git a/chromium/net/base/mime_util.cc b/chromium/net/base/mime_util.cc
index 9b02c4c18d0..27f3c7049ad 100644
--- a/chromium/net/base/mime_util.cc
+++ b/chromium/net/base/mime_util.cc
@@ -11,6 +11,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -50,6 +51,25 @@ namespace net {
// Singleton utility class for mime types.
class MimeUtil : public PlatformMimeUtil {
public:
+ enum Codec {
+ INVALID_CODEC,
+ PCM,
+ MP3,
+ MPEG2_AAC_LC,
+ MPEG2_AAC_MAIN,
+ MPEG2_AAC_SSR,
+ MPEG4_AAC_LC,
+ MPEG4_AAC_SBRv1,
+ VORBIS,
+ OPUS,
+ H264_BASELINE,
+ H264_MAIN,
+ H264_HIGH,
+ VP8,
+ VP9,
+ THEORA
+ };
+
bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext,
std::string* mime_type) const;
@@ -83,7 +103,7 @@ class MimeUtil : public PlatformMimeUtil {
bool strip);
bool IsStrictMediaMimeType(const std::string& mime_type) const;
- bool IsSupportedStrictMediaMimeType(
+ SupportsType IsSupportedStrictMediaMimeType(
const std::string& mime_type,
const std::vector<std::string>& codecs) const;
@@ -93,14 +113,27 @@ class MimeUtil : public PlatformMimeUtil {
friend struct base::DefaultLazyInstanceTraits<MimeUtil>;
typedef base::hash_set<std::string> MimeMappings;
- typedef std::map<std::string, MimeMappings> StrictMappings;
+
+ typedef base::hash_set<int> CodecSet;
+ typedef std::map<std::string, CodecSet> StrictMappings;
+ struct CodecEntry {
+ CodecEntry() : codec(INVALID_CODEC), is_ambiguous(true) {}
+ CodecEntry(Codec c, bool ambiguous) : codec(c), is_ambiguous(ambiguous) {}
+ Codec codec;
+ bool is_ambiguous;
+ };
+ typedef std::map<std::string, CodecEntry> StringToCodecMappings;
MimeUtil();
- // Returns true if |codecs| is nonempty and all the items in it are present in
- // |supported_codecs|.
- static bool AreSupportedCodecs(const MimeMappings& supported_codecs,
- const std::vector<std::string>& codecs);
+ // Returns IsSupported if all codec IDs in |codecs| are unambiguous
+ // and are supported by the platform. MayBeSupported is returned if
+ // at least one codec ID in |codecs| is ambiguous but all the codecs
+ // are supported by the platform. IsNotSupported is returned if at
+ // least one codec ID is not supported by the platform.
+ SupportsType AreSupportedCodecs(
+ const CodecSet& supported_codecs,
+ const std::vector<std::string>& codecs) const;
// For faster lookup, keep hash sets.
void InitializeMimeTypeMaps();
@@ -109,14 +142,51 @@ class MimeUtil : public PlatformMimeUtil {
bool include_platform_types,
std::string* mime_type) const;
+ // Converts a codec ID into an Codec enum value and indicates
+ // whether the conversion was ambiguous.
+ // Returns true if this method was able to map |codec_id| to a specific
+ // Codec enum value. |codec| and |is_ambiguous| are only valid if true
+ // is returned. Otherwise their value is undefined after the call.
+ // |is_ambiguous| is true if |codec_id| did not have enough information to
+ // unambiguously determine the proper Codec enum value. If |is_ambiguous|
+ // is true |codec| contains the best guess for the intended Codec enum value.
+ bool StringToCodec(const std::string& codec_id,
+ Codec* codec,
+ bool* is_ambiguous) const;
+
+ // Returns true if |codec| is supported by the platform.
+ // Note: This method will return false if the platform supports proprietary
+ // codecs but |allow_proprietary_codecs_| is set to false.
+ bool IsCodecSupported(Codec codec) const;
+
+ // Returns true if |codec| refers to a proprietary codec.
+ bool IsCodecProprietary(Codec codec) const;
+
+ // Returns true and sets |*default_codec| if |mime_type| has a
+ // default codec associated with it.
+ // Returns false otherwise and the value of |*default_codec| is undefined.
+ bool GetDefaultCodec(const std::string& mime_type,
+ Codec* default_codec) const;
+
+ // Returns true if |mime_type| has a default codec associated with it
+ // and IsCodecSupported() returns true for that particular codec.
+ bool IsDefaultCodecSupported(const std::string& mime_type) const;
+
MimeMappings image_map_;
MimeMappings media_map_;
MimeMappings non_image_map_;
MimeMappings unsupported_text_map_;
MimeMappings javascript_map_;
- MimeMappings codecs_map_;
+ // A map of mime_types and hash map of the supported codecs for the mime_type.
StrictMappings strict_format_map_;
+
+ // Keeps track of whether proprietary codec support should be
+ // advertised to callers.
+ bool allow_proprietary_codecs_;
+
+ // Lookup table for string compare based string -> Codec mappings.
+ StringToCodecMappings string_to_codec_map_;
}; // class MimeUtil
// This variable is Leaky because we need to access it from WorkerPool threads.
@@ -173,7 +243,8 @@ static const MimeInfo secondary_mappings[] = {
{ "application/vnd.mozilla.xul+xml", "xul" },
{ "application/x-shockwave-flash", "swf,swl" },
{ "application/pkcs7-mime", "p7m,p7c,p7z" },
- { "application/pkcs7-signature", "p7s" }
+ { "application/pkcs7-signature", "p7s" },
+ { "application/x-mpegurl", "m3u8" },
};
static const char* FindMimeType(const MimeInfo* mappings,
@@ -308,32 +379,11 @@ static const char* const proprietary_media_types[] = {
"audio/mp3",
"audio/x-mp3",
"audio/mpeg",
-};
-// List of supported codecs when passed in with <source type="...">.
-// This set of codecs is supported by all variations of Chromium.
-//
-// Refer to http://wiki.whatwg.org/wiki/Video_type_parameters#Browser_Support
-// for more information.
-//
-// The codecs for WAV are integers as defined in Appendix A of RFC2361:
-// http://tools.ietf.org/html/rfc2361
-static const char* const common_media_codecs[] = {
-#if !defined(OS_ANDROID) // Android doesn't support Ogg Theora.
- "theora",
+#if defined(ENABLE_MPEG2TS_STREAM_PARSER)
+ // MPEG-2 TS.
+ "video/mp2t",
#endif
- "opus",
- "vorbis",
- "vp8",
- "vp9",
- "1" // WAVE_FORMAT_PCM.
-};
-
-// List of proprietary codecs only supported by Google Chrome.
-static const char* const proprietary_media_codecs[] = {
- "avc1",
- "avc3",
- "mp4a"
};
// Note:
@@ -417,23 +467,42 @@ static const char* const supported_javascript_types[] = {
};
#if defined(OS_ANDROID)
-static bool IsCodecSupportedOnAndroid(const std::string& codec) {
- // Theora is not supported in Android
- if (!codec.compare("theora"))
- return false;
+static bool IsCodecSupportedOnAndroid(MimeUtil::Codec codec) {
+ switch (codec) {
+ case MimeUtil::INVALID_CODEC:
+ return false;
- // VP9 is supported only in KitKat+ (API Level 19).
- if ((!codec.compare("vp9") || !codec.compare("vp9.0")) &&
- base::android::BuildInfo::GetInstance()->sdk_int() < 19) {
- return false;
- }
+ case MimeUtil::PCM:
+ case MimeUtil::MP3:
+ case MimeUtil::MPEG4_AAC_LC:
+ case MimeUtil::MPEG4_AAC_SBRv1:
+ case MimeUtil::H264_BASELINE:
+ case MimeUtil::H264_MAIN:
+ case MimeUtil::H264_HIGH:
+ case MimeUtil::VP8:
+ case MimeUtil::VORBIS:
+ return true;
- // TODO(vigneshv): Change this similar to the VP9 check once Opus is
- // supported on Android (http://crbug.com/318436).
- if (!codec.compare("opus")) {
- return false;
+ case MimeUtil::MPEG2_AAC_LC:
+ case MimeUtil::MPEG2_AAC_MAIN:
+ case MimeUtil::MPEG2_AAC_SSR:
+ // MPEG-2 variants of AAC are not supported on Android.
+ return false;
+
+ case MimeUtil::VP9:
+ // VP9 is supported only in KitKat+ (API Level 19).
+ return base::android::BuildInfo::GetInstance()->sdk_int() >= 19;
+
+ case MimeUtil::OPUS:
+ // TODO(vigneshv): Change this similar to the VP9 check once Opus is
+ // supported on Android (http://crbug.com/318436).
+ return false;
+
+ case MimeUtil::THEORA:
+ return false;
}
- return true;
+
+ return false;
}
static bool IsMimeTypeSupportedOnAndroid(const std::string& mimeType) {
@@ -452,6 +521,24 @@ struct MediaFormatStrict {
const char* codecs_list;
};
+// Following is the list of RFC 6381 compliant codecs:
+// mp4a.66 - MPEG-2 AAC MAIN
+// mp4a.67 - MPEG-2 AAC LC
+// mp4a.68 - MPEG-2 AAC SSR
+// mp4a.69 - MPEG-2 extension to MPEG-1
+// mp4a.6B - MPEG-1 audio
+// mp4a.40.2 - MPEG-4 AAC LC
+// mp4a.40.5 - MPEG-4 AAC SBRv1
+//
+// avc1.42E0xx - H.264 Baseline
+// avc1.4D40xx - H.264 Main
+// avc1.6400xx - H.264 High
+static const char kMP4AudioCodecsExpression[] =
+ "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.5";
+static const char kMP4VideoCodecsExpression[] =
+ "avc1.42E00A,avc1.4D400A,avc1.64000A," \
+ "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.5";
+
static const MediaFormatStrict format_codec_mappings[] = {
{ "video/webm", "opus,vorbis,vp8,vp8.0,vp9,vp9.0" },
{ "audio/webm", "opus,vorbis" },
@@ -460,39 +547,82 @@ static const MediaFormatStrict format_codec_mappings[] = {
{ "video/ogg", "opus,theora,vorbis" },
{ "audio/ogg", "opus,vorbis" },
{ "application/ogg", "opus,theora,vorbis" },
- { "audio/mpeg", ",mp3" }, // Note: The comma before the 'mp3'results in an
- // empty string codec ID and indicates
- // a missing codecs= parameter is also valid.
- // The presense of 'mp3' is not RFC compliant,
- // but is common in the wild so it is a defacto
- // standard.
+ { "audio/mpeg", "mp3" },
{ "audio/mp3", "" },
- { "audio/x-mp3", "" }
+ { "audio/x-mp3", "" },
+ { "audio/mp4", kMP4AudioCodecsExpression },
+ { "audio/x-m4a", kMP4AudioCodecsExpression },
+ { "video/mp4", kMP4VideoCodecsExpression },
+ { "video/x-m4v", kMP4VideoCodecsExpression },
+ { "application/x-mpegurl", kMP4VideoCodecsExpression },
+ { "application/vnd.apple.mpegurl", kMP4VideoCodecsExpression }
};
-MimeUtil::MimeUtil() {
+struct CodecIDMappings {
+ const char* const codec_id;
+ MimeUtil::Codec codec;
+};
+
+// List of codec IDs that provide enough information to determine the
+// codec and profile being requested.
+//
+// The "mp4a" strings come from RFC 6381.
+static const CodecIDMappings kUnambiguousCodecIDs[] = {
+ { "1", MimeUtil::PCM }, // We only allow this for WAV so it isn't ambiguous.
+ { "mp3", MimeUtil::MP3 },
+ { "mp4a.66", MimeUtil::MPEG2_AAC_MAIN },
+ { "mp4a.67", MimeUtil::MPEG2_AAC_LC },
+ { "mp4a.68", MimeUtil::MPEG2_AAC_SSR },
+ { "mp4a.69", MimeUtil::MP3 },
+ { "mp4a.6B", MimeUtil::MP3 },
+ { "mp4a.40.2", MimeUtil::MPEG4_AAC_LC },
+ { "mp4a.40.5", MimeUtil::MPEG4_AAC_SBRv1 },
+ { "vorbis", MimeUtil::VORBIS },
+ { "opus", MimeUtil::OPUS },
+ { "vp8", MimeUtil::VP8 },
+ { "vp8.0", MimeUtil::VP8 },
+ { "vp9", MimeUtil::VP9 },
+ { "vp9.0", MimeUtil::VP9 },
+ { "theora", MimeUtil::THEORA }
+};
+
+// List of codec IDs that are ambiguous and don't provide
+// enough information to determine the codec and profile.
+// The codec in these entries indicate the codec and profile
+// we assume the user is trying to indicate.
+static const CodecIDMappings kAmbiguousCodecIDs[] = {
+ { "mp4a.40", MimeUtil::MPEG4_AAC_LC },
+ { "avc1", MimeUtil::H264_BASELINE },
+ { "avc3", MimeUtil::H264_BASELINE },
+};
+
+MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
InitializeMimeTypeMaps();
}
-// static
-bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs,
- const std::vector<std::string>& codecs) {
- if (supported_codecs.empty())
- return codecs.empty();
-
- // If no codecs are specified in the mimetype, check to see if a missing
- // codecs parameter is allowed.
- if (codecs.empty())
- return supported_codecs.find(std::string()) != supported_codecs.end();
+SupportsType MimeUtil::AreSupportedCodecs(
+ const CodecSet& supported_codecs,
+ const std::vector<std::string>& codecs) const {
+ DCHECK(!supported_codecs.empty());
+ DCHECK(!codecs.empty());
+ SupportsType result = IsSupported;
for (size_t i = 0; i < codecs.size(); ++i) {
- if (codecs[i].empty() ||
- supported_codecs.find(codecs[i]) == supported_codecs.end()) {
- return false;
+ bool is_ambiguous = true;
+ Codec codec = INVALID_CODEC;
+ if (!StringToCodec(codecs[i], &codec, &is_ambiguous))
+ return IsNotSupported;
+
+ if (!IsCodecSupported(codec) ||
+ supported_codecs.find(codec) == supported_codecs.end()) {
+ return IsNotSupported;
}
+
+ if (is_ambiguous)
+ result = MayBeSupported;
}
- return true;
+ return result;
}
void MimeUtil::InitializeMimeTypeMaps() {
@@ -516,6 +646,8 @@ void MimeUtil::InitializeMimeTypeMaps() {
non_image_map_.insert(common_media_types[i]);
}
#if defined(USE_PROPRIETARY_CODECS)
+ allow_proprietary_codecs_ = true;
+
for (size_t i = 0; i < arraysize(proprietary_media_types); ++i)
non_image_map_.insert(proprietary_media_types[i]);
#endif
@@ -536,17 +668,15 @@ void MimeUtil::InitializeMimeTypeMaps() {
for (size_t i = 0; i < arraysize(supported_javascript_types); ++i)
javascript_map_.insert(supported_javascript_types[i]);
- for (size_t i = 0; i < arraysize(common_media_codecs); ++i) {
-#if defined(OS_ANDROID)
- if (!IsCodecSupportedOnAndroid(common_media_codecs[i]))
- continue;
-#endif
- codecs_map_.insert(common_media_codecs[i]);
+ for (size_t i = 0; i < arraysize(kUnambiguousCodecIDs); ++i) {
+ string_to_codec_map_[kUnambiguousCodecIDs[i].codec_id] =
+ CodecEntry(kUnambiguousCodecIDs[i].codec, false);
+ }
+
+ for (size_t i = 0; i < arraysize(kAmbiguousCodecIDs); ++i) {
+ string_to_codec_map_[kAmbiguousCodecIDs[i].codec_id] =
+ CodecEntry(kAmbiguousCodecIDs[i].codec, true);
}
-#if defined(USE_PROPRIETARY_CODECS)
- for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i)
- codecs_map_.insert(proprietary_media_codecs[i]);
-#endif
// Initialize the strict supported media types.
for (size_t i = 0; i < arraysize(format_codec_mappings); ++i) {
@@ -555,14 +685,15 @@ void MimeUtil::InitializeMimeTypeMaps() {
&mime_type_codecs,
false);
- MimeMappings codecs;
+ CodecSet codecs;
for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
-#if defined(OS_ANDROID)
- if (!IsCodecSupportedOnAndroid(mime_type_codecs[j]))
- continue;
-#endif
- codecs.insert(mime_type_codecs[j]);
+ Codec codec = INVALID_CODEC;
+ bool is_ambiguous = true;
+ CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous));
+ DCHECK(!is_ambiguous);
+ codecs.insert(codec);
}
+
strict_format_map_[format_codec_mappings[i].mime_type] = codecs;
}
}
@@ -639,8 +770,8 @@ bool MatchesMimeTypeParameters(const std::string& mime_type_pattern,
bool MimeUtil::MatchesMimeType(const std::string& mime_type_pattern,
const std::string& mime_type) const {
// Verify caller is passing lowercase strings.
- DCHECK_EQ(StringToLowerASCII(mime_type_pattern), mime_type_pattern);
- DCHECK_EQ(StringToLowerASCII(mime_type), mime_type);
+ DCHECK_EQ(base::StringToLowerASCII(mime_type_pattern), mime_type_pattern);
+ DCHECK_EQ(base::StringToLowerASCII(mime_type), mime_type);
if (mime_type_pattern.empty())
return false;
@@ -710,7 +841,7 @@ bool MimeUtil::ParseMimeTypeWithoutParameter(
}
bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const {
- std::string lower_type = StringToLowerASCII(type_string);
+ std::string lower_type = base::StringToLowerASCII(type_string);
for (size_t i = 0; i < arraysize(legal_top_level_types); ++i) {
if (lower_type.compare(legal_top_level_types[i]) == 0)
return true;
@@ -721,7 +852,15 @@ bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const {
bool MimeUtil::AreSupportedMediaCodecs(
const std::vector<std::string>& codecs) const {
- return AreSupportedCodecs(codecs_map_, codecs);
+ for (size_t i = 0; i < codecs.size(); ++i) {
+ Codec codec = INVALID_CODEC;
+ bool is_ambiguous = true;
+ if (!StringToCodec(codecs[i], &codec, &is_ambiguous) ||
+ !IsCodecSupported(codec)) {
+ return false;
+ }
+ }
+ return true;
}
void MimeUtil::ParseCodecString(const std::string& codecs,
@@ -745,17 +884,36 @@ void MimeUtil::ParseCodecString(const std::string& codecs,
}
bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const {
- if (strict_format_map_.find(mime_type) == strict_format_map_.end())
- return false;
- return true;
+ return strict_format_map_.find(mime_type) != strict_format_map_.end();
}
-bool MimeUtil::IsSupportedStrictMediaMimeType(
+SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
const std::string& mime_type,
const std::vector<std::string>& codecs) const {
- StrictMappings::const_iterator it = strict_format_map_.find(mime_type);
- return (it != strict_format_map_.end()) &&
- AreSupportedCodecs(it->second, codecs);
+ StrictMappings::const_iterator it_strict_map =
+ strict_format_map_.find(mime_type);
+ if (it_strict_map == strict_format_map_.end())
+ return codecs.empty() ? MayBeSupported : IsNotSupported;
+
+ if (it_strict_map->second.empty()) {
+ // We get here if the mimetype does not expect a codecs parameter.
+ return (codecs.empty() && IsDefaultCodecSupported(mime_type)) ?
+ IsSupported : IsNotSupported;
+ }
+
+ if (codecs.empty()) {
+ // We get here if the mimetype expects to get a codecs parameter,
+ // but didn't get one. If |mime_type| does not have a default codec
+ // the best we can do is say "maybe" because we don't have enough
+ // information.
+ Codec default_codec = INVALID_CODEC;
+ if (!GetDefaultCodec(mime_type, &default_codec))
+ return MayBeSupported;
+
+ return IsCodecSupported(default_codec) ? IsSupported : IsNotSupported;
+ }
+
+ return AreSupportedCodecs(it_strict_map->second, codecs);
}
void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
@@ -763,8 +921,165 @@ void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
non_image_map_.erase(proprietary_media_types[i]);
media_map_.erase(proprietary_media_types[i]);
}
- for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i)
- codecs_map_.erase(proprietary_media_codecs[i]);
+ allow_proprietary_codecs_ = false;
+}
+
+// Returns true iff |profile_str| conforms to hex string "42y0", where y is one
+// of [8..F]. Requiring constraint_set0_flag be set and profile_idc be 0x42 is
+// taken from ISO-14496-10 7.3.2.1, 7.4.2.1, and Annex A.2.1.
+//
+// |profile_str| is the first four characters of the H.264 suffix string
+// (ignoring the last 2 characters of the full 6 character suffix that are
+// level_idc). From ISO-14496-10 7.3.2.1, it consists of:
+// 8 bits: profile_idc: required to be 0x42 here.
+// 1 bit: constraint_set0_flag : required to be true here.
+// 1 bit: constraint_set1_flag : ignored here.
+// 1 bit: constraint_set2_flag : ignored here.
+// 1 bit: constraint_set3_flag : ignored here.
+// 4 bits: reserved : required to be 0 here.
+//
+// The spec indicates other ways, not implemented here, that a |profile_str|
+// can indicate a baseline conforming decoder is sufficient for decode in Annex
+// A.2.1: "[profile_idc not necessarily 0x42] with constraint_set0_flag set and
+// in which level_idc and constraint_set3_flag represent a level less than or
+// equal to the specified level."
+static bool IsValidH264BaselineProfile(const std::string& profile_str) {
+ uint32 constraint_set_bits;
+ if (profile_str.size() != 4 ||
+ profile_str[0] != '4' ||
+ profile_str[1] != '2' ||
+ profile_str[3] != '0' ||
+ !base::HexStringToUInt(base::StringPiece(profile_str.c_str() + 2, 1),
+ &constraint_set_bits)) {
+ return false;
+ }
+
+ return constraint_set_bits >= 8;
+}
+
+static bool IsValidH264Level(const std::string& level_str) {
+ uint32 level;
+ if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level))
+ return false;
+
+ // Valid levels taken from Table A-1 in ISO-14496-10.
+ // Essentially |level_str| is toHex(10 * level).
+ return ((level >= 10 && level <= 13) ||
+ (level >= 20 && level <= 22) ||
+ (level >= 30 && level <= 32) ||
+ (level >= 40 && level <= 42) ||
+ (level >= 50 && level <= 51));
+}
+
+// Handle parsing H.264 codec IDs as outlined in RFC 6381 and ISO-14496-10.
+// avc1.42y0xx, y >= 8 - H.264 Baseline
+// avc1.4D40xx - H.264 Main
+// avc1.6400xx - H.264 High
+//
+// avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to
+// signal H.264 Baseline. For example, the idc_level, profile_idc and
+// constraint_set3_flag pieces may explicitly require decoder to conform to
+// baseline profile at the specified level (see Annex A and constraint_set0 in
+// ISO-14496-10).
+static bool ParseH264CodecID(const std::string& codec_id,
+ MimeUtil::Codec* codec,
+ bool* is_ambiguous) {
+ // Make sure we have avc1.xxxxxx or avc3.xxxxxx
+ if (codec_id.size() != 11 ||
+ (!StartsWithASCII(codec_id, "avc1.", true) &&
+ !StartsWithASCII(codec_id, "avc3.", true))) {
+ return false;
+ }
+
+ std::string profile = StringToUpperASCII(codec_id.substr(5, 4));
+ if (IsValidH264BaselineProfile(profile)) {
+ *codec = MimeUtil::H264_BASELINE;
+ } else if (profile == "4D40") {
+ *codec = MimeUtil::H264_MAIN;
+ } else if (profile == "6400") {
+ *codec = MimeUtil::H264_HIGH;
+ } else {
+ *codec = MimeUtil::H264_BASELINE;
+ *is_ambiguous = true;
+ return true;
+ }
+
+ *is_ambiguous = !IsValidH264Level(StringToUpperASCII(codec_id.substr(9)));
+ return true;
+}
+
+bool MimeUtil::StringToCodec(const std::string& codec_id,
+ Codec* codec,
+ bool* is_ambiguous) const {
+ StringToCodecMappings::const_iterator itr =
+ string_to_codec_map_.find(codec_id);
+ if (itr != string_to_codec_map_.end()) {
+ *codec = itr->second.codec;
+ *is_ambiguous = itr->second.is_ambiguous;
+ return true;
+ }
+
+ // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is
+ // an H.264 codec ID because currently those are the only ones that can't be
+ // stored in the |string_to_codec_map_| and require parsing.
+ return ParseH264CodecID(codec_id, codec, is_ambiguous);
+}
+
+bool MimeUtil::IsCodecSupported(Codec codec) const {
+ DCHECK_NE(codec, INVALID_CODEC);
+
+#if defined(OS_ANDROID)
+ if (!IsCodecSupportedOnAndroid(codec))
+ return false;
+#endif
+
+ return allow_proprietary_codecs_ || !IsCodecProprietary(codec);
+}
+
+bool MimeUtil::IsCodecProprietary(Codec codec) const {
+ switch (codec) {
+ case INVALID_CODEC:
+ case MP3:
+ case MPEG2_AAC_LC:
+ case MPEG2_AAC_MAIN:
+ case MPEG2_AAC_SSR:
+ case MPEG4_AAC_LC:
+ case MPEG4_AAC_SBRv1:
+ case H264_BASELINE:
+ case H264_MAIN:
+ case H264_HIGH:
+ return true;
+
+ case PCM:
+ case VORBIS:
+ case OPUS:
+ case VP8:
+ case VP9:
+ case THEORA:
+ return false;
+ }
+
+ return true;
+}
+
+bool MimeUtil::GetDefaultCodec(const std::string& mime_type,
+ Codec* default_codec) const {
+ if (mime_type == "audio/mpeg" ||
+ mime_type == "audio/mp3" ||
+ mime_type == "audio/x-mp3") {
+ *default_codec = MimeUtil::MP3;
+ return true;
+ }
+
+ return false;
+}
+
+
+bool MimeUtil::IsDefaultCodecSupported(const std::string& mime_type) const {
+ Codec default_codec = Codec::INVALID_CODEC;
+ if (!GetDefaultCodec(mime_type, &default_codec))
+ return false;
+ return IsCodecSupported(default_codec);
}
//----------------------------------------------------------------------------
@@ -840,8 +1155,9 @@ bool IsStrictMediaMimeType(const std::string& mime_type) {
return g_mime_util.Get().IsStrictMediaMimeType(mime_type);
}
-bool IsSupportedStrictMediaMimeType(const std::string& mime_type,
- const std::vector<std::string>& codecs) {
+SupportsType IsSupportedStrictMediaMimeType(
+ const std::string& mime_type,
+ const std::vector<std::string>& codecs) {
return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs);
}
@@ -993,7 +1309,7 @@ void GetExtensionsForMimeType(
if (unsafe_mime_type == "*/*" || unsafe_mime_type == "*")
return;
- const std::string mime_type = StringToLowerASCII(unsafe_mime_type);
+ const std::string mime_type = base::StringToLowerASCII(unsafe_mime_type);
base::hash_set<base::FilePath::StringType> unique_extensions;
if (EndsWith(mime_type, "/*", true)) {
diff --git a/chromium/net/base/mime_util.h b/chromium/net/base/mime_util.h
index 6c943a7f7da..24dca3def6e 100644
--- a/chromium/net/base/mime_util.h
+++ b/chromium/net/base/mime_util.h
@@ -94,12 +94,34 @@ NET_EXPORT void ParseCodecString(const std::string& codecs,
// certain subset of codecs.
NET_EXPORT bool IsStrictMediaMimeType(const std::string& mime_type);
-// Check to see if a particular MIME type is in our list which only supports a
-// certain subset of codecs. Returns true if and only if all codecs are
-// supported for that specific MIME type, false otherwise. If this returns
-// false you will still need to check if the media MIME tpyes and codecs are
-// supported.
-NET_EXPORT bool IsSupportedStrictMediaMimeType(
+// Indicates that the MIME type and (possible codec string) are supported by the
+// underlying platform.
+enum SupportsType {
+ // The underlying platform is known not to support the given MIME type and
+ // codec combination.
+ IsNotSupported,
+
+ // The underlying platform is known to support the given MIME type and codec
+ // combination.
+ IsSupported,
+
+ // The underlying platform is unsure whether the given MIME type and codec
+ // combination can be rendered or not before actually trying to play it.
+ MayBeSupported
+};
+
+// Checks the |mime_type| and |codecs| against the MIME types known to support
+// only a particular subset of codecs.
+// * Returns IsSupported if the |mime_type| is supported and all the codecs
+// within the |codecs| are supported for the |mime_type|.
+// * Returns MayBeSupported if the |mime_type| is supported and is known to
+// support only a subset of codecs, but |codecs| was empty. Also returned if
+// all the codecs in |codecs| are supported, but additional codec parameters
+// were supplied (such as profile) for which the support cannot be decided.
+// * Returns IsNotSupported if either the |mime_type| is not supported or the
+// |mime_type| is supported but at least one of the codecs within |codecs| is
+// not supported for the |mime_type|.
+NET_EXPORT SupportsType IsSupportedStrictMediaMimeType(
const std::string& mime_type,
const std::vector<std::string>& codecs);
@@ -125,10 +147,14 @@ NET_EXPORT void RemoveProprietaryMediaTypesAndCodecsForTests();
NET_EXPORT const std::string GetIANAMediaType(const std::string& mime_type);
// A list of supported certificate-related mime types.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
enum CertificateMimeType {
-#define CERTIFICATE_MIME_TYPE(name, value) CERTIFICATE_MIME_TYPE_ ## name = value,
-#include "net/base/mime_util_certificate_type_list.h"
-#undef CERTIFICATE_MIME_TYPE
+ CERTIFICATE_MIME_TYPE_UNKNOWN,
+ CERTIFICATE_MIME_TYPE_X509_USER_CERT,
+ CERTIFICATE_MIME_TYPE_X509_CA_CERT,
+ CERTIFICATE_MIME_TYPE_PKCS12_ARCHIVE,
};
NET_EXPORT CertificateMimeType GetCertificateMimeTypeForMimeType(
diff --git a/chromium/net/base/mime_util_certificate_type_list.h b/chromium/net/base/mime_util_certificate_type_list.h
deleted file mode 100644
index b7e1be0096c..00000000000
--- a/chromium/net/base/mime_util_certificate_type_list.h
+++ /dev/null
@@ -1,13 +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.
-
-// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
-
-// This file contains the list of certificate MIME types.
-
-CERTIFICATE_MIME_TYPE(UNKNOWN, 0)
-CERTIFICATE_MIME_TYPE(X509_USER_CERT, 1)
-CERTIFICATE_MIME_TYPE(X509_CA_CERT, 2)
-CERTIFICATE_MIME_TYPE(PKCS12_ARCHIVE, 3)
diff --git a/chromium/net/base/mime_util_unittest.cc b/chromium/net/base/mime_util_unittest.cc
index bb783af90f3..49c46614908 100644
--- a/chromium/net/base/mime_util_unittest.cc
+++ b/chromium/net/base/mime_util_unittest.cc
@@ -24,13 +24,16 @@ TEST(MimeUtilTest, ExtensionTest) {
{ FILE_PATH_LITERAL("css"), "text/css", true },
{ FILE_PATH_LITERAL("pjp"), "image/jpeg", true },
{ FILE_PATH_LITERAL("pjpeg"), "image/jpeg", true },
+#if defined(OS_ANDROID)
+ { FILE_PATH_LITERAL("m3u8"), "application/x-mpegurl", true },
+#endif
{ FILE_PATH_LITERAL("not an extension / for sure"), "", false },
};
std::string mime_type;
bool rv;
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
rv = GetMimeTypeFromExtension(tests[i].extension, &mime_type);
EXPECT_EQ(tests[i].valid, rv);
if (rv)
@@ -55,7 +58,7 @@ TEST(MimeUtilTest, FileTest) {
std::string mime_type;
bool rv;
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
rv = GetMimeTypeFromFile(base::FilePath(tests[i].file_path),
&mime_type);
EXPECT_EQ(tests[i].valid, rv);
@@ -113,15 +116,13 @@ TEST(MimeUtilTest, StrictMediaMimeType) {
EXPECT_TRUE(IsStrictMediaMimeType("audio/mp3"));
EXPECT_TRUE(IsStrictMediaMimeType("audio/x-mp3"));
- // TODO(amogh.bihani): These will be fixed http://crbug.com/53193
- EXPECT_FALSE(IsStrictMediaMimeType("video/mp4"));
- EXPECT_FALSE(IsStrictMediaMimeType("video/x-m4v"));
- EXPECT_FALSE(IsStrictMediaMimeType("audio/mp4"));
- EXPECT_FALSE(IsStrictMediaMimeType("audio/x-m4a"));
+ EXPECT_TRUE(IsStrictMediaMimeType("video/mp4"));
+ EXPECT_TRUE(IsStrictMediaMimeType("video/x-m4v"));
+ EXPECT_TRUE(IsStrictMediaMimeType("audio/mp4"));
+ EXPECT_TRUE(IsStrictMediaMimeType("audio/x-m4a"));
- EXPECT_FALSE(IsStrictMediaMimeType("application/x-mpegurl"));
- EXPECT_FALSE(IsStrictMediaMimeType("application/vnd.apple.mpegurl"));
- // ---------------------------------------------------------------------------
+ EXPECT_TRUE(IsStrictMediaMimeType("application/x-mpegurl"));
+ EXPECT_TRUE(IsStrictMediaMimeType("application/vnd.apple.mpegurl"));
EXPECT_FALSE(IsStrictMediaMimeType("video/unknown"));
EXPECT_FALSE(IsStrictMediaMimeType("audio/unknown"));
@@ -230,6 +231,12 @@ TEST(MimeUtilTest, CommonMediaMimeType) {
EXPECT_TRUE(IsSupportedMediaMimeType("audio/mp3"));
EXPECT_TRUE(IsSupportedMediaMimeType("audio/x-mp3"));
EXPECT_TRUE(IsSupportedMediaMimeType("audio/mpeg"));
+
+#if defined(ENABLE_MPEG2TS_STREAM_PARSER)
+ EXPECT_TRUE(IsSupportedMediaMimeType("video/mp2t"));
+#else
+ EXPECT_FALSE(IsSupportedMediaMimeType("video/mp2t"));
+#endif
#else
EXPECT_FALSE(IsSupportedMediaMimeType("audio/mp4"));
EXPECT_FALSE(IsSupportedMediaMimeType("audio/x-m4a"));
@@ -267,7 +274,7 @@ TEST(MimeUtilTest, ParseCodecString) {
{ ",", 2, { "", "" } },
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
std::vector<std::string> codecs_out;
ParseCodecString(tests[i].original, &codecs_out, true);
ASSERT_EQ(tests[i].expected_size, codecs_out.size());
@@ -394,7 +401,7 @@ TEST(MimeUtilTest, TestGetExtensionsForMimeType) {
{ "aUDIo/*", 6, "wav" },
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
std::vector<base::FilePath::StringType> extensions;
GetExtensionsForMimeType(tests[i].mime_type, &extensions);
ASSERT_TRUE(tests[i].min_expected_size <= extensions.size());
diff --git a/chromium/net/base/mock_file_stream.cc b/chromium/net/base/mock_file_stream.cc
index be2dc821527..a34edb218be 100644
--- a/chromium/net/base/mock_file_stream.cc
+++ b/chromium/net/base/mock_file_stream.cc
@@ -33,7 +33,7 @@ MockFileStream::MockFileStream(
MockFileStream::~MockFileStream() {
}
-int MockFileStream::Seek(Whence whence, int64 offset,
+int MockFileStream::Seek(base::File::Whence whence, int64 offset,
const Int64CompletionCallback& callback) {
Int64CompletionCallback wrapped_callback =
base::Bind(&MockFileStream::DoCallback64,
diff --git a/chromium/net/base/mock_file_stream.h b/chromium/net/base/mock_file_stream.h
index c9f07f02487..7b7dea83170 100644
--- a/chromium/net/base/mock_file_stream.h
+++ b/chromium/net/base/mock_file_stream.h
@@ -25,18 +25,19 @@ class MockFileStream : public net::FileStream {
explicit MockFileStream(const scoped_refptr<base::TaskRunner>& task_runner);
MockFileStream(base::File file,
const scoped_refptr<base::TaskRunner>& task_runner);
- virtual ~MockFileStream();
+ ~MockFileStream() override;
// FileStream methods.
- virtual int Seek(net::Whence whence, int64 offset,
- const Int64CompletionCallback& callback) OVERRIDE;
- virtual int Read(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) OVERRIDE;
- virtual int Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) OVERRIDE;
- virtual int Flush(const CompletionCallback& callback) OVERRIDE;
+ int Seek(base::File::Whence whence,
+ int64 offset,
+ const Int64CompletionCallback& callback) override;
+ int Read(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) override;
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) override;
+ int Flush(const CompletionCallback& callback) override;
void set_forced_error_async(int error) {
forced_error_ = error;
diff --git a/chromium/net/base/net_error_list.h b/chromium/net/base/net_error_list.h
index 65d3a45d198..89fbfff08c1 100644
--- a/chromium/net/base/net_error_list.h
+++ b/chromium/net/base/net_error_list.h
@@ -96,9 +96,13 @@ NET_ERROR(SOCKET_IS_CONNECTED, -23)
// The request was blocked because the forced reenrollment check is still
// pending. This error can only occur on ChromeOS.
-// The error can be emitted by code in c/b/policy/policy_helpers.cc.
+// The error can be emitted by code in chrome/browser/policy/policy_helpers.cc.
NET_ERROR(BLOCKED_ENROLLMENT_CHECK_PENDING, -24)
+// The upload failed because the upload stream needed to be re-read, due to a
+// retry or a redirect, but the upload stream doesn't support that operation.
+NET_ERROR(UPLOAD_STREAM_REWIND_NOT_SUPPORTED, -25)
+
// A connection was closed (corresponding to a TCP FIN).
NET_ERROR(CONNECTION_CLOSED, -100)
@@ -332,6 +336,14 @@ NET_ERROR(SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE, -162)
// return code from setsockopt.
NET_ERROR(SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE, -163)
+// Failed to import a client certificate from the platform store into the SSL
+// library.
+NET_ERROR(SSL_CLIENT_AUTH_CERT_BAD_FORMAT, -164)
+
+// The SSL server requires falling back to a version older than the configured
+// minimum fallback version, and thus fallback failed.
+NET_ERROR(SSL_FALLBACK_BEYOND_MINIMUM_VERSION, -165)
+
// Certificate error codes
//
// The values of certificate error codes must be consecutive.
@@ -645,6 +657,9 @@ NET_ERROR(CACHE_CHECKSUM_READ_FAILURE, -407)
// SimpleCache backend, but not by any URLRequest methods or members.
NET_ERROR(CACHE_CHECKSUM_MISMATCH, -408)
+// Internal error code for the HTTP cache. The cache lock timeout has fired.
+NET_ERROR(CACHE_LOCK_TIMEOUT, -409)
+
// The server's response was insecure (e.g. there was a cert error).
NET_ERROR(INSECURE_RESPONSE, -501)
@@ -732,6 +747,9 @@ NET_ERROR(SELF_SIGNED_CERT_GENERATION_FAILED, -713)
// The certificate database changed in some way.
NET_ERROR(CERT_DATABASE_CHANGED, -714)
+// Failure to import Channel ID.
+NET_ERROR(CHANNEL_ID_IMPORT_FAILED, -715)
+
// DNS error codes.
// DNS resolver received a malformed response.
diff --git a/chromium/net/base/net_errors.cc b/chromium/net/base/net_errors.cc
index a9d1443c913..55cdebb1ac5 100644
--- a/chromium/net/base/net_errors.cc
+++ b/chromium/net/base/net_errors.cc
@@ -24,18 +24,47 @@ namespace net {
const char kErrorDomain[] = "net";
-const char* ErrorToString(int error) {
+std::string ErrorToString(int error) {
+ return "net::" + ErrorToShortString(error);
+}
+
+std::string ErrorToShortString(int error) {
if (error == 0)
- return "net::OK";
+ return "OK";
+ const char* error_string;
switch (error) {
#define NET_ERROR(label, value) \
case ERR_ ## label: \
- return "net::" STRINGIZE_NO_EXPANSION(ERR_ ## label);
+ error_string = # label; \
+ break;
#include "net/base/net_error_list.h"
#undef NET_ERROR
default:
- return "net::<unknown>";
+ NOTREACHED();
+ error_string = "<unknown>";
+ }
+ return std::string("ERR_") + error_string;
+}
+
+bool IsCertificateError(int error) {
+ // Certificate errors are negative integers from net::ERR_CERT_BEGIN
+ // (inclusive) to net::ERR_CERT_END (exclusive) in *decreasing* order.
+ // ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN is currently an exception to this
+ // rule.
+ return (error <= ERR_CERT_BEGIN && error > ERR_CERT_END) ||
+ (error == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN);
+}
+
+bool IsClientCertificateError(int error) {
+ switch (error) {
+ case ERR_BAD_SSL_CLIENT_AUTH_CERT:
+ case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED:
+ case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY:
+ case ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED:
+ return true;
+ default:
+ return false;
}
}
diff --git a/chromium/net/base/net_errors.h b/chromium/net/base/net_errors.h
index 2c513612209..29b7742f721 100644
--- a/chromium/net/base/net_errors.h
+++ b/chromium/net/base/net_errors.h
@@ -5,6 +5,7 @@
#ifndef NET_BASE_NET_ERRORS_H__
#define NET_BASE_NET_ERRORS_H__
+#include <string>
#include <vector>
#include "base/basictypes.h"
@@ -30,17 +31,18 @@ enum Error {
};
// Returns a textual representation of the error code for logging purposes.
-NET_EXPORT const char* ErrorToString(int error);
+NET_EXPORT std::string ErrorToString(int error);
+
+// Same as above, but leaves off the leading "net::".
+NET_EXPORT std::string ErrorToShortString(int error);
// Returns true if |error| is a certificate error code.
-inline bool IsCertificateError(int error) {
- // Certificate errors are negative integers from net::ERR_CERT_BEGIN
- // (inclusive) to net::ERR_CERT_END (exclusive) in *decreasing* order.
- // ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN is currently an exception to this
- // rule.
- return (error <= ERR_CERT_BEGIN && error > ERR_CERT_END) ||
- (error == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN);
-}
+NET_EXPORT bool IsCertificateError(int error);
+
+// Returns true if |error| is a client certificate authentication error. This
+// does not include ERR_SSL_PROTOCOL_ERROR which may also signal a bad client
+// certificate.
+NET_EXPORT bool IsClientCertificateError(int error);
// Map system error code to Error.
NET_EXPORT Error MapSystemError(int os_error);
diff --git a/chromium/net/base/net_info_source_list.h b/chromium/net/base/net_info_source_list.h
new file mode 100644
index 00000000000..be3019e9183
--- /dev/null
+++ b/chromium/net/base/net_info_source_list.h
@@ -0,0 +1,22 @@
+// Copyright 2014 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.
+
+// This file intentionally does not have header guards, it's included
+// inside a macro to generate enum values.
+
+// Flags used to request different types of information about the current state
+// of a URLRequestContext.
+//
+// The strings don't match the enums for historical reasons.
+
+NET_INFO_SOURCE(PROXY_SETTINGS, "proxySettings", 1 << 0)
+NET_INFO_SOURCE(BAD_PROXIES, "badProxies", 1 << 1)
+NET_INFO_SOURCE(HOST_RESOLVER, "hostResolverInfo", 1 << 2)
+NET_INFO_SOURCE(SOCKET_POOL, "socketPoolInfo", 1 << 3)
+NET_INFO_SOURCE(QUIC, "quicInfo", 1 << 4)
+NET_INFO_SOURCE(SPDY_SESSIONS, "spdySessionInfo", 1 << 5)
+NET_INFO_SOURCE(SPDY_STATUS, "spdyStatus", 1 << 6)
+NET_INFO_SOURCE(SPDY_ALT_PROTO_MAPPINGS, "spdyAlternateProtocolMappings",
+ 1 << 7)
+NET_INFO_SOURCE(HTTP_CACHE, "httpCacheInfo", 1 << 8)
diff --git a/chromium/net/base/net_log.cc b/chromium/net/base/net_log.cc
index 6016d0de026..4f460356399 100644
--- a/chromium/net/base/net_log.cc
+++ b/chromium/net/base/net_log.cc
@@ -101,10 +101,10 @@ NetLog::ParametersCallback NetLog::Source::ToEventParametersCallback() const {
// static
bool NetLog::Source::FromEventParameters(base::Value* event_params,
Source* source) {
- base::DictionaryValue* dict;
- base::DictionaryValue* source_dict;
- int source_id;
- int source_type;
+ base::DictionaryValue* dict = NULL;
+ base::DictionaryValue* source_dict = NULL;
+ int source_id = -1;
+ int source_type = NetLog::SOURCE_COUNT;
if (!event_params ||
!event_params->GetAsDictionary(&dict) ||
!dict->GetDictionary("source_dependency", &source_dict) ||
@@ -114,7 +114,7 @@ bool NetLog::Source::FromEventParameters(base::Value* event_params,
return false;
}
- DCHECK_LE(0, source_id);
+ DCHECK_GE(source_id, 0);
DCHECK_LT(source_type, NetLog::SOURCE_COUNT);
*source = Source(static_cast<SourceType>(source_type), source_id);
return true;
@@ -198,10 +198,7 @@ void NetLog::ThreadSafeObserver::OnAddEntryData(const EntryData& entry_data) {
OnAddEntry(Entry(&entry_data, log_level()));
}
-NetLog::NetLog()
- : last_id_(0),
- base_log_level_(LOG_NONE),
- effective_log_level_(LOG_NONE) {
+NetLog::NetLog() : last_id_(0), effective_log_level_(LOG_NONE) {
}
NetLog::~NetLog() {
@@ -227,13 +224,6 @@ uint32 NetLog::NextID() {
return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
}
-void NetLog::SetBaseLogLevel(LogLevel log_level) {
- base::AutoLock lock(lock_);
- base_log_level_ = log_level;
-
- UpdateLogLevel();
-}
-
NetLog::LogLevel NetLog::GetLogLevel() const {
base::subtle::Atomic32 log_level =
base::subtle::NoBarrier_Load(&effective_log_level_);
@@ -285,7 +275,7 @@ void NetLog::UpdateLogLevel() {
// Look through all the observers and find the finest granularity
// log level (higher values of the enum imply *lower* log levels).
- LogLevel new_effective_log_level = base_log_level_;
+ LogLevel new_effective_log_level = LOG_NONE;
ObserverListBase<ThreadSafeObserver>::Iterator it(observers_);
ThreadSafeObserver* observer;
while ((observer = it.GetNext()) != NULL) {
diff --git a/chromium/net/base/net_log.h b/chromium/net/base/net_log.h
index b037a336bc5..1b598ed84b7 100644
--- a/chromium/net/base/net_log.h
+++ b/chromium/net/base/net_log.h
@@ -300,10 +300,6 @@ class NET_EXPORT NetLog {
static ParametersCallback StringCallback(const char* name,
const base::string16* value);
- protected:
- // Set the lowest allowed log level, regardless of any Observers.
- void SetBaseLogLevel(LogLevel log_level);
-
private:
friend class BoundNetLog;
@@ -322,10 +318,6 @@ class NET_EXPORT NetLog {
// Last assigned source ID. Incremented to get the next one.
base::subtle::Atomic32 last_id_;
- // The lowest allowed log level, regardless of any Observers.
- // Normally defaults to LOG_NONE, but can be changed with SetBaseLogLevel
- LogLevel base_log_level_;
-
// The current log level.
base::subtle::Atomic32 effective_log_level_;
diff --git a/chromium/net/base/net_log_event_type_list.h b/chromium/net/base/net_log_event_type_list.h
index c6ed7c5d937..823cde18bd3 100644
--- a/chromium/net/base/net_log_event_type_list.h
+++ b/chromium/net/base/net_log_event_type_list.h
@@ -798,6 +798,14 @@ EVENT_TYPE(URL_REQUEST_REDIRECT_JOB)
// "reason": <Reason for the redirect, as a string>,
// }
+EVENT_TYPE(URL_REQUEST_FAKE_RESPONSE_HEADERS_CREATED)
+// This event is logged when a URLRequestRedirectJob creates the fake response
+// headers for a request, prior to returning them.
+// The following parameters are attached:
+// {
+// "headers": <The list of header:value pairs>,
+// }
+
// ------------------------------------------------------------------------
// HttpCache
// ------------------------------------------------------------------------
@@ -827,6 +835,29 @@ EVENT_TYPE(HTTP_CACHE_WRITE_INFO)
EVENT_TYPE(HTTP_CACHE_READ_DATA)
EVENT_TYPE(HTTP_CACHE_WRITE_DATA)
+// Identifies the NetLog::Source() for the asynchronous HttpCache::Transaction
+// that will revalidate this entry.
+// The event parameters are:
+// {
+// "source_dependency": <Source identifier for the async Transaction>
+// }
+EVENT_TYPE(HTTP_CACHE_VALIDATE_RESOURCE_ASYNC)
+
+// The start/end of performing an async revalidation.
+// For the BEGIN phase, the event parameters are:
+// {
+// "source_dependency": <Source identifier for the Request>
+// "url": <String of URL being loaded>,
+// "method": <Method of request>
+// }
+//
+// For the END phase, if there was an error, the following parameters are
+// attached:
+// {
+// "net_error": <Net error code of the failure>,
+// }
+EVENT_TYPE(ASYNC_REVALIDATION)
+
// ------------------------------------------------------------------------
// Disk Cache / Memory Cache
// ------------------------------------------------------------------------
@@ -1351,6 +1382,12 @@ EVENT_TYPE(QUIC_SESSION)
// }
EVENT_TYPE(QUIC_SESSION_CLOSE_ON_ERROR)
+// Session verified a certificate from the server.
+// {
+// "subjects": <list of DNS names that the certificate is valid for>,
+// }
+EVENT_TYPE(QUIC_SESSION_CERTIFICATE_VERIFIED)
+
// Session received a QUIC packet.
// {
// "peer_address": <The ip:port of the peer>,
diff --git a/chromium/net/base/net_log_logger.cc b/chromium/net/base/net_log_logger.cc
index aa5ec4021f8..bb0331badef 100644
--- a/chromium/net/base/net_log_logger.cc
+++ b/chromium/net/base/net_log_logger.cc
@@ -9,21 +9,15 @@
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_number_conversions.h"
#include "base/values.h"
-#include "net/base/address_family.h"
-#include "net/base/load_states.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_utils.h"
+#include "net/base/net_log_util.h"
namespace net {
-// This should be incremented when significant changes are made that will
-// invalidate the old loading code.
-static const int kLogFormatVersion = 1;
-
NetLogLogger::NetLogLogger(FILE* file, const base::Value& constants)
- : file_(file), log_level_(NetLog::LOG_ALL_BUT_BYTES), added_events_(false) {
+ : file_(file),
+ log_level_(NetLog::LOG_STRIP_PRIVATE_DATA),
+ added_events_(false) {
DCHECK(file);
// Write constants to the output file. This allows loading files that have
@@ -66,170 +60,9 @@ void NetLogLogger::OnAddEntry(const net::NetLog::Entry& entry) {
added_events_ = true;
}
+// static
base::DictionaryValue* NetLogLogger::GetConstants() {
- base::DictionaryValue* constants_dict = new base::DictionaryValue();
-
- // Version of the file format.
- constants_dict->SetInteger("logFormatVersion", kLogFormatVersion);
-
- // Add a dictionary with information on the relationship between event type
- // enums and their symbolic names.
- constants_dict->Set("logEventTypes", net::NetLog::GetEventTypesAsValue());
-
- // Add a dictionary with information about the relationship between CertStatus
- // flags and their symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
-#define CERT_STATUS_FLAG(label, value) dict->SetInteger(#label, value);
-#include "net/cert/cert_status_flags_list.h"
-#undef CERT_STATUS_FLAG
-
- constants_dict->Set("certStatusFlag", dict);
- }
-
- // Add a dictionary with information about the relationship between load flag
- // enums and their symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
-#define LOAD_FLAG(label, value) \
- dict->SetInteger(# label, static_cast<int>(value));
-#include "net/base/load_flags_list.h"
-#undef LOAD_FLAG
-
- constants_dict->Set("loadFlag", dict);
- }
-
- // Add a dictionary with information about the relationship between load state
- // enums and their symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
-#define LOAD_STATE(label) \
- dict->SetInteger(# label, net::LOAD_STATE_ ## label);
-#include "net/base/load_states_list.h"
-#undef LOAD_STATE
-
- constants_dict->Set("loadState", dict);
- }
-
- // Add information on the relationship between net error codes and their
- // symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
-#define NET_ERROR(label, value) \
- dict->SetInteger(# label, static_cast<int>(value));
-#include "net/base/net_error_list.h"
-#undef NET_ERROR
-
- constants_dict->Set("netError", dict);
- }
-
- // Add information on the relationship between QUIC error codes and their
- // symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
- for (net::QuicErrorCode error = net::QUIC_NO_ERROR;
- error < net::QUIC_LAST_ERROR;
- error = static_cast<net::QuicErrorCode>(error + 1)) {
- dict->SetInteger(net::QuicUtils::ErrorToString(error),
- static_cast<int>(error));
- }
-
- constants_dict->Set("quicError", dict);
- }
-
- // Add information on the relationship between QUIC RST_STREAM error codes
- // and their symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
- for (net::QuicRstStreamErrorCode error = net::QUIC_STREAM_NO_ERROR;
- error < net::QUIC_STREAM_LAST_ERROR;
- error = static_cast<net::QuicRstStreamErrorCode>(error + 1)) {
- dict->SetInteger(net::QuicUtils::StreamErrorToString(error),
- static_cast<int>(error));
- }
-
- constants_dict->Set("quicRstStreamError", dict);
- }
-
- // Information about the relationship between event phase enums and their
- // symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
- dict->SetInteger("PHASE_BEGIN", net::NetLog::PHASE_BEGIN);
- dict->SetInteger("PHASE_END", net::NetLog::PHASE_END);
- dict->SetInteger("PHASE_NONE", net::NetLog::PHASE_NONE);
-
- constants_dict->Set("logEventPhase", dict);
- }
-
- // Information about the relationship between source type enums and
- // their symbolic names.
- constants_dict->Set("logSourceType", net::NetLog::GetSourceTypesAsValue());
-
- // Information about the relationship between LogLevel enums and their
- // symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
- dict->SetInteger("LOG_ALL", net::NetLog::LOG_ALL);
- dict->SetInteger("LOG_ALL_BUT_BYTES", net::NetLog::LOG_ALL_BUT_BYTES);
- dict->SetInteger("LOG_STRIP_PRIVATE_DATA",
- net::NetLog::LOG_STRIP_PRIVATE_DATA);
-
- constants_dict->Set("logLevelType", dict);
- }
-
- // Information about the relationship between address family enums and
- // their symbolic names.
- {
- base::DictionaryValue* dict = new base::DictionaryValue();
-
- dict->SetInteger("ADDRESS_FAMILY_UNSPECIFIED",
- net::ADDRESS_FAMILY_UNSPECIFIED);
- dict->SetInteger("ADDRESS_FAMILY_IPV4",
- net::ADDRESS_FAMILY_IPV4);
- dict->SetInteger("ADDRESS_FAMILY_IPV6",
- net::ADDRESS_FAMILY_IPV6);
-
- constants_dict->Set("addressFamily", dict);
- }
-
- // Information about how the "time ticks" values we have given it relate to
- // actual system times. (We used time ticks throughout since they are stable
- // across system clock changes).
- {
- int64 cur_time_ms = (base::Time::Now() - base::Time()).InMilliseconds();
-
- int64 cur_time_ticks_ms =
- (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds();
-
- // If we add this number to a time tick value, it gives the timestamp.
- int64 tick_to_time_ms = cur_time_ms - cur_time_ticks_ms;
-
- // Chrome on all platforms stores times using the Windows epoch
- // (Jan 1 1601), but the javascript wants a unix epoch.
- // TODO(eroman): Getting the timestamp relative to the unix epoch should
- // be part of the time library.
- const int64 kUnixEpochMs = 11644473600000LL;
- int64 tick_to_unix_time_ms = tick_to_time_ms - kUnixEpochMs;
-
- // Pass it as a string, since it may be too large to fit in an integer.
- constants_dict->SetString("timeTickOffset",
- base::Int64ToString(tick_to_unix_time_ms));
- }
-
- // "clientInfo" key is required for some NetLogLogger log readers.
- // Provide a default empty value for compatibility.
- constants_dict->Set("clientInfo", new base::DictionaryValue());
-
- return constants_dict;
+ return GetNetConstants().release();
}
} // namespace net
diff --git a/chromium/net/base/net_log_logger.h b/chromium/net/base/net_log_logger.h
index 3d53f3910d9..ede3ca443db 100644
--- a/chromium/net/base/net_log_logger.h
+++ b/chromium/net/base/net_log_logger.h
@@ -8,9 +8,11 @@
#include <stdio.h>
#include "base/files/scoped_file.h"
+#include "base/macros.h"
#include "net/base/net_log.h"
namespace base {
+class DictionaryValue;
class FilePath;
class Value;
}
@@ -27,7 +29,7 @@ class NET_EXPORT NetLogLogger : public NetLog::ThreadSafeObserver {
// starts. |file| must be non-NULL handle and be open for writing.
// |constants| is a legend for decoding constant values used in the log.
NetLogLogger(FILE* file, const base::Value& constants);
- virtual ~NetLogLogger();
+ ~NetLogLogger() override;
// Sets the log level to log at. Must be called before StartObserving.
void set_log_level(NetLog::LogLevel log_level);
@@ -40,10 +42,13 @@ class NET_EXPORT NetLogLogger : public NetLog::ThreadSafeObserver {
void StopObserving();
// net::NetLog::ThreadSafeObserver implementation:
- virtual void OnAddEntry(const NetLog::Entry& entry) OVERRIDE;
+ void OnAddEntry(const NetLog::Entry& entry) override;
// Create a dictionary containing legend for net/ constants. Caller takes
// ownership of returned value.
+ // TODO(mmenke): Get rid of this, and have embedders use GetNetConstants
+ // directly. Also maybe call that function by default, so only embedders
+ // that need more constants need to worry about it.
static base::DictionaryValue* GetConstants();
private:
diff --git a/chromium/net/base/net_log_logger_unittest.cc b/chromium/net/base/net_log_logger_unittest.cc
index 5d587dabd5f..256ae591740 100644
--- a/chromium/net/base/net_log_logger_unittest.cc
+++ b/chromium/net/base/net_log_logger_unittest.cc
@@ -4,18 +4,22 @@
#include "net/base/net_log_logger.h"
-#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/values.h"
+#include "net/base/net_log.h"
+#include "net/base/net_log_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
+namespace {
+
class NetLogLoggerTest : public testing::Test {
public:
- virtual void SetUp() {
+ void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
log_path_ = temp_dir_.path().AppendASCII("NetLogFile");
}
@@ -26,13 +30,12 @@ class NetLogLoggerTest : public testing::Test {
};
TEST_F(NetLogLoggerTest, GeneratesValidJSONForNoEvents) {
- {
- // Create and destroy a logger.
- FILE* file = base::OpenFile(log_path_, "w");
- ASSERT_TRUE(file);
- scoped_ptr<base::Value> constants(NetLogLogger::GetConstants());
- NetLogLogger logger(file, *constants);
- }
+ // Create and destroy a logger.
+ FILE* file = base::OpenFile(log_path_, "w");
+ ASSERT_TRUE(file);
+ scoped_ptr<base::Value> constants(GetNetConstants());
+ scoped_ptr<NetLogLogger> logger(new NetLogLogger(file, *constants));
+ logger.reset();
std::string input;
ASSERT_TRUE(base::ReadFileToString(log_path_, &input));
@@ -48,23 +51,42 @@ TEST_F(NetLogLoggerTest, GeneratesValidJSONForNoEvents) {
ASSERT_EQ(0u, events->GetSize());
}
+// Make sure the log level is LOG_STRIP_PRIVATE_DATA by default.
+TEST_F(NetLogLoggerTest, LogLevel) {
+ FILE* file = base::OpenFile(log_path_, "w");
+ ASSERT_TRUE(file);
+ scoped_ptr<base::Value> constants(GetNetConstants());
+ NetLogLogger logger(file, *constants);
+
+ NetLog net_log;
+ logger.StartObserving(&net_log);
+ EXPECT_EQ(NetLog::LOG_STRIP_PRIVATE_DATA, logger.log_level());
+ EXPECT_EQ(NetLog::LOG_STRIP_PRIVATE_DATA, net_log.GetLogLevel());
+ logger.StopObserving();
+
+ logger.set_log_level(NetLog::LOG_ALL_BUT_BYTES);
+ logger.StartObserving(&net_log);
+ EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, logger.log_level());
+ EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
+ logger.StopObserving();
+}
+
TEST_F(NetLogLoggerTest, GeneratesValidJSONWithOneEvent) {
- {
- FILE* file = base::OpenFile(log_path_, "w");
- ASSERT_TRUE(file);
- scoped_ptr<base::Value> constants(NetLogLogger::GetConstants());
- NetLogLogger logger(file, *constants);
-
- const int kDummyId = 1;
- NetLog::Source source(NetLog::SOURCE_SPDY_SESSION, kDummyId);
- NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE,
- source,
- NetLog::PHASE_BEGIN,
- base::TimeTicks::Now(),
- NULL);
- NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);
- logger.OnAddEntry(entry);
- }
+ FILE* file = base::OpenFile(log_path_, "w");
+ ASSERT_TRUE(file);
+ scoped_ptr<base::Value> constants(GetNetConstants());
+ scoped_ptr<NetLogLogger> logger(new NetLogLogger(file, *constants));
+
+ const int kDummyId = 1;
+ NetLog::Source source(NetLog::SOURCE_SPDY_SESSION, kDummyId);
+ NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE,
+ source,
+ NetLog::PHASE_BEGIN,
+ base::TimeTicks::Now(),
+ NULL);
+ NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);
+ logger->OnAddEntry(entry);
+ logger.reset();
std::string input;
ASSERT_TRUE(base::ReadFileToString(log_path_, &input));
@@ -81,25 +103,24 @@ TEST_F(NetLogLoggerTest, GeneratesValidJSONWithOneEvent) {
}
TEST_F(NetLogLoggerTest, GeneratesValidJSONWithMultipleEvents) {
- {
- FILE* file = base::OpenFile(log_path_, "w");
- ASSERT_TRUE(file);
- scoped_ptr<base::Value> constants(NetLogLogger::GetConstants());
- NetLogLogger logger(file, *constants);
-
- const int kDummyId = 1;
- NetLog::Source source(NetLog::SOURCE_SPDY_SESSION, kDummyId);
- NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE,
- source,
- NetLog::PHASE_BEGIN,
- base::TimeTicks::Now(),
- NULL);
- NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);
-
- // Add the entry multiple times.
- logger.OnAddEntry(entry);
- logger.OnAddEntry(entry);
- }
+ FILE* file = base::OpenFile(log_path_, "w");
+ ASSERT_TRUE(file);
+ scoped_ptr<base::Value> constants(GetNetConstants());
+ scoped_ptr<NetLogLogger> logger(new NetLogLogger(file, *constants));
+
+ const int kDummyId = 1;
+ NetLog::Source source(NetLog::SOURCE_SPDY_SESSION, kDummyId);
+ NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE,
+ source,
+ NetLog::PHASE_BEGIN,
+ base::TimeTicks::Now(),
+ NULL);
+ NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);
+
+ // Add the entry multiple times.
+ logger->OnAddEntry(entry);
+ logger->OnAddEntry(entry);
+ logger.reset();
std::string input;
ASSERT_TRUE(base::ReadFileToString(log_path_, &input));
@@ -115,4 +136,6 @@ TEST_F(NetLogLoggerTest, GeneratesValidJSONWithMultipleEvents) {
ASSERT_EQ(2u, events->GetSize());
}
+} // namespace
+
} // namespace net
diff --git a/chromium/net/base/net_log_source_type_list.h b/chromium/net/base/net_log_source_type_list.h
index 265ba747459..9d66c175f2d 100644
--- a/chromium/net/base/net_log_source_type_list.h
+++ b/chromium/net/base/net_log_source_type_list.h
@@ -28,3 +28,4 @@ SOURCE_TYPE(FILESTREAM)
SOURCE_TYPE(DNS_PROBER)
SOURCE_TYPE(PROXY_CLIENT_SOCKET)
SOURCE_TYPE(IPV6_REACHABILITY_CHECK)
+SOURCE_TYPE(ASYNC_REVALIDATION)
diff --git a/chromium/net/base/net_log_unittest.cc b/chromium/net/base/net_log_unittest.cc
index 8f15e9cdf7a..0f5b0ebf46c 100644
--- a/chromium/net/base/net_log_unittest.cc
+++ b/chromium/net/base/net_log_unittest.cc
@@ -75,14 +75,12 @@ class CountingObserver : public NetLog::ThreadSafeObserver {
public:
CountingObserver() : count_(0) {}
- virtual ~CountingObserver() {
+ ~CountingObserver() override {
if (net_log())
net_log()->RemoveThreadSafeObserver(this);
}
- virtual void OnAddEntry(const NetLog::Entry& entry) OVERRIDE {
- ++count_;
- }
+ void OnAddEntry(const NetLog::Entry& entry) override { ++count_; }
int count() const { return count_; }
@@ -94,12 +92,12 @@ class LoggingObserver : public NetLog::ThreadSafeObserver {
public:
LoggingObserver() {}
- virtual ~LoggingObserver() {
+ ~LoggingObserver() override {
if (net_log())
net_log()->RemoveThreadSafeObserver(this);
}
- virtual void OnAddEntry(const NetLog::Entry& entry) OVERRIDE {
+ void OnAddEntry(const NetLog::Entry& entry) override {
base::Value* value = entry.ToValue();
base::DictionaryValue* dict = NULL;
ASSERT_TRUE(value->GetAsDictionary(&dict));
@@ -138,7 +136,7 @@ class NetLogTestThread : public base::SimpleThread {
net_log_ = net_log;
}
- virtual void Run() OVERRIDE {
+ void Run() override {
start_event_->Wait();
RunTestThread();
}
@@ -162,10 +160,10 @@ class NetLogTestThread : public base::SimpleThread {
class AddEventsTestThread : public NetLogTestThread {
public:
AddEventsTestThread() {}
- virtual ~AddEventsTestThread() {}
+ ~AddEventsTestThread() override {}
private:
- virtual void RunTestThread() OVERRIDE {
+ void RunTestThread() override {
for (int i = 0; i < kEvents; ++i)
AddEvent(net_log_);
}
@@ -178,12 +176,10 @@ class AddRemoveObserverTestThread : public NetLogTestThread {
public:
AddRemoveObserverTestThread() {}
- virtual ~AddRemoveObserverTestThread() {
- EXPECT_TRUE(!observer_.net_log());
- }
+ ~AddRemoveObserverTestThread() override { EXPECT_TRUE(!observer_.net_log()); }
private:
- virtual void RunTestThread() OVERRIDE {
+ void RunTestThread() override {
for (int i = 0; i < kEvents; ++i) {
ASSERT_FALSE(observer_.net_log());
diff --git a/chromium/net/base/net_log_util.cc b/chromium/net/base/net_log_util.cc
new file mode 100644
index 00000000000..b8816bad919
--- /dev/null
+++ b/chromium/net/base/net_log_util.cc
@@ -0,0 +1,461 @@
+// Copyright 2014 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_log_util.h"
+
+#include <string>
+
+#include "base/metrics/field_trial.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "net/base/address_family.h"
+#include "net/base/load_states.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/dns/host_cache.h"
+#include "net/dns/host_resolver.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_server_properties.h"
+#include "net/http/http_transaction_factory.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_retry_info.h"
+#include "net/proxy/proxy_service.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_utils.h"
+#include "net/url_request/url_request_context.h"
+
+namespace net {
+
+namespace {
+
+// This should be incremented when significant changes are made that will
+// invalidate the old loading code.
+const int kLogFormatVersion = 1;
+
+struct StringToConstant {
+ const char* name;
+ const int constant;
+};
+
+const StringToConstant kCertStatusFlags[] = {
+#define CERT_STATUS_FLAG(label, value) { #label, value },
+#include "net/cert/cert_status_flags_list.h"
+#undef CERT_STATUS_FLAG
+};
+
+const StringToConstant kLoadFlags[] = {
+#define LOAD_FLAG(label, value) { #label, value },
+#include "net/base/load_flags_list.h"
+#undef LOAD_FLAG
+};
+
+const StringToConstant kLoadStateTable[] = {
+#define LOAD_STATE(label) { # label, net::LOAD_STATE_ ## label },
+#include "net/base/load_states_list.h"
+#undef LOAD_STATE
+};
+
+const short kNetErrors[] = {
+#define NET_ERROR(label, value) value,
+#include "net/base/net_error_list.h"
+#undef NET_ERROR
+};
+
+const char* NetInfoSourceToString(NetInfoSource source) {
+ switch (source) {
+ #define NET_INFO_SOURCE(label, string, value) \
+ case NET_INFO_ ## label: \
+ return string;
+#include "net/base/net_info_source_list.h"
+ #undef NET_INFO_SOURCE
+ case NET_INFO_ALL_SOURCES:
+ return "All";
+ }
+ return "?";
+}
+
+// Returns the disk cache backend for |context| if there is one, or NULL.
+// Despite the name, can return an in memory "disk cache".
+disk_cache::Backend* GetDiskCacheBackend(net::URLRequestContext* context) {
+ if (!context->http_transaction_factory())
+ return NULL;
+
+ net::HttpCache* http_cache = context->http_transaction_factory()->GetCache();
+ if (!http_cache)
+ return NULL;
+
+ return http_cache->GetCurrentBackend();
+}
+
+} // namespace
+
+scoped_ptr<base::DictionaryValue> GetNetConstants() {
+ scoped_ptr<base::DictionaryValue> constants_dict(new base::DictionaryValue());
+
+ // Version of the file format.
+ constants_dict->SetInteger("logFormatVersion", kLogFormatVersion);
+
+ // Add a dictionary with information on the relationship between event type
+ // enums and their symbolic names.
+ constants_dict->Set("logEventTypes", net::NetLog::GetEventTypesAsValue());
+
+ // Add a dictionary with information about the relationship between CertStatus
+ // flags and their symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ for (size_t i = 0; i < arraysize(kCertStatusFlags); i++)
+ dict->SetInteger(kCertStatusFlags[i].name, kCertStatusFlags[i].constant);
+
+ constants_dict->Set("certStatusFlag", dict);
+ }
+
+ // Add a dictionary with information about the relationship between load flag
+ // enums and their symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ for (size_t i = 0; i < arraysize(kLoadFlags); i++)
+ dict->SetInteger(kLoadFlags[i].name, kLoadFlags[i].constant);
+
+ constants_dict->Set("loadFlag", dict);
+ }
+
+ // Add a dictionary with information about the relationship between load state
+ // enums and their symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ for (size_t i = 0; i < arraysize(kLoadStateTable); i++)
+ dict->SetInteger(kLoadStateTable[i].name, kLoadStateTable[i].constant);
+
+ constants_dict->Set("loadState", dict);
+ }
+
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ #define NET_INFO_SOURCE(label, string, value) \
+ dict->SetInteger(string, NET_INFO_ ## label);
+#include "net/base/net_info_source_list.h"
+ #undef NET_INFO_SOURCE
+ constants_dict->Set("netInfoSources", dict);
+ }
+
+ // Add information on the relationship between net error codes and their
+ // symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ for (size_t i = 0; i < arraysize(kNetErrors); i++)
+ dict->SetInteger(ErrorToShortString(kNetErrors[i]), kNetErrors[i]);
+
+ constants_dict->Set("netError", dict);
+ }
+
+ // Add information on the relationship between QUIC error codes and their
+ // symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ for (net::QuicErrorCode error = net::QUIC_NO_ERROR;
+ error < net::QUIC_LAST_ERROR;
+ error = static_cast<net::QuicErrorCode>(error + 1)) {
+ dict->SetInteger(net::QuicUtils::ErrorToString(error),
+ static_cast<int>(error));
+ }
+
+ constants_dict->Set("quicError", dict);
+ }
+
+ // Add information on the relationship between QUIC RST_STREAM error codes
+ // and their symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ for (net::QuicRstStreamErrorCode error = net::QUIC_STREAM_NO_ERROR;
+ error < net::QUIC_STREAM_LAST_ERROR;
+ error = static_cast<net::QuicRstStreamErrorCode>(error + 1)) {
+ dict->SetInteger(net::QuicUtils::StreamErrorToString(error),
+ static_cast<int>(error));
+ }
+
+ constants_dict->Set("quicRstStreamError", dict);
+ }
+
+ // Information about the relationship between event phase enums and their
+ // symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ dict->SetInteger("PHASE_BEGIN", net::NetLog::PHASE_BEGIN);
+ dict->SetInteger("PHASE_END", net::NetLog::PHASE_END);
+ dict->SetInteger("PHASE_NONE", net::NetLog::PHASE_NONE);
+
+ constants_dict->Set("logEventPhase", dict);
+ }
+
+ // Information about the relationship between source type enums and
+ // their symbolic names.
+ constants_dict->Set("logSourceType", net::NetLog::GetSourceTypesAsValue());
+
+ // Information about the relationship between LogLevel enums and their
+ // symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ dict->SetInteger("LOG_ALL", net::NetLog::LOG_ALL);
+ dict->SetInteger("LOG_ALL_BUT_BYTES", net::NetLog::LOG_ALL_BUT_BYTES);
+ dict->SetInteger("LOG_STRIP_PRIVATE_DATA",
+ net::NetLog::LOG_STRIP_PRIVATE_DATA);
+
+ constants_dict->Set("logLevelType", dict);
+ }
+
+ // Information about the relationship between address family enums and
+ // their symbolic names.
+ {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+
+ dict->SetInteger("ADDRESS_FAMILY_UNSPECIFIED",
+ net::ADDRESS_FAMILY_UNSPECIFIED);
+ dict->SetInteger("ADDRESS_FAMILY_IPV4",
+ net::ADDRESS_FAMILY_IPV4);
+ dict->SetInteger("ADDRESS_FAMILY_IPV6",
+ net::ADDRESS_FAMILY_IPV6);
+
+ constants_dict->Set("addressFamily", dict);
+ }
+
+ // Information about how the "time ticks" values we have given it relate to
+ // actual system times. (We used time ticks throughout since they are stable
+ // across system clock changes).
+ {
+ int64 cur_time_ms = (base::Time::Now() - base::Time()).InMilliseconds();
+
+ int64 cur_time_ticks_ms =
+ (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds();
+
+ // If we add this number to a time tick value, it gives the timestamp.
+ int64 tick_to_time_ms = cur_time_ms - cur_time_ticks_ms;
+
+ // Chrome on all platforms stores times using the Windows epoch
+ // (Jan 1 1601), but the javascript wants a unix epoch.
+ // TODO(eroman): Getting the timestamp relative to the unix epoch should
+ // be part of the time library.
+ const int64 kUnixEpochMs = 11644473600000LL;
+ int64 tick_to_unix_time_ms = tick_to_time_ms - kUnixEpochMs;
+
+ // Pass it as a string, since it may be too large to fit in an integer.
+ constants_dict->SetString("timeTickOffset",
+ base::Int64ToString(tick_to_unix_time_ms));
+ }
+
+ // "clientInfo" key is required for some NetLogLogger log readers.
+ // Provide a default empty value for compatibility.
+ constants_dict->Set("clientInfo", new base::DictionaryValue());
+
+ // Add a list of active field experiments.
+ {
+ base::FieldTrial::ActiveGroups active_groups;
+ base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
+ base::ListValue* field_trial_groups = new base::ListValue();
+ for (base::FieldTrial::ActiveGroups::const_iterator it =
+ active_groups.begin();
+ it != active_groups.end(); ++it) {
+ field_trial_groups->AppendString(it->trial_name + ":" +
+ it->group_name);
+ }
+ constants_dict->Set("activeFieldTrialGroups", field_trial_groups);
+ }
+
+ return constants_dict.Pass();
+}
+
+NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
+ URLRequestContext* context, int info_sources) {
+ scoped_ptr<base::DictionaryValue> net_info_dict(new base::DictionaryValue());
+
+ // TODO(mmenke): The code for most of these sources should probably be moved
+ // into the sources themselves.
+ if (info_sources & NET_INFO_PROXY_SETTINGS) {
+ net::ProxyService* proxy_service = context->proxy_service();
+
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ if (proxy_service->fetched_config().is_valid())
+ dict->Set("original", proxy_service->fetched_config().ToValue());
+ if (proxy_service->config().is_valid())
+ dict->Set("effective", proxy_service->config().ToValue());
+
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_PROXY_SETTINGS), dict);
+ }
+
+ if (info_sources & NET_INFO_BAD_PROXIES) {
+ const net::ProxyRetryInfoMap& bad_proxies_map =
+ context->proxy_service()->proxy_retry_info();
+
+ base::ListValue* list = new base::ListValue();
+
+ for (net::ProxyRetryInfoMap::const_iterator it = bad_proxies_map.begin();
+ it != bad_proxies_map.end(); ++it) {
+ const std::string& proxy_uri = it->first;
+ const net::ProxyRetryInfo& retry_info = it->second;
+
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ dict->SetString("proxy_uri", proxy_uri);
+ dict->SetString("bad_until",
+ net::NetLog::TickCountToString(retry_info.bad_until));
+
+ list->Append(dict);
+ }
+
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_BAD_PROXIES), list);
+ }
+
+ if (info_sources & NET_INFO_HOST_RESOLVER) {
+ net::HostResolver* host_resolver = context->host_resolver();
+ DCHECK(host_resolver);
+ net::HostCache* cache = host_resolver->GetHostCache();
+ if (cache) {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ base::Value* dns_config = host_resolver->GetDnsConfigAsValue();
+ if (dns_config)
+ dict->Set("dns_config", dns_config);
+
+ dict->SetInteger(
+ "default_address_family",
+ static_cast<int>(host_resolver->GetDefaultAddressFamily()));
+
+ base::DictionaryValue* cache_info_dict = new base::DictionaryValue();
+
+ cache_info_dict->SetInteger(
+ "capacity",
+ static_cast<int>(cache->max_entries()));
+
+ base::ListValue* entry_list = new base::ListValue();
+
+ net::HostCache::EntryMap::Iterator it(cache->entries());
+ for (; it.HasNext(); it.Advance()) {
+ const net::HostCache::Key& key = it.key();
+ const net::HostCache::Entry& entry = it.value();
+
+ base::DictionaryValue* entry_dict = new base::DictionaryValue();
+
+ entry_dict->SetString("hostname", key.hostname);
+ entry_dict->SetInteger("address_family",
+ static_cast<int>(key.address_family));
+ entry_dict->SetString("expiration",
+ net::NetLog::TickCountToString(it.expiration()));
+
+ if (entry.error != net::OK) {
+ entry_dict->SetInteger("error", entry.error);
+ } else {
+ // Append all of the resolved addresses.
+ base::ListValue* address_list = new base::ListValue();
+ for (size_t i = 0; i < entry.addrlist.size(); ++i) {
+ address_list->AppendString(entry.addrlist[i].ToStringWithoutPort());
+ }
+ entry_dict->Set("addresses", address_list);
+ }
+
+ entry_list->Append(entry_dict);
+ }
+
+ cache_info_dict->Set("entries", entry_list);
+ dict->Set("cache", cache_info_dict);
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_HOST_RESOLVER), dict);
+ }
+ }
+
+ net::HttpNetworkSession* http_network_session =
+ context->http_transaction_factory()->GetSession();
+
+ if (info_sources & NET_INFO_SOCKET_POOL) {
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_SOCKET_POOL),
+ http_network_session->SocketPoolInfoToValue());
+ }
+
+ if (info_sources & NET_INFO_SPDY_SESSIONS) {
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_SPDY_SESSIONS),
+ http_network_session->SpdySessionPoolInfoToValue());
+ }
+
+ if (info_sources & NET_INFO_SPDY_STATUS) {
+ base::DictionaryValue* status_dict = new base::DictionaryValue();
+
+ status_dict->SetBoolean("spdy_enabled",
+ net::HttpStreamFactory::spdy_enabled());
+ status_dict->SetBoolean(
+ "use_alternate_protocols",
+ http_network_session->params().use_alternate_protocols);
+ status_dict->SetBoolean(
+ "force_spdy_over_ssl",
+ http_network_session->params().force_spdy_over_ssl);
+ status_dict->SetBoolean(
+ "force_spdy_always",
+ http_network_session->params().force_spdy_always);
+
+ std::vector<std::string> next_protos;
+ http_network_session->GetNextProtos(&next_protos);
+ std::string next_protos_string = JoinString(next_protos, ',');
+ status_dict->SetString("next_protos", next_protos_string);
+
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_SPDY_STATUS),
+ status_dict);
+ }
+
+ if (info_sources & NET_INFO_SPDY_ALT_PROTO_MAPPINGS) {
+ base::ListValue* dict_list = new base::ListValue();
+
+ const net::HttpServerProperties& http_server_properties =
+ *context->http_server_properties();
+
+ const net::AlternateProtocolMap& map =
+ http_server_properties.alternate_protocol_map();
+
+ for (net::AlternateProtocolMap::const_iterator it = map.begin();
+ it != map.end(); ++it) {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ dict->SetString("host_port_pair", it->first.ToString());
+ dict->SetString("alternate_protocol", it->second.ToString());
+ dict_list->Append(dict);
+ }
+
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_SPDY_ALT_PROTO_MAPPINGS),
+ dict_list);
+ }
+
+ if (info_sources & NET_INFO_QUIC) {
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_QUIC),
+ http_network_session->QuicInfoToValue());
+ }
+
+ if (info_sources & NET_INFO_HTTP_CACHE) {
+ base::DictionaryValue* info_dict = new base::DictionaryValue();
+ base::DictionaryValue* stats_dict = new base::DictionaryValue();
+
+ disk_cache::Backend* disk_cache = GetDiskCacheBackend(context);
+
+ if (disk_cache) {
+ // Extract the statistics key/value pairs from the backend.
+ base::StringPairs stats;
+ disk_cache->GetStats(&stats);
+ for (size_t i = 0; i < stats.size(); ++i) {
+ stats_dict->SetStringWithoutPathExpansion(
+ stats[i].first, stats[i].second);
+ }
+ }
+ info_dict->Set("stats", stats_dict);
+
+ net_info_dict->Set(NetInfoSourceToString(NET_INFO_HTTP_CACHE),
+ info_dict);
+ }
+
+ return net_info_dict.Pass();
+}
+
+} // namespace net
diff --git a/chromium/net/base/net_log_util.h b/chromium/net/base/net_log_util.h
new file mode 100644
index 00000000000..d9627da416e
--- /dev/null
+++ b/chromium/net/base/net_log_util.h
@@ -0,0 +1,43 @@
+// Copyright 2014 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.
+
+#ifndef NET_BASE_NET_LOG_UTIL_H_
+#define NET_BASE_NET_LOG_UTIL_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
+
+namespace base {
+class DictionaryValue;
+class Value;
+}
+
+namespace net {
+
+class URLRequestContext;
+
+// A set of flags that can be OR'd together to request specific information
+// about the current state of the URLRequestContext. See GetNetInfo, below.
+enum NetInfoSource {
+#define NET_INFO_SOURCE(label, string, value) NET_INFO_ ## label = value,
+#include "net/base/net_info_source_list.h"
+#undef NET_INFO_SOURCE
+ NET_INFO_ALL_SOURCES = -1,
+};
+
+// Utility methods for creating NetLog dumps.
+
+// Create a dictionary containing legend for net/ constants.
+NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetConstants();
+
+// Retrieves a dictionary containing information about the current state of
+// |context|. |info_sources| is a set of NetInfoSources OR'd together,
+// indicating just what information is being requested. Each NetInfoSource adds
+// one top-level entry to the returned dictionary.
+NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
+ URLRequestContext* context, int info_sources);
+
+} // namespace net
+
+#endif // NET_BASE_NET_LOG_UTIL_H_
diff --git a/chromium/net/base/net_log_util_unittest.cc b/chromium/net/base/net_log_util_unittest.cc
new file mode 100644
index 00000000000..e5cc3a33fb2
--- /dev/null
+++ b/chromium/net/base/net_log_util_unittest.cc
@@ -0,0 +1,54 @@
+// Copyright 2014 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_log_util.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_transaction.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+// Make sure GetNetConstants doesn't crash.
+TEST(NetLogUtil, GetNetConstants) {
+ scoped_ptr<base::Value> constants(GetNetConstants());
+}
+
+// Make sure GetNetInfo doesn't crash when called on contexts with and without
+// caches, and they have the same number of elements.
+TEST(NetLogUtil, GetNetInfo) {
+ TestURLRequestContext context;
+ net::HttpCache* http_cache = context.http_transaction_factory()->GetCache();
+
+ // Get NetInfo when there's no cache backend (It's only created on first use).
+ EXPECT_FALSE(http_cache->GetCurrentBackend());
+ scoped_ptr<base::DictionaryValue> net_info_without_cache(
+ GetNetInfo(&context, NET_INFO_ALL_SOURCES));
+ EXPECT_FALSE(http_cache->GetCurrentBackend());
+ EXPECT_GT(net_info_without_cache->size(), 0u);
+
+ // Fore creation of a cache backend, and get NetInfo again.
+ disk_cache::Backend* backend = NULL;
+ EXPECT_EQ(
+ OK,
+ context.http_transaction_factory()->GetCache()->GetBackend(
+ &backend, TestCompletionCallback().callback()));
+ EXPECT_TRUE(http_cache->GetCurrentBackend());
+ scoped_ptr<base::DictionaryValue> net_info_with_cache(
+ GetNetInfo(&context, NET_INFO_ALL_SOURCES));
+ EXPECT_GT(net_info_with_cache->size(), 0u);
+
+ EXPECT_EQ(net_info_without_cache->size(), net_info_with_cache->size());
+}
+
+} // namespace
+
+} // namespace net
diff --git a/chromium/net/base/net_string_util_icu_alternatives_android.cc b/chromium/net/base/net_string_util_icu_alternatives_android.cc
index ca0630328f5..ca0e7f0315d 100644
--- a/chromium/net/base/net_string_util_icu_alternatives_android.cc
+++ b/chromium/net/base/net_string_util_icu_alternatives_android.cc
@@ -20,12 +20,13 @@ namespace {
ScopedJavaLocalRef<jstring> ConvertToJstring(const std::string& text,
const char* charset) {
JNIEnv* env = base::android::AttachCurrentThread();
- jobject java_byte_buffer =
- env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length());
+ ScopedJavaLocalRef<jobject> java_byte_buffer(
+ env,
+ env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
base::android::ScopedJavaLocalRef<jstring> java_charset =
base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
ScopedJavaLocalRef<jstring> java_result =
- android::Java_NetStringUtil_convertToUnicode(env, java_byte_buffer,
+ android::Java_NetStringUtil_convertToUnicode(env, java_byte_buffer.obj(),
java_charset.obj());
return java_result;
}
@@ -36,13 +37,14 @@ ScopedJavaLocalRef<jstring> ConvertToJstring(const std::string& text,
ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring(
const std::string& text, const char* charset) {
JNIEnv* env = base::android::AttachCurrentThread();
- jobject java_byte_buffer =
- env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length());
+ ScopedJavaLocalRef<jobject> java_byte_buffer(
+ env,
+ env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
base::android::ScopedJavaLocalRef<jstring> java_charset =
base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
ScopedJavaLocalRef<jstring> java_result =
android::Java_NetStringUtil_convertToUnicodeAndNormalize(
- env, java_byte_buffer, java_charset.obj());
+ env, java_byte_buffer.obj(), java_charset.obj());
return java_result;
}
@@ -51,13 +53,14 @@ ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring(
ScopedJavaLocalRef<jstring> ConvertToJstringWithSubstitutions(
const std::string& text, const char* charset) {
JNIEnv* env = base::android::AttachCurrentThread();
- jobject java_byte_buffer =
- env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length());
+ ScopedJavaLocalRef<jobject> java_byte_buffer(
+ env,
+ env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
base::android::ScopedJavaLocalRef<jstring> java_charset =
base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
ScopedJavaLocalRef<jstring> java_result =
android::Java_NetStringUtil_convertToUnicodeWithSubstitutions(
- env, java_byte_buffer, java_charset.obj());
+ env, java_byte_buffer.obj(), java_charset.obj());
return java_result;
}
diff --git a/chromium/net/base/net_util.cc b/chromium/net/base/net_util.cc
index 5b3d65e515b..b9cf59f1789 100644
--- a/chromium/net/base/net_util.cc
+++ b/chromium/net/base/net_util.cc
@@ -5,6 +5,7 @@
#include "net/base/net_util.h"
#include <errno.h>
+#include <string.h>
#include <algorithm>
#include <iterator>
@@ -43,7 +44,6 @@
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
#include "base/values.h"
-#include "grit/net_resources.h"
#include "url/gurl.h"
#include "url/url_canon.h"
#include "url/url_canon_ip.h"
@@ -51,6 +51,7 @@
#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)
@@ -250,8 +251,7 @@ inline bool IsHostCharAlphanumeric(char c) {
return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'));
}
-bool IsCanonicalizedHostCompliant(const std::string& host,
- const std::string& desired_tld) {
+bool IsCanonicalizedHostCompliant(const std::string& host) {
if (host.empty())
return false;
@@ -281,8 +281,7 @@ bool IsCanonicalizedHostCompliant(const std::string& host,
}
}
- return most_recent_component_started_alphanumeric ||
- (!desired_tld.empty() && IsHostCharAlphanumeric(desired_tld[0]));
+ return most_recent_component_started_alphanumeric;
}
base::string16 StripWWW(const base::string16& text) {
@@ -375,6 +374,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;
@@ -501,6 +517,18 @@ bool IsIPAddressReserved(const IPAddressNumber& host_addr) {
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,
@@ -786,6 +814,28 @@ int ConvertAddressFamily(AddressFamily address_family) {
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
@@ -969,13 +1019,15 @@ NetworkInterface::NetworkInterface(const std::string& name,
uint32 interface_index,
NetworkChangeNotifier::ConnectionType type,
const IPAddressNumber& address,
- size_t network_prefix)
+ uint32 network_prefix,
+ int ip_address_attributes)
: name(name),
friendly_name(friendly_name),
interface_index(interface_index),
type(type),
address(address),
- network_prefix(network_prefix) {
+ network_prefix(network_prefix),
+ ip_address_attributes(ip_address_attributes) {
}
NetworkInterface::~NetworkInterface() {
@@ -1003,4 +1055,7 @@ unsigned MaskPrefixLength(const IPAddressNumber& mask) {
return CommonPrefixLength(mask, all_ones);
}
+ScopedWifiOptions::~ScopedWifiOptions() {
+}
+
} // namespace net
diff --git a/chromium/net/base/net_util.h b/chromium/net/base/net_util.h
index d83744fb596..72ac169a24c 100644
--- a/chromium/net/base/net_util.h
+++ b/chromium/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,
@@ -114,6 +118,9 @@ NET_EXPORT bool IsIPAddressReserved(const IPAddressNumber& address);
struct SockaddrStorage {
SockaddrStorage() : addr_len(sizeof(addr_storage)),
addr(reinterpret_cast<struct sockaddr*>(&addr_storage)) {}
+ SockaddrStorage(const SockaddrStorage& other);
+ void operator=(const SockaddrStorage& other);
+
struct sockaddr_storage addr_storage;
socklen_t addr_len;
struct sockaddr* const addr;
@@ -208,15 +215,10 @@ NET_EXPORT std::string CanonicalizeHost(const std::string& host,
// * Each component ends with an alphanumeric character or '-'
// * The last component begins with an alphanumeric character
// * Optional trailing dot after last component (means "treat as FQDN")
-// If |desired_tld| is non-NULL, the host will only be considered invalid if
-// appending it as a trailing component still results in an invalid host. This
-// helps us avoid marking as "invalid" user attempts to open, say, "www.-9.com"
-// by typing -, 9, <ctrl>+<enter>.
//
// 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,
- const std::string& desired_tld);
+NET_EXPORT bool IsCanonicalizedHostCompliant(const std::string& host);
// Call these functions to get the html snippet for a directory listing.
// The return values of both functions are in UTF-8.
@@ -369,10 +371,15 @@ NET_EXPORT_PRIVATE AddressFamily GetAddressFamily(
// Maps the given AddressFamily to either AF_INET, AF_INET6 or AF_UNSPEC.
NET_EXPORT_PRIVATE int ConvertAddressFamily(AddressFamily address_family);
+// Parses a URL-safe IP literal (see RFC 3986, Sec 3.2.2) to its numeric value.
+// Returns true on success, and fills |ip_number| with the numeric value
+NET_EXPORT bool ParseURLHostnameToNumber(const std::string& hostname,
+ IPAddressNumber* ip_number);
+
// Parses an IP address literal (either IPv4 or IPv6) to its numeric value.
// Returns true on success and fills |ip_number| with the numeric value.
-NET_EXPORT_PRIVATE bool ParseIPLiteralToNumber(const std::string& ip_literal,
- IPAddressNumber* ip_number);
+NET_EXPORT bool ParseIPLiteralToNumber(const std::string& ip_literal,
+ IPAddressNumber* ip_number);
// Converts an IPv4 address to an IPv4-mapped IPv6 address.
// For example 192.168.0.1 would be converted to ::ffff:192.168.0.1.
@@ -430,6 +437,24 @@ NET_EXPORT_PRIVATE int GetPortFromSockaddr(const struct sockaddr* address,
// machine.
NET_EXPORT_PRIVATE bool IsLocalhost(const std::string& host);
+// A subset of IP address attributes which are actionable by the
+// application layer. Currently unimplemented for all hosts;
+// IP_ADDRESS_ATTRIBUTE_NONE is always returned.
+enum IPAddressAttributes {
+ IP_ADDRESS_ATTRIBUTE_NONE = 0,
+
+ // A temporary address is dynamic by nature and will not contain MAC
+ // address. Presence of MAC address in IPv6 addresses can be used to
+ // track an endpoint and cause privacy concern. Please refer to
+ // RFC4941.
+ IP_ADDRESS_ATTRIBUTE_TEMPORARY = 1 << 0,
+
+ // A temporary address could become deprecated once the preferred
+ // lifetime is reached. It is still valid but shouldn't be used to
+ // create new connections.
+ IP_ADDRESS_ATTRIBUTE_DEPRECATED = 1 << 1,
+};
+
// struct that is used by GetNetworkList() to represent a network
// interface.
struct NET_EXPORT NetworkInterface {
@@ -439,7 +464,8 @@ struct NET_EXPORT NetworkInterface {
uint32 interface_index,
NetworkChangeNotifier::ConnectionType type,
const IPAddressNumber& address,
- size_t network_prefix);
+ uint32 network_prefix,
+ int ip_address_attributes);
~NetworkInterface();
std::string name;
@@ -447,7 +473,8 @@ struct NET_EXPORT NetworkInterface {
uint32 interface_index; // Always 0 on Android.
NetworkChangeNotifier::ConnectionType type;
IPAddressNumber address;
- size_t network_prefix;
+ uint32 network_prefix;
+ int ip_address_attributes; // Combination of |IPAddressAttributes|.
};
typedef std::vector<NetworkInterface> NetworkInterfaceList;
@@ -490,6 +517,28 @@ enum WifiPHYLayerProtocol {
// Currently only available on OS_WIN.
NET_EXPORT WifiPHYLayerProtocol GetWifiPHYLayerProtocol();
+enum WifiOptions {
+ // Disables background SSID scans.
+ WIFI_OPTIONS_DISABLE_SCAN = 1 << 0,
+ // Enables media streaming mode.
+ WIFI_OPTIONS_MEDIA_STREAMING_MODE = 1 << 1
+};
+
+class NET_EXPORT ScopedWifiOptions {
+ public:
+ ScopedWifiOptions() {}
+ virtual ~ScopedWifiOptions();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedWifiOptions);
+};
+
+// Set temporary options on all wifi interfaces.
+// |options| is an ORed bitfield of WifiOptions.
+// Options are automatically disabled when the scoped pointer
+// is freed. Currently only available on OS_WIN.
+NET_EXPORT scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options);
+
// Returns number of matching initial bits between the addresses |a1| and |a2|.
unsigned CommonPrefixLength(const IPAddressNumber& a1,
const IPAddressNumber& a2);
diff --git a/chromium/net/base/net_util_icu.cc b/chromium/net/base/net_util_icu.cc
index 4094feeff74..8526edaffbe 100644
--- a/chromium/net/base/net_util_icu.cc
+++ b/chromium/net/base/net_util_icu.cc
@@ -491,9 +491,9 @@ class HostComponentTransform : public AppendComponentTransform {
}
private:
- virtual base::string16 Execute(
+ base::string16 Execute(
const std::string& component_text,
- base::OffsetAdjuster::Adjustments* adjustments) const OVERRIDE {
+ base::OffsetAdjuster::Adjustments* adjustments) const override {
return IDNToUnicodeWithAdjustments(component_text, languages_,
adjustments);
}
@@ -508,9 +508,9 @@ class NonHostComponentTransform : public AppendComponentTransform {
}
private:
- virtual base::string16 Execute(
+ base::string16 Execute(
const std::string& component_text,
- base::OffsetAdjuster::Adjustments* adjustments) const OVERRIDE {
+ base::OffsetAdjuster::Adjustments* adjustments) const override {
return (unescape_rules_ == UnescapeRule::NONE) ?
base::UTF8ToUTF16WithAdjustments(component_text, adjustments) :
UnescapeAndDecodeUTF8URLComponentWithAdjustments(component_text,
diff --git a/chromium/net/base/net_util_icu_unittest.cc b/chromium/net/base/net_util_icu_unittest.cc
index 9beb4349b57..d92b9d162e1 100644
--- a/chromium/net/base/net_util_icu_unittest.cc
+++ b/chromium/net/base/net_util_icu_unittest.cc
@@ -411,7 +411,7 @@ void CheckAdjustedOffsets(const std::string& url_string,
} // anonymous namespace
TEST(NetUtilTest, IDNToUnicodeFast) {
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(idn_cases); i++) {
+ for (size_t i = 0; i < arraysize(idn_cases); i++) {
for (size_t j = 0; j < arraysize(kLanguages); j++) {
// ja || zh-TW,en || ko,ja -> IDNToUnicodeSlow
if (j == 3 || j == 17 || j == 18)
@@ -427,7 +427,7 @@ TEST(NetUtilTest, IDNToUnicodeFast) {
}
TEST(NetUtilTest, IDNToUnicodeSlow) {
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(idn_cases); i++) {
+ for (size_t i = 0; i < arraysize(idn_cases); i++) {
for (size_t j = 0; j < arraysize(kLanguages); j++) {
// !(ja || zh-TW,en || ko,ja) -> IDNToUnicodeFast
if (!(j == 3 || j == 17 || j == 18))
@@ -506,7 +506,7 @@ TEST(NetUtilTest, GetDirectoryListingEntry) {
",0,\"9.8 kB\",\"\");</script>\n"},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+ for (size_t i = 0; i < arraysize(test_cases); ++i) {
const std::string results = GetDirectoryListingEntry(
WideToUTF16(test_cases[i].name),
test_cases[i].raw_bytes,
diff --git a/chromium/net/base/net_util_posix.cc b/chromium/net/base/net_util_posix.cc
index 315e9ed1a23..a2fa6cdf2ce 100644
--- a/chromium/net/base/net_util_posix.cc
+++ b/chromium/net/base/net_util_posix.cc
@@ -9,6 +9,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
@@ -18,11 +19,16 @@
#include "net/base/net_errors.h"
#include "url/gurl.h"
-#if !defined(OS_ANDROID) && !defined(OS_NACL)
+#if !defined(OS_NACL)
+#if defined(OS_MACOSX)
#include <ifaddrs.h>
+#else
+#include "net/base/address_tracker_linux.h"
+#include "net/base/net_util_posix.h"
+#endif // OS_MACOSX
#include <net/if.h>
#include <netinet/in.h>
-#endif
+#endif // !defined(OS_NACL)
#if defined(OS_MACOSX) && !defined(OS_IOS)
#include <net/if_media.h>
@@ -30,15 +36,48 @@
#include <sys/ioctl.h>
#endif
-#if defined(OS_ANDROID)
-#include "net/android/network_library.h"
-#endif
-
namespace net {
namespace {
-#if !defined(OS_ANDROID)
+// The application layer can pass |policy| defined in net_util.h to
+// request filtering out certain type of interfaces.
+bool ShouldIgnoreInterface(const std::string& name, int policy) {
+ // Filter out VMware interfaces, typically named vmnet1 and vmnet8,
+ // which might not be useful for use cases like WebRTC.
+ if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) &&
+ ((name.find("vmnet") != std::string::npos) ||
+ (name.find("vnic") != std::string::npos))) {
+ return true;
+ }
+
+ return false;
+}
+
+// Check if the address is unspecified (i.e. made of zeroes) or loopback.
+bool IsLoopbackOrUnspecifiedAddress(const sockaddr* addr) {
+ if (addr->sa_family == 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_UNSPECIFIED(sin6_addr)) {
+ return true;
+ }
+ } else if (addr->sa_family == AF_INET) {
+ const struct sockaddr_in* addr_in =
+ reinterpret_cast<const struct sockaddr_in*>(addr);
+ if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK ||
+ addr_in->sin_addr.s_addr == 0) {
+ return true;
+ }
+ } else {
+ // Skip non-IP addresses.
+ return true;
+ }
+ return false;
+}
+
+#if defined(OS_MACOSX)
struct NetworkInterfaceInfo {
NetworkInterfaceInfo() : permanent(true) { }
@@ -82,10 +121,7 @@ void RemovePermanentIPv6AddressesWhereTemporaryExists(
}
}
-#endif
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-
+#if !defined(OS_IOS)
NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
int addr_family, const std::string& interface_name) {
NetworkChangeNotifier::ConnectionType type =
@@ -110,53 +146,160 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
return type;
}
-#endif
+#endif // !defined(OS_IOS)
+#elif !defined(OS_NACL) // OS_MACOSX
+
+// Convert platform native IPv6 address attributes to net IP address
+// attributes and drop ones that can't be used by the application
+// layer.
+bool TryConvertNativeToNetIPAttributes(int native_attributes,
+ int* net_attributes) {
+ // For Linux/ChromeOS/Android, we disallow addresses with attributes
+ // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these
+ // are still progressing through duplicated address detection (DAD)
+ // and shouldn't be used by the application layer until DAD process
+ // is completed.
+ if (native_attributes & (
+#if !defined(OS_ANDROID)
+ IFA_F_OPTIMISTIC | IFA_F_DADFAILED |
+#endif // !OS_ANDROID
+ IFA_F_TENTATIVE)) {
+ return false;
+ }
+
+ if (native_attributes & IFA_F_TEMPORARY) {
+ *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
+ }
+
+ if (native_attributes & IFA_F_DEPRECATED) {
+ *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
+ }
+ return true;
+}
+#endif // OS_MACOSX
} // namespace
-bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
-#if defined(OS_NACL)
- NOTIMPLEMENTED();
- return false;
-#elif defined(OS_ANDROID)
- std::string network_list = android::GetNetworkList();
- base::StringTokenizer network_interfaces(network_list, "\n");
- while (network_interfaces.GetNext()) {
- std::string network_item = network_interfaces.token();
- base::StringTokenizer network_tokenizer(network_item, "\t");
- CHECK(network_tokenizer.GetNext());
- std::string name = network_tokenizer.token();
-
- CHECK(network_tokenizer.GetNext());
- std::string interface_address = network_tokenizer.token();
- IPAddressNumber address;
- size_t network_prefix = 0;
- CHECK(ParseCIDRBlock(network_tokenizer.token(),
- &address,
- &network_prefix));
-
- CHECK(network_tokenizer.GetNext());
- uint32 index = 0;
- CHECK(base::StringToUint(network_tokenizer.token(), &index));
+namespace internal {
+
+#if !defined(OS_MACOSX) && !defined(OS_NACL)
+
+inline const unsigned char* GetIPAddressData(const IPAddressNumber& ip) {
+#if defined(OS_ANDROID)
+ return ip.begin();
+#else
+ return ip.data();
+#endif
+}
+
+bool GetNetworkListImpl(
+ NetworkInterfaceList* networks,
+ int policy,
+ const base::hash_set<int>& online_links,
+ const internal::AddressTrackerLinux::AddressMap& address_map,
+ GetInterfaceNameFunction get_interface_name) {
+ std::map<int, std::string> ifnames;
+
+ for (internal::AddressTrackerLinux::AddressMap::const_iterator it =
+ address_map.begin();
+ it != address_map.end();
+ ++it) {
+ // Ignore addresses whose links are not online.
+ if (online_links.find(it->second.ifa_index) == online_links.end())
+ continue;
+
+ sockaddr_storage sock_addr;
+ socklen_t sock_len = sizeof(sockaddr_storage);
+
+ // Convert to sockaddr for next check.
+ if (!IPEndPoint(it->first, 0)
+ .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) {
+ continue;
+ }
+
+ // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
+ if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr*>(&sock_addr)))
+ continue;
+
+ int ip_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
+
+ if (it->second.ifa_family == AF_INET6) {
+ // Ignore addresses whose attributes are not actionable by
+ // the application layer.
+ if (!TryConvertNativeToNetIPAttributes(it->second.ifa_flags,
+ &ip_attributes))
+ continue;
+ }
+
+ // Find the name of this link.
+ std::map<int, std::string>::const_iterator itname =
+ ifnames.find(it->second.ifa_index);
+ std::string ifname;
+ if (itname == ifnames.end()) {
+ char buffer[IF_NAMESIZE] = {0};
+ if (get_interface_name(it->second.ifa_index, buffer)) {
+ ifname = ifnames[it->second.ifa_index] = buffer;
+ } else {
+ // Ignore addresses whose interface name can't be retrieved.
+ continue;
+ }
+ } else {
+ ifname = itname->second;
+ }
+
+ // Based on the interface name and policy, determine whether we
+ // should ignore it.
+ if (ShouldIgnoreInterface(ifname, policy))
+ continue;
networks->push_back(
- NetworkInterface(name, name, index,
+ NetworkInterface(ifname,
+ ifname,
+ it->second.ifa_index,
NetworkChangeNotifier::CONNECTION_UNKNOWN,
- address, network_prefix));
+ it->first,
+ it->second.ifa_prefixlen,
+ ip_attributes));
}
+
return true;
-#else
+}
+#endif
+
+} // namespace internal
+
+bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
+ if (networks == NULL)
+ return false;
+#if defined(OS_NACL)
+ NOTIMPLEMENTED();
+ return false;
+#elif !defined(OS_MACOSX)
+
+ internal::AddressTrackerLinux tracker;
+ tracker.Init();
+
+ return internal::GetNetworkListImpl(networks,
+ policy,
+ tracker.GetOnlineLinks(),
+ tracker.GetAddressMap(),
+ &if_indextoname);
+
+#else // Only OS_MACOSX and OS_IOS will run the code below
+
// getifaddrs() may require IO operations.
base::ThreadRestrictions::AssertIOAllowed();
+#if !defined(OS_IOS)
int ioctl_socket = -1;
if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) {
// we need a socket to query information about temporary address.
ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0);
DCHECK_GT(ioctl_socket, 0);
}
+#endif
- ifaddrs *interfaces;
+ ifaddrs* interfaces;
if (getifaddrs(&interfaces) < 0) {
PLOG(ERROR) << "getifaddrs";
return false;
@@ -180,41 +323,26 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
// Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
// configured on non-loopback interfaces.
+ if (IsLoopbackOrUnspecifiedAddress(addr))
+ continue;
+
int addr_size = 0;
if (addr->sa_family == AF_INET6) {
- struct sockaddr_in6* addr_in6 =
- reinterpret_cast<struct sockaddr_in6*>(addr);
- struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
- addr_size = sizeof(*addr_in6);
- if (IN6_IS_ADDR_LOOPBACK(sin6_addr) ||
- IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) {
- continue;
- }
+ addr_size = sizeof(sockaddr_in6);
} else if (addr->sa_family == AF_INET) {
- struct sockaddr_in* addr_in =
- reinterpret_cast<struct sockaddr_in*>(addr);
- addr_size = sizeof(*addr_in);
- if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK ||
- addr_in->sin_addr.s_addr == 0) {
- continue;
- }
- } else {
- // Skip non-IP addresses.
- continue;
+ addr_size = sizeof(sockaddr_in);
}
const std::string& name = interface->ifa_name;
// Filter out VMware interfaces, typically named vmnet1 and vmnet8.
- if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) &&
- ((name.find("vmnet") != std::string::npos) ||
- (name.find("vnic") != std::string::npos))) {
+ if (ShouldIgnoreInterface(name, policy)) {
continue;
}
NetworkInterfaceInfo network_info;
NetworkChangeNotifier::ConnectionType connection_type =
NetworkChangeNotifier::CONNECTION_UNKNOWN;
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if !defined(OS_IOS)
// Check if this is a temporary address. Currently this is only supported
// on Mac.
if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) &&
@@ -245,17 +373,23 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
net_mask = MaskPrefixLength(netmask.address());
}
}
- network_info.interface = NetworkInterface(
- name, name, if_nametoindex(name.c_str()),
- connection_type, address.address(), net_mask);
+ network_info.interface = NetworkInterface(name,
+ name,
+ if_nametoindex(name.c_str()),
+ connection_type,
+ address.address(),
+ net_mask,
+ IP_ADDRESS_ATTRIBUTE_NONE);
network_infos.push_back(NetworkInterfaceInfo(network_info));
}
}
freeifaddrs(interfaces);
+#if !defined(OS_IOS)
if (ioctl_socket >= 0) {
close(ioctl_socket);
}
+#endif
if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) {
RemovePermanentIPv6AddressesWhereTemporaryExists(&network_infos);
@@ -272,4 +406,9 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
}
+scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) {
+ return scoped_ptr<ScopedWifiOptions>();
+}
+
+
} // namespace net
diff --git a/chromium/net/base/net_util_posix.h b/chromium/net/base/net_util_posix.h
new file mode 100644
index 00000000000..b553d1c9144
--- /dev/null
+++ b/chromium/net/base/net_util_posix.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2014 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.
+
+#ifndef NET_BASE_NET_UTIL_POSIX_H_
+#define NET_BASE_NET_UTIL_POSIX_H_
+
+// This file is only used to expose some of the internals
+// of net_util_posix.cc to tests.
+
+namespace net {
+namespace internal {
+
+#if !defined(OS_MACOSX) && !defined(OS_NACL)
+typedef char* (*GetInterfaceNameFunction)(unsigned int interface_index,
+ char* ifname);
+
+NET_EXPORT bool GetNetworkListImpl(
+ NetworkInterfaceList* networks,
+ int policy,
+ const base::hash_set<int>& online_links,
+ const internal::AddressTrackerLinux::AddressMap& address_map,
+ GetInterfaceNameFunction get_interface_name);
+
+#endif // !OS_MACOSX && !OS_NACL
+
+} // namespace internal
+
+} // namespace net
+
+#endif // NET_BASE_NET_UTIL_POSIX_H_
diff --git a/chromium/net/base/net_util_unittest.cc b/chromium/net/base/net_util_unittest.cc
index 674a7259121..45f08571c41 100644
--- a/chromium/net/base/net_util_unittest.cc
+++ b/chromium/net/base/net_util_unittest.cc
@@ -17,6 +17,11 @@
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
#include "base/time/time.h"
+
+#if !defined(OS_NACL) && !defined(OS_WIN)
+#include <net/if.h>
+#include <netinet/in.h>
+#endif // !OS_NACL && !OS_WIN
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -24,10 +29,17 @@
#include <iphlpapi.h>
#include <objbase.h>
#include "base/win/windows_version.h"
-#elif !defined(OS_ANDROID)
-#include <net/if.h>
+#include "net/base/net_util_win.h"
#endif // OS_WIN
+#if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_WIN)
+#include "net/base/address_tracker_linux.h"
+#endif // !OS_MACOSX && !OS_NACL && !OS_WIN
+
+#if !defined(OS_WIN)
+#include "net/base/net_util_posix.h"
+#endif // !OS_WIN
+
using base::ASCIIToUTF16;
using base::WideToUTF16;
@@ -40,12 +52,6 @@ struct HeaderCase {
const char* expected;
};
-struct CompliantHostCase {
- const char* host;
- const char* desired_tld;
- bool expected_output;
-};
-
// Fills in sockaddr for the given 32-bit address (IPv4.)
// |bytes| should be an array of length 4.
void MakeIPv4Address(const uint8* bytes, int port, SockaddrStorage* storage) {
@@ -123,7 +129,7 @@ TEST(NetUtilTest, GetIdentityFromURL) {
"p&ssword",
},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
tests[i].input_url));
GURL url(tests[i].input_url);
@@ -185,50 +191,53 @@ TEST(NetUtilTest, GetSpecificHeader) {
};
// Test first with google_headers.
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
std::string result =
GetSpecificHeader(google_headers, tests[i].header_name);
EXPECT_EQ(result, tests[i].expected);
}
// Test again with empty headers.
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
std::string result = GetSpecificHeader(std::string(), tests[i].header_name);
EXPECT_EQ(result, std::string());
}
}
TEST(NetUtilTest, CompliantHost) {
+ struct CompliantHostCase {
+ const char* host;
+ bool expected_output;
+ };
+
const CompliantHostCase compliant_host_cases[] = {
- {"", "", false},
- {"a", "", true},
- {"-", "", false},
- {".", "", false},
- {"9", "", true},
- {"9a", "", true},
- {"a.", "", true},
- {"a.a", "", true},
- {"9.a", "", true},
- {"a.9", "", true},
- {"_9a", "", false},
- {"-9a", "", false},
- {"-9a", "a", true},
- {"a.a9", "", true},
- {"a.-a9", "", false},
- {"a+9a", "", false},
- {"-a.a9", "", true},
- {"1-.a-b", "", true},
- {"1_.a-b", "", false},
- {"1-2.a_b", "", true},
- {"a.b.c.d.e", "", true},
- {"1.2.3.4.5", "", true},
- {"1.2.3.4.5.", "", true},
+ {"", false},
+ {"a", true},
+ {"-", false},
+ {".", false},
+ {"9", true},
+ {"9a", true},
+ {"a.", true},
+ {"a.a", true},
+ {"9.a", true},
+ {"a.9", true},
+ {"_9a", false},
+ {"-9a", false},
+ {"a.a9", true},
+ {"a.-a9", false},
+ {"a+9a", false},
+ {"-a.a9", true},
+ {"1-.a-b", true},
+ {"1_.a-b", false},
+ {"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_UNSAFE(compliant_host_cases); ++i) {
+ 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,
- compliant_host_cases[i].desired_tld));
+ IsCanonicalizedHostCompliant(compliant_host_cases[i].host));
}
}
@@ -245,9 +254,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},
@@ -261,9 +281,11 @@ 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) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
std::string host;
int port;
bool ok = ParseHostAndPort(tests[i].input, &host, &port);
@@ -289,7 +311,7 @@ TEST(NetUtilTest, GetHostAndPort) {
{ GURL("http://[1::2]/x"), "[1::2]:80"},
{ GURL("http://[::a]:33/x"), "[::a]:33"},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ 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);
}
@@ -307,7 +329,7 @@ TEST(NetUtilTest, GetHostAndOptionalPort) {
{ GURL("http://[1::2]/x"), "[1::2]"},
{ GURL("http://[::a]:33/x"), "[::a]:33"},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ 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);
}
@@ -347,7 +369,7 @@ TEST(NetUtilTest, NetAddressToString_IPv4) {
{{192, 168, 0, 1}, "192.168.0.1"},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
SockaddrStorage storage;
MakeIPv4Address(tests[i].addr, 80, &storage);
std::string result = NetAddressToString(storage.addr, storage.addr_len);
@@ -365,7 +387,7 @@ TEST(NetUtilTest, NetAddressToString_IPv6) {
"fedc:ba98:7654:3210:fedc:ba98:7654:3210"},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
SockaddrStorage storage;
MakeIPv6Address(tests[i].addr, 80, &storage);
EXPECT_EQ(std::string(tests[i].result),
@@ -441,7 +463,7 @@ TEST(NetUtilTest, SimplifyUrlForRequest) {
"foobar://user:pass@google.com:80/sup?yo",
},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ 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));
@@ -454,12 +476,12 @@ TEST(NetUtilTest, SetExplicitlyAllowedPortsTest) {
std::string invalid[] = { "1,2,a", "'1','2'", "1, 2, 3", "1 0,11,12" };
std::string valid[] = { "", "1", "1,2", "1,2,3", "10,11,12,13" };
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(invalid); ++i) {
+ for (size_t i = 0; i < arraysize(invalid); ++i) {
SetExplicitlyAllowedPorts(invalid[i]);
EXPECT_EQ(0, static_cast<int>(GetCountOfExplicitlyAllowedPorts()));
}
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(valid); ++i) {
+ for (size_t i = 0; i < arraysize(valid); ++i) {
SetExplicitlyAllowedPorts(valid[i]);
EXPECT_EQ(i, GetCountOfExplicitlyAllowedPorts());
}
@@ -524,6 +546,31 @@ TEST(NetUtilTest, ConvertIPv4NumberToIPv6Number) {
EXPECT_EQ("::ffff:c0a8:1", IPAddressToString(ipv6_number));
}
+TEST(NetUtilTest, ParseURLHostnameToNumber_FailParse) {
+ IPAddressNumber number;
+
+ EXPECT_FALSE(ParseURLHostnameToNumber("bad value", &number));
+ EXPECT_FALSE(ParseURLHostnameToNumber("bad:value", &number));
+ EXPECT_FALSE(ParseURLHostnameToNumber(std::string(), &number));
+ EXPECT_FALSE(ParseURLHostnameToNumber("192.168.0.1:30", &number));
+ EXPECT_FALSE(ParseURLHostnameToNumber(" 192.168.0.1 ", &number));
+ EXPECT_FALSE(ParseURLHostnameToNumber("::1", &number));
+}
+
+TEST(NetUtilTest, ParseURLHostnameToNumber_IPv4) {
+ IPAddressNumber number;
+ EXPECT_TRUE(ParseURLHostnameToNumber("192.168.0.1", &number));
+ EXPECT_EQ("192,168,0,1", DumpIPNumber(number));
+ EXPECT_EQ("192.168.0.1", IPAddressToString(number));
+}
+
+TEST(NetUtilTest, ParseURLHostnameToNumber_IPv6) {
+ IPAddressNumber number;
+ EXPECT_TRUE(ParseURLHostnameToNumber("[1:abcd::3:4:ff]", &number));
+ EXPECT_EQ("0,1,171,205,0,0,0,0,0,0,0,3,0,4,0,255", DumpIPNumber(number));
+ EXPECT_EQ("1:abcd::3:4:ff", IPAddressToString(number));
+}
+
TEST(NetUtilTest, IsIPv4Mapped) {
IPAddressNumber ipv4_number;
EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &ipv4_number));
@@ -647,7 +694,7 @@ TEST(NetUtilTest, IPNumberMatchesPrefix) {
false
},
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ for (size_t i = 0; i < arraysize(tests); ++i) {
SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s, %s", i,
tests[i].cidr_literal,
tests[i].ip_literal));
@@ -765,6 +812,261 @@ TEST(NetUtilTest, GetNetworkList) {
}
}
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_NACL)
+
+char* CopyInterfaceName(const char* ifname, int ifname_size, char* output) {
+ EXPECT_LT(ifname_size, IF_NAMESIZE);
+ memcpy(output, ifname, ifname_size);
+ return output;
+}
+
+static const char ifname_em1[] = "em1";
+char* GetInterfaceName(unsigned int interface_index, char* ifname) {
+ return CopyInterfaceName(ifname_em1, arraysize(ifname_em1), ifname);
+}
+
+static const char ifname_vm[] = "vmnet";
+char* GetInterfaceNameVM(unsigned int interface_index, char* ifname) {
+ return CopyInterfaceName(ifname_vm, arraysize(ifname_vm), ifname);
+}
+
+TEST(NetUtilTest, GetNetworkListTrimming) {
+ NetworkInterfaceList results;
+ ::base::hash_set<int> online_links;
+ net::internal::AddressTrackerLinux::AddressMap address_map;
+
+ const unsigned char kIPv6LocalAddr[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ const unsigned char kIPv6Addr[] =
+ {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
+ 0xfe, 0xe5, 0x00, 0xc3};
+
+ IPAddressNumber ipv6_local_address(
+ kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
+ IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
+
+ // Interface 1 is offline.
+ struct ifaddrmsg msg = {
+ AF_INET6,
+ 1, /* prefix length */
+ IFA_F_TEMPORARY, /* address flags */
+ 0, /* link scope */
+ 1 /* link index */
+ };
+
+ // Address of offline links should be ignored.
+ ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+ EXPECT_TRUE(
+ net::internal::GetNetworkListImpl(&results,
+ INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+ online_links,
+ address_map,
+ GetInterfaceName));
+ EXPECT_EQ(results.size(), 0ul);
+
+ // Mark interface 1 online.
+ online_links.insert(1);
+
+ // Local address should be trimmed out.
+ address_map.clear();
+ ASSERT_TRUE(
+ address_map.insert(std::make_pair(ipv6_local_address, msg)).second);
+ EXPECT_TRUE(
+ net::internal::GetNetworkListImpl(&results,
+ INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+ online_links,
+ address_map,
+ GetInterfaceName));
+ EXPECT_EQ(results.size(), 0ul);
+
+ // vmware address should return by default.
+ address_map.clear();
+ ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+ EXPECT_TRUE(
+ net::internal::GetNetworkListImpl(&results,
+ INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+ online_links,
+ address_map,
+ GetInterfaceNameVM));
+ EXPECT_EQ(results.size(), 1ul);
+ EXPECT_EQ(results[0].name, ifname_vm);
+ EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].address, ipv6_address);
+ results.clear();
+
+ // vmware address should be trimmed out if policy specified so.
+ address_map.clear();
+ ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+ EXPECT_TRUE(
+ net::internal::GetNetworkListImpl(&results,
+ EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+ online_links,
+ address_map,
+ GetInterfaceNameVM));
+ EXPECT_EQ(results.size(), 0ul);
+ results.clear();
+
+ // Addresses with banned attributes should be ignored.
+ address_map.clear();
+ msg.ifa_flags = IFA_F_TENTATIVE;
+ ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+ EXPECT_TRUE(
+ net::internal::GetNetworkListImpl(&results,
+ INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+ online_links,
+ address_map,
+ GetInterfaceName));
+ EXPECT_EQ(results.size(), 0ul);
+ results.clear();
+
+ // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
+ // attributes should be translated correctly.
+ address_map.clear();
+ msg.ifa_flags = IFA_F_TEMPORARY;
+ ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+ EXPECT_TRUE(
+ net::internal::GetNetworkListImpl(&results,
+ INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+ online_links,
+ address_map,
+ GetInterfaceName));
+ EXPECT_EQ(results.size(), 1ul);
+ EXPECT_EQ(results[0].name, ifname_em1);
+ EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].address, ipv6_address);
+ EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
+ results.clear();
+
+ // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
+ // attributes should be translated correctly.
+ address_map.clear();
+ msg.ifa_flags = IFA_F_DEPRECATED;
+ ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+ EXPECT_TRUE(
+ net::internal::GetNetworkListImpl(&results,
+ INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+ online_links,
+ address_map,
+ GetInterfaceName));
+ EXPECT_EQ(results.size(), 1ul);
+ EXPECT_EQ(results[0].name, ifname_em1);
+ EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].address, ipv6_address);
+ EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
+ results.clear();
+}
+
+#endif
+
+namespace {
+
+#if defined(OS_WIN)
+bool read_int_or_bool(DWORD data_size,
+ PVOID data) {
+ switch (data_size) {
+ case 1:
+ return !!*reinterpret_cast<uint8*>(data);
+ case 4:
+ return !!*reinterpret_cast<uint32*>(data);
+ default:
+ LOG(FATAL) << "That is not a type I know!";
+ return false;
+ }
+}
+
+int GetWifiOptions() {
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
+ if (!wlanapi.initialized)
+ return -1;
+
+ internal::WlanHandle client;
+ DWORD cur_version = 0;
+ const DWORD kMaxClientVersion = 2;
+ DWORD result = wlanapi.OpenHandle(
+ kMaxClientVersion, &cur_version, &client);
+ if (result != ERROR_SUCCESS)
+ return -1;
+
+ WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
+ result = wlanapi.enum_interfaces_func(client.Get(), NULL,
+ &interface_list_ptr);
+ if (result != ERROR_SUCCESS)
+ return -1;
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list(
+ interface_list_ptr);
+
+ for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) {
+ WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i];
+ DWORD data_size;
+ PVOID data;
+ int options = 0;
+ result = wlanapi.query_interface_func(
+ client.Get(),
+ &info->InterfaceGuid,
+ wlan_intf_opcode_background_scan_enabled,
+ NULL,
+ &data_size,
+ &data,
+ NULL);
+ if (result != ERROR_SUCCESS)
+ continue;
+ if (!read_int_or_bool(data_size, data)) {
+ options |= WIFI_OPTIONS_DISABLE_SCAN;
+ }
+ internal::WlanApi::GetInstance().free_memory_func(data);
+
+ result = wlanapi.query_interface_func(
+ client.Get(),
+ &info->InterfaceGuid,
+ wlan_intf_opcode_media_streaming_mode,
+ NULL,
+ &data_size,
+ &data,
+ NULL);
+ if (result != ERROR_SUCCESS)
+ continue;
+ if (read_int_or_bool(data_size, data)) {
+ options |= WIFI_OPTIONS_MEDIA_STREAMING_MODE;
+ }
+ internal::WlanApi::GetInstance().free_memory_func(data);
+
+ // Just the the options from the first succesful
+ // interface.
+ return options;
+ }
+
+ // No wifi interface found.
+ return -1;
+}
+
+#else // OS_WIN
+
+int GetWifiOptions() {
+ // Not supported.
+ return -1;
+}
+
+#endif // OS_WIN
+
+void TryChangeWifiOptions(int options) {
+ int previous_options = GetWifiOptions();
+ scoped_ptr<ScopedWifiOptions> scoped_options = SetWifiOptions(options);
+ EXPECT_EQ(previous_options | options, GetWifiOptions());
+ scoped_options.reset();
+ EXPECT_EQ(previous_options, GetWifiOptions());
+}
+
+}; // namespace
+
+// Test SetWifiOptions().
+TEST(NetUtilTest, SetWifiOptionsTest) {
+ TryChangeWifiOptions(0);
+ TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN);
+ TryChangeWifiOptions(WIFI_OPTIONS_MEDIA_STREAMING_MODE);
+ TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN |
+ WIFI_OPTIONS_MEDIA_STREAMING_MODE);
+}
+
struct NonUniqueNameTestData {
bool is_unique;
const char* hostname;
diff --git a/chromium/net/base/net_util_win.cc b/chromium/net/base/net_util_win.cc
index cac92e39d54..7d146b91e51 100644
--- a/chromium/net/base/net_util_win.cc
+++ b/chromium/net/base/net_util_win.cc
@@ -22,67 +22,13 @@
#include "net/base/escape.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
+#include "net/base/net_util_win.h"
#include "url/gurl.h"
namespace net {
namespace {
-struct WlanApi {
- typedef DWORD (WINAPI *WlanOpenHandleFunc)(
- DWORD, VOID*, DWORD*, HANDLE*);
- typedef DWORD (WINAPI *WlanEnumInterfacesFunc)(
- HANDLE, VOID*, WLAN_INTERFACE_INFO_LIST**);
- typedef DWORD (WINAPI *WlanQueryInterfaceFunc)(
- HANDLE, const GUID*, WLAN_INTF_OPCODE, VOID*, DWORD*, VOID**,
- WLAN_OPCODE_VALUE_TYPE*);
- typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*);
- typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*);
-
- WlanApi() : initialized(false) {
- // Use an absolute path to load the DLL to avoid DLL preloading attacks.
- static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll";
- wchar_t path[MAX_PATH] = {0};
- ExpandEnvironmentStrings(kDLL, path, arraysize(path));
- module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!module)
- return;
-
- open_handle_func = reinterpret_cast<WlanOpenHandleFunc>(
- ::GetProcAddress(module, "WlanOpenHandle"));
- enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>(
- ::GetProcAddress(module, "WlanEnumInterfaces"));
- query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>(
- ::GetProcAddress(module, "WlanQueryInterface"));
- free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>(
- ::GetProcAddress(module, "WlanFreeMemory"));
- close_handle_func = reinterpret_cast<WlanCloseHandleFunc>(
- ::GetProcAddress(module, "WlanCloseHandle"));
- initialized = open_handle_func && enum_interfaces_func &&
- query_interface_func && free_memory_func &&
- close_handle_func;
- }
-
- template <typename T>
- DWORD OpenHandle(DWORD client_version, DWORD* cur_version, T* handle) const {
- HANDLE temp_handle;
- DWORD result = open_handle_func(client_version, NULL, cur_version,
- &temp_handle);
- if (result != ERROR_SUCCESS)
- return result;
- handle->Set(temp_handle);
- return ERROR_SUCCESS;
- }
-
- HMODULE module;
- WlanOpenHandleFunc open_handle_func;
- WlanEnumInterfacesFunc enum_interfaces_func;
- WlanQueryInterfaceFunc query_interface_func;
- WlanFreeMemoryFunc free_memory_func;
- WlanCloseHandleFunc close_handle_func;
- bool initialized;
-};
-
// Converts Windows defined types to NetworkInterfaceType.
NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
// Bail out for pre-Vista versions of Windows which are documented to give
@@ -104,6 +50,43 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
} // namespace
+namespace internal {
+
+base::LazyInstance<WlanApi>::Leaky lazy_wlanapi =
+ LAZY_INSTANCE_INITIALIZER;
+
+WlanApi& WlanApi::GetInstance() {
+ return lazy_wlanapi.Get();
+}
+
+WlanApi::WlanApi() : initialized(false) {
+ // Use an absolute path to load the DLL to avoid DLL preloading attacks.
+ static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll";
+ wchar_t path[MAX_PATH] = {0};
+ ExpandEnvironmentStrings(kDLL, path, arraysize(path));
+ module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (!module)
+ return;
+
+ open_handle_func = reinterpret_cast<WlanOpenHandleFunc>(
+ ::GetProcAddress(module, "WlanOpenHandle"));
+ enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>(
+ ::GetProcAddress(module, "WlanEnumInterfaces"));
+ query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>(
+ ::GetProcAddress(module, "WlanQueryInterface"));
+ set_interface_func = reinterpret_cast<WlanSetInterfaceFunc>(
+ ::GetProcAddress(module, "WlanSetInterface"));
+ free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>(
+ ::GetProcAddress(module, "WlanFreeMemory"));
+ close_handle_func = reinterpret_cast<WlanCloseHandleFunc>(
+ ::GetProcAddress(module, "WlanCloseHandle"));
+ initialized = open_handle_func && enum_interfaces_func &&
+ query_interface_func && set_interface_func &&
+ free_memory_func && close_handle_func;
+}
+
+} // namespace internal
+
bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
// GetAdaptersAddresses() may require IO operations.
base::ThreadRestrictions::AssertIOAllowed();
@@ -190,20 +173,25 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
if (ipv6_valid_lifetime == 0 ||
ipv6_valid_lifetime > address->ValidLifetime) {
ipv6_valid_lifetime = address->ValidLifetime;
- ipv6_address.reset(new NetworkInterface(adapter->AdapterName,
- base::SysWideToNativeMB(adapter->FriendlyName),
- index,
- GetNetworkInterfaceType(adapter->IfType),
- endpoint.address(),
- net_prefix));
+ ipv6_address.reset(new NetworkInterface(
+ adapter->AdapterName,
+ base::SysWideToNativeMB(adapter->FriendlyName),
+ index,
+ GetNetworkInterfaceType(adapter->IfType),
+ endpoint.address(),
+ net_prefix,
+ IP_ADDRESS_ATTRIBUTE_NONE));
continue;
}
}
networks->push_back(
NetworkInterface(adapter->AdapterName,
base::SysWideToNativeMB(adapter->FriendlyName),
- index, GetNetworkInterfaceType(adapter->IfType),
- endpoint.address(), net_prefix));
+ index,
+ GetNetworkInterfaceType(adapter->IfType),
+ endpoint.address(),
+ net_prefix,
+ IP_ADDRESS_ATTRIBUTE_NONE));
}
}
}
@@ -216,39 +204,11 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
}
WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
- static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi =
- LAZY_INSTANCE_INITIALIZER;
-
- struct WlanApiHandleTraits {
- typedef HANDLE Handle;
-
- static bool CloseHandle(HANDLE handle) {
- return lazy_wlanapi.Get().close_handle_func(handle, NULL) ==
- ERROR_SUCCESS;
- }
- static bool IsHandleValid(HANDLE handle) {
- return base::win::HandleTraits::IsHandleValid(handle);
- }
- static HANDLE NullHandle() {
- return base::win::HandleTraits::NullHandle();
- }
- };
-
- typedef base::win::GenericScopedHandle<
- WlanApiHandleTraits,
- base::win::DummyVerifierTraits> WlanHandle;
-
- struct WlanApiDeleter {
- inline void operator()(void* ptr) const {
- lazy_wlanapi.Get().free_memory_func(ptr);
- }
- };
-
- const WlanApi& wlanapi = lazy_wlanapi.Get();
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
if (!wlanapi.initialized)
return WIFI_PHY_LAYER_PROTOCOL_NONE;
- WlanHandle client;
+ internal::WlanHandle client;
DWORD cur_version = 0;
const DWORD kMaxClientVersion = 2;
DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client);
@@ -256,10 +216,11 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
return WIFI_PHY_LAYER_PROTOCOL_NONE;
WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
- result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr);
+ result = wlanapi.enum_interfaces_func(client.Get(), NULL,
+ &interface_list_ptr);
if (result != ERROR_SUCCESS)
return WIFI_PHY_LAYER_PROTOCOL_NONE;
- scoped_ptr<WLAN_INTERFACE_INFO_LIST, WlanApiDeleter> interface_list(
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list(
interface_list_ptr);
// Assume at most one connected wifi interface.
@@ -279,11 +240,12 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
DWORD conn_info_size = 0;
WLAN_OPCODE_VALUE_TYPE op_code;
result = wlanapi.query_interface_func(
- client, &info->InterfaceGuid, wlan_intf_opcode_current_connection, NULL,
- &conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr), &op_code);
+ client.Get(), &info->InterfaceGuid, wlan_intf_opcode_current_connection,
+ NULL, &conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr),
+ &op_code);
if (result != ERROR_SUCCESS)
return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
- scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, WlanApiDeleter> conn_info(
+ scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter> conn_info(
conn_info_ptr);
switch (conn_info->wlanAssociationAttributes.dot11PhyType) {
@@ -306,4 +268,60 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
}
}
+// Note: There is no need to explicitly set the options back
+// as the OS will automatically set them back when the WlanHandle
+// is closed.
+class WifiOptionSetter : public ScopedWifiOptions {
+ public:
+ WifiOptionSetter(int options) {
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
+ if (!wlanapi.initialized)
+ return;
+
+ DWORD cur_version = 0;
+ const DWORD kMaxClientVersion = 2;
+ DWORD result = wlanapi.OpenHandle(
+ kMaxClientVersion, &cur_version, &client_);
+ if (result != ERROR_SUCCESS)
+ return;
+
+ WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
+ result = wlanapi.enum_interfaces_func(client_.Get(), NULL,
+ &interface_list_ptr);
+ if (result != ERROR_SUCCESS)
+ return;
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter>
+ interface_list(interface_list_ptr);
+
+ for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) {
+ WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i];
+ if (options & WIFI_OPTIONS_DISABLE_SCAN) {
+ BOOL data = false;
+ wlanapi.set_interface_func(client_.Get(),
+ &info->InterfaceGuid,
+ wlan_intf_opcode_background_scan_enabled,
+ sizeof(data),
+ &data,
+ NULL);
+ }
+ if (options & WIFI_OPTIONS_MEDIA_STREAMING_MODE) {
+ BOOL data = true;
+ wlanapi.set_interface_func(client_.Get(),
+ &info->InterfaceGuid,
+ wlan_intf_opcode_media_streaming_mode,
+ sizeof(data),
+ &data,
+ NULL);
+ }
+ }
+ }
+
+ private:
+ internal::WlanHandle client_;
+};
+
+scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) {
+ return scoped_ptr<ScopedWifiOptions>(new WifiOptionSetter(options));
+}
+
} // namespace net
diff --git a/chromium/net/base/net_util_win.h b/chromium/net/base/net_util_win.h
new file mode 100644
index 00000000000..afa888b1320
--- /dev/null
+++ b/chromium/net/base/net_util_win.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2014 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.
+
+#ifndef NET_BASE_NET_UTIL_WIN_H_
+#define NET_BASE_NET_UTIL_WIN_H_
+
+// This file is only used to expose some of the internals
+// of net_util_win.cc to tests.
+
+#include <wlanapi.h>
+
+#include "base/win/scoped_handle.h"
+#include "net/base/net_export.h"
+
+namespace net {
+namespace internal {
+
+struct NET_EXPORT WlanApi {
+ typedef DWORD (WINAPI *WlanOpenHandleFunc)(
+ DWORD, VOID*, DWORD*, HANDLE*);
+ typedef DWORD (WINAPI *WlanEnumInterfacesFunc)(
+ HANDLE, VOID*, WLAN_INTERFACE_INFO_LIST**);
+ typedef DWORD (WINAPI *WlanQueryInterfaceFunc)(
+ HANDLE, const GUID*, WLAN_INTF_OPCODE, VOID*, DWORD*, VOID**,
+ WLAN_OPCODE_VALUE_TYPE*);
+ typedef DWORD (WINAPI *WlanSetInterfaceFunc)(
+ HANDLE, const GUID*, WLAN_INTF_OPCODE, DWORD, const VOID*, VOID*);
+ typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*);
+ typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*);
+
+ WlanApi();
+ static WlanApi& GetInstance();
+
+ template <typename T>
+ DWORD OpenHandle(DWORD client_version, DWORD* cur_version, T* handle) const {
+ HANDLE temp_handle;
+ DWORD result = open_handle_func(client_version, NULL, cur_version,
+ &temp_handle);
+ if (result != ERROR_SUCCESS)
+ return result;
+ handle->Set(temp_handle);
+ return ERROR_SUCCESS;
+ }
+
+ HMODULE module;
+ WlanOpenHandleFunc open_handle_func;
+ WlanEnumInterfacesFunc enum_interfaces_func;
+ WlanQueryInterfaceFunc query_interface_func;
+ WlanSetInterfaceFunc set_interface_func;
+ WlanFreeMemoryFunc free_memory_func;
+ WlanCloseHandleFunc close_handle_func;
+ bool initialized;
+};
+
+struct WlanApiHandleTraits {
+ typedef HANDLE Handle;
+
+ static bool CloseHandle(HANDLE handle) {
+ return WlanApi::GetInstance().close_handle_func(handle, NULL) ==
+ ERROR_SUCCESS;
+ }
+ static bool IsHandleValid(HANDLE handle) {
+ return base::win::HandleTraits::IsHandleValid(handle);
+ }
+ static HANDLE NullHandle() {
+ return base::win::HandleTraits::NullHandle();
+ }
+};
+
+typedef base::win::GenericScopedHandle<
+ WlanApiHandleTraits,
+ base::win::DummyVerifierTraits> WlanHandle;
+
+struct WlanApiDeleter {
+ inline void operator()(void* ptr) const {
+ WlanApi::GetInstance().free_memory_func(ptr);
+ }
+};
+
+} // namespace internal
+
+} // namespace net
+
+#endif // NET_BASE_NET_UTIL_WIN_H_
diff --git a/chromium/net/base/network_change_notifier.cc b/chromium/net/base/network_change_notifier.cc
index c55be07d731..afd6b23d4fa 100644
--- a/chromium/net/base/network_change_notifier.cc
+++ b/chromium/net/base/network_change_notifier.cc
@@ -4,6 +4,8 @@
#include "net/base/network_change_notifier.h"
+#include <limits>
+
#include "base/metrics/histogram.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
@@ -43,7 +45,7 @@ NetworkChangeNotifierFactory* g_network_change_notifier_factory = NULL;
class MockNetworkChangeNotifier : public NetworkChangeNotifier {
public:
- virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
+ ConnectionType GetCurrentConnectionType() const override {
return CONNECTION_UNKNOWN;
}
};
@@ -81,7 +83,7 @@ class HistogramWatcher
NetworkChangeNotifier::AddNetworkChangeObserver(this);
}
- virtual ~HistogramWatcher() {
+ ~HistogramWatcher() override {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(g_network_change_notifier);
NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
@@ -91,7 +93,7 @@ class HistogramWatcher
}
// NetworkChangeNotifier::IPAddressObserver implementation.
- virtual void OnIPAddressChanged() OVERRIDE {
+ void OnIPAddressChanged() override {
DCHECK(thread_checker_.CalledOnValidThread());
UMA_HISTOGRAM_MEDIUM_TIMES("NCN.IPAddressChange",
SinceLast(&last_ip_address_change_));
@@ -101,8 +103,8 @@ class HistogramWatcher
}
// NetworkChangeNotifier::ConnectionTypeObserver implementation.
- virtual void OnConnectionTypeChanged(
- NetworkChangeNotifier::ConnectionType type) OVERRIDE {
+ void OnConnectionTypeChanged(
+ NetworkChangeNotifier::ConnectionType type) override {
DCHECK(thread_checker_.CalledOnValidThread());
base::TimeTicks now = base::TimeTicks::Now();
int32 kilobytes_read = bytes_read_since_last_connection_change_ / 1000;
@@ -262,15 +264,14 @@ class HistogramWatcher
}
// NetworkChangeNotifier::DNSObserver implementation.
- virtual void OnDNSChanged() OVERRIDE {
+ void OnDNSChanged() override {
DCHECK(thread_checker_.CalledOnValidThread());
UMA_HISTOGRAM_MEDIUM_TIMES("NCN.DNSConfigChange",
SinceLast(&last_dns_change_));
}
// NetworkChangeNotifier::NetworkChangeObserver implementation.
- virtual void OnNetworkChanged(
- NetworkChangeNotifier::ConnectionType type) OVERRIDE {
+ void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) override {
DCHECK(thread_checker_.CalledOnValidThread());
if (type != NetworkChangeNotifier::CONNECTION_NONE) {
UMA_HISTOGRAM_MEDIUM_TIMES("NCN.NetworkOnlineChange",
@@ -422,7 +423,7 @@ class NetworkChangeNotifier::NetworkChangeCalculator
AddIPAddressObserver(this);
}
- virtual ~NetworkChangeCalculator() {
+ ~NetworkChangeCalculator() override {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(g_network_change_notifier);
RemoveConnectionTypeObserver(this);
@@ -430,7 +431,7 @@ class NetworkChangeNotifier::NetworkChangeCalculator
}
// NetworkChangeNotifier::IPAddressObserver implementation.
- virtual void OnIPAddressChanged() OVERRIDE {
+ void OnIPAddressChanged() override {
DCHECK(thread_checker_.CalledOnValidThread());
base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
? params_.ip_address_offline_delay_ : params_.ip_address_online_delay_;
@@ -439,7 +440,7 @@ class NetworkChangeNotifier::NetworkChangeCalculator
}
// NetworkChangeNotifier::ConnectionTypeObserver implementation.
- virtual void OnConnectionTypeChanged(ConnectionType type) OVERRIDE {
+ void OnConnectionTypeChanged(ConnectionType type) override {
DCHECK(thread_checker_.CalledOnValidThread());
pending_connection_type_ = type;
base::TimeDelta delay = last_announced_connection_type_ == CONNECTION_NONE
@@ -535,6 +536,13 @@ NetworkChangeNotifier::GetConnectionType() {
}
// static
+double NetworkChangeNotifier::GetMaxBandwidth() {
+ return g_network_change_notifier ?
+ g_network_change_notifier->GetCurrentMaxBandwidth() :
+ std::numeric_limits<double>::infinity();
+}
+
+// static
void NetworkChangeNotifier::GetDnsConfig(DnsConfig* config) {
if (!g_network_change_notifier) {
*config = DnsConfig();
@@ -710,6 +718,32 @@ void NetworkChangeNotifier::RemoveNetworkChangeObserver(
}
}
+// static
+void NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests() {
+ if (g_network_change_notifier)
+ g_network_change_notifier->NotifyObserversOfIPAddressChangeImpl();
+}
+
+// static
+void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests(
+ ConnectionType type) {
+ if (g_network_change_notifier)
+ g_network_change_notifier->NotifyObserversOfConnectionTypeChangeImpl(type);
+}
+
+// static
+void NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ ConnectionType type) {
+ if (g_network_change_notifier)
+ g_network_change_notifier->NotifyObserversOfNetworkChangeImpl(type);
+}
+
+// static
+void NetworkChangeNotifier::SetTestNotificationsOnly(bool test_only) {
+ if (g_network_change_notifier)
+ g_network_change_notifier->test_notifications_only_ = test_only;
+}
+
NetworkChangeNotifier::NetworkChangeNotifier(
const NetworkChangeCalculatorParams& params
/*= NetworkChangeCalculatorParams()*/)
@@ -726,7 +760,8 @@ NetworkChangeNotifier::NetworkChangeNotifier(
new ObserverListThreadSafe<NetworkChangeObserver>(
ObserverListBase<NetworkChangeObserver>::NOTIFY_EXISTING_ONLY)),
network_state_(new NetworkState()),
- network_change_calculator_(new NetworkChangeCalculator(params)) {
+ network_change_calculator_(new NetworkChangeCalculator(params)),
+ test_notifications_only_(false) {
DCHECK(!g_network_change_notifier);
g_network_change_notifier = this;
network_change_calculator_->Init();
@@ -739,19 +774,46 @@ NetworkChangeNotifier::GetAddressTrackerInternal() const {
}
#endif
+double NetworkChangeNotifier::GetCurrentMaxBandwidth() const {
+ // This default implementation conforms to the NetInfo V3 specification but
+ // should be overridden to provide specific bandwidth data based on the
+ // platform.
+ if (GetCurrentConnectionType() == CONNECTION_NONE)
+ return 0.0;
+ return std::numeric_limits<double>::infinity();
+}
+
// static
void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() {
- if (g_network_change_notifier) {
- g_network_change_notifier->ip_address_observer_list_->Notify(
- &IPAddressObserver::OnIPAddressChanged);
+ if (g_network_change_notifier &&
+ !g_network_change_notifier->test_notifications_only_) {
+ g_network_change_notifier->NotifyObserversOfIPAddressChangeImpl();
+ }
+}
+
+// static
+void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange() {
+ if (g_network_change_notifier &&
+ !g_network_change_notifier->test_notifications_only_) {
+ g_network_change_notifier->NotifyObserversOfConnectionTypeChangeImpl(
+ GetConnectionType());
+ }
+}
+
+// static
+void NetworkChangeNotifier::NotifyObserversOfNetworkChange(
+ ConnectionType type) {
+ if (g_network_change_notifier &&
+ !g_network_change_notifier->test_notifications_only_) {
+ g_network_change_notifier->NotifyObserversOfNetworkChangeImpl(type);
}
}
// static
void NetworkChangeNotifier::NotifyObserversOfDNSChange() {
- if (g_network_change_notifier) {
- g_network_change_notifier->resolver_state_observer_list_->Notify(
- &DNSObserver::OnDNSChanged);
+ if (g_network_change_notifier &&
+ !g_network_change_notifier->test_notifications_only_) {
+ g_network_change_notifier->NotifyObserversOfDNSChangeImpl();
}
}
@@ -763,21 +825,24 @@ void NetworkChangeNotifier::SetDnsConfig(const DnsConfig& config) {
NotifyObserversOfDNSChange();
}
-void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange() {
- if (g_network_change_notifier) {
- g_network_change_notifier->connection_type_observer_list_->Notify(
- &ConnectionTypeObserver::OnConnectionTypeChanged,
- GetConnectionType());
- }
+void NetworkChangeNotifier::NotifyObserversOfIPAddressChangeImpl() {
+ ip_address_observer_list_->Notify(&IPAddressObserver::OnIPAddressChanged);
}
-void NetworkChangeNotifier::NotifyObserversOfNetworkChange(
+void NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeImpl(
ConnectionType type) {
- if (g_network_change_notifier) {
- g_network_change_notifier->network_change_observer_list_->Notify(
- &NetworkChangeObserver::OnNetworkChanged,
- type);
- }
+ connection_type_observer_list_->Notify(
+ &ConnectionTypeObserver::OnConnectionTypeChanged, type);
+}
+
+void NetworkChangeNotifier::NotifyObserversOfNetworkChangeImpl(
+ ConnectionType type) {
+ network_change_observer_list_->Notify(
+ &NetworkChangeObserver::OnNetworkChanged, type);
+}
+
+void NetworkChangeNotifier::NotifyObserversOfDNSChangeImpl() {
+ resolver_state_observer_list_->Notify(&DNSObserver::OnDNSChanged);
}
NetworkChangeNotifier::DisableForTest::DisableForTest()
diff --git a/chromium/net/base/network_change_notifier.h b/chromium/net/base/network_change_notifier.h
index 6b801bc7c42..bdd2d181a1f 100644
--- a/chromium/net/base/network_change_notifier.h
+++ b/chromium/net/base/network_change_notifier.h
@@ -132,7 +132,7 @@ class NET_EXPORT NetworkChangeNotifier {
// See the description of NetworkChangeNotifier::GetConnectionType().
// Implementations must be thread-safe. Implementations must also be
- // cheap as this could be called (repeatedly) from the network thread.
+ // cheap as it is called often.
virtual ConnectionType GetCurrentConnectionType() const = 0;
// Replaces the default class factory instance of NetworkChangeNotifier class.
@@ -159,6 +159,12 @@ class NET_EXPORT NetworkChangeNotifier {
// the internet, the connection type is CONNECTION_WIFI.
static ConnectionType GetConnectionType();
+ // Returns a theoretical upper limit on download bandwidth, potentially based
+ // on underlying connection type, signal strength, or some other signal. The
+ // default mapping of connection type to maximum bandwidth is provided in the
+ // NetInfo spec: http://w3c.github.io/netinfo/.
+ static double GetMaxBandwidth();
+
// Retrieve the last read DnsConfig. This could be expensive if the system has
// a large HOSTS file.
static void GetDnsConfig(DnsConfig* config);
@@ -212,9 +218,15 @@ class NET_EXPORT NetworkChangeNotifier {
static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer);
// Allow unit tests to trigger notifications.
- static void NotifyObserversOfIPAddressChangeForTests() {
- NotifyObserversOfIPAddressChange();
- }
+ static void NotifyObserversOfIPAddressChangeForTests();
+ static void NotifyObserversOfConnectionTypeChangeForTests(
+ ConnectionType type);
+ static void NotifyObserversOfNetworkChangeForTests(ConnectionType type);
+
+ // Enable or disable notifications from the host. After setting to true, be
+ // sure to pump the RunLoop until idle to finish any preexisting
+ // notifications.
+ static void SetTestNotificationsOnly(bool test_only);
// Return a string equivalent to |type|.
static const char* ConnectionTypeToString(ConnectionType type);
@@ -289,6 +301,11 @@ class NET_EXPORT NetworkChangeNotifier {
GetAddressTrackerInternal() const;
#endif
+ // See the description of NetworkChangeNotifier::GetMaxBandwidth().
+ // Implementations must be thread-safe. Implementations must also be
+ // cheap as it is called often.
+ virtual double GetCurrentMaxBandwidth() const;
+
// Broadcasts a notification to all registered observers. Note that this
// happens asynchronously, even for observers on the current thread, even in
// tests.
@@ -309,6 +326,11 @@ class NET_EXPORT NetworkChangeNotifier {
class NetworkState;
class NetworkChangeCalculator;
+ void NotifyObserversOfIPAddressChangeImpl();
+ void NotifyObserversOfConnectionTypeChangeImpl(ConnectionType type);
+ void NotifyObserversOfDNSChangeImpl();
+ void NotifyObserversOfNetworkChangeImpl(ConnectionType type);
+
const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> >
ip_address_observer_list_;
const scoped_refptr<ObserverListThreadSafe<ConnectionTypeObserver> >
@@ -327,6 +349,9 @@ class NET_EXPORT NetworkChangeNotifier {
// Computes NetworkChange signal from IPAddress and ConnectionType signals.
scoped_ptr<NetworkChangeCalculator> network_change_calculator_;
+ // Set true to disable non-test notifications (to prevent flakes in tests).
+ bool test_notifications_only_;
+
DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
};
diff --git a/chromium/net/base/network_change_notifier_linux.cc b/chromium/net/base/network_change_notifier_linux.cc
index 3fe96562c04..f77025a33d8 100644
--- a/chromium/net/base/network_change_notifier_linux.cc
+++ b/chromium/net/base/network_change_notifier_linux.cc
@@ -15,7 +15,7 @@ namespace net {
class NetworkChangeNotifierLinux::Thread : public base::Thread {
public:
Thread();
- virtual ~Thread();
+ ~Thread() override;
// Plumbing for NetworkChangeNotifier::GetCurrentConnectionType.
// Safe to call from any thread.
@@ -29,8 +29,8 @@ class NetworkChangeNotifierLinux::Thread : public base::Thread {
protected:
// base::Thread
- virtual void Init() OVERRIDE;
- virtual void CleanUp() OVERRIDE;
+ void Init() override;
+ void CleanUp() override;
private:
scoped_ptr<DnsConfigService> dns_config_service_;
diff --git a/chromium/net/base/network_change_notifier_linux.h b/chromium/net/base/network_change_notifier_linux.h
index a7080d9effb..5a0f6dff308 100644
--- a/chromium/net/base/network_change_notifier_linux.h
+++ b/chromium/net/base/network_change_notifier_linux.h
@@ -22,14 +22,14 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierLinux
class Thread;
NetworkChangeNotifierLinux();
- virtual ~NetworkChangeNotifierLinux();
+ ~NetworkChangeNotifierLinux() override;
static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsLinux();
// NetworkChangeNotifier:
- virtual ConnectionType GetCurrentConnectionType() const OVERRIDE;
+ ConnectionType GetCurrentConnectionType() const override;
- virtual const internal::AddressTrackerLinux*
- GetAddressTrackerInternal() const OVERRIDE;
+ const internal::AddressTrackerLinux* GetAddressTrackerInternal()
+ const override;
// The thread used to listen for notifications. This relays the notification
// to the registered observers without posting back to the thread the object
diff --git a/chromium/net/base/network_change_notifier_mac.cc b/chromium/net/base/network_change_notifier_mac.cc
index 7fa97b48b61..14ec5542c51 100644
--- a/chromium/net/base/network_change_notifier_mac.cc
+++ b/chromium/net/base/network_change_notifier_mac.cc
@@ -43,18 +43,14 @@ class NetworkChangeNotifierMac::DnsConfigServiceThread : public base::Thread {
public:
DnsConfigServiceThread() : base::Thread("DnsConfigService") {}
- virtual ~DnsConfigServiceThread() {
- Stop();
- }
+ ~DnsConfigServiceThread() override { Stop(); }
- virtual void Init() OVERRIDE {
+ void Init() override {
service_ = DnsConfigService::CreateSystemService();
service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig));
}
- virtual void CleanUp() OVERRIDE {
- service_.reset();
- }
+ void CleanUp() override { service_.reset(); }
private:
scoped_ptr<DnsConfigService> service_;
diff --git a/chromium/net/base/network_change_notifier_mac.h b/chromium/net/base/network_change_notifier_mac.h
index 168ea1480b7..6f340872fc1 100644
--- a/chromium/net/base/network_change_notifier_mac.h
+++ b/chromium/net/base/network_change_notifier_mac.h
@@ -21,10 +21,10 @@ namespace net {
class NetworkChangeNotifierMac: public NetworkChangeNotifier {
public:
NetworkChangeNotifierMac();
- virtual ~NetworkChangeNotifierMac();
+ ~NetworkChangeNotifierMac() override;
// NetworkChangeNotifier implementation:
- virtual ConnectionType GetCurrentConnectionType() const OVERRIDE;
+ ConnectionType GetCurrentConnectionType() const override;
// Forwarder just exists to keep the NetworkConfigWatcherMac API out of
// NetworkChangeNotifierMac's public API.
@@ -34,11 +34,10 @@ class NetworkChangeNotifierMac: public NetworkChangeNotifier {
: net_config_watcher_(net_config_watcher) {}
// NetworkConfigWatcherMac::Delegate implementation:
- virtual void Init() OVERRIDE;
- virtual void StartReachabilityNotifications() OVERRIDE;
- virtual void SetDynamicStoreNotificationKeys(
- SCDynamicStoreRef store) OVERRIDE;
- virtual void OnNetworkConfigChange(CFArrayRef changed_keys) OVERRIDE;
+ void Init() override;
+ void StartReachabilityNotifications() override;
+ void SetDynamicStoreNotificationKeys(SCDynamicStoreRef store) override;
+ void OnNetworkConfigChange(CFArrayRef changed_keys) override;
private:
NetworkChangeNotifierMac* const net_config_watcher_;
diff --git a/chromium/net/base/network_change_notifier_unittest.cc b/chromium/net/base/network_change_notifier_unittest.cc
new file mode 100644
index 00000000000..b8310fa5b7f
--- /dev/null
+++ b/chromium/net/base/network_change_notifier_unittest.cc
@@ -0,0 +1,60 @@
+// Copyright (c) 2014 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/network_change_notifier.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+// Note: This test is subject to the host's OS and network connection. This test
+// is not future-proof. New standards will come about necessitating the need to
+// alter the ranges of these tests.
+TEST(NetworkChangeNotifierTest, NetMaxBandwidthRange) {
+ NetworkChangeNotifier::ConnectionType connection_type =
+ NetworkChangeNotifier::GetConnectionType();
+ double max_bandwidth = NetworkChangeNotifier::GetMaxBandwidth();
+
+ // Always accept infinity as it's the default value if the bandwidth is
+ // unknown.
+ if (max_bandwidth == std::numeric_limits<double>::infinity()) {
+ EXPECT_NE(NetworkChangeNotifier::CONNECTION_NONE, connection_type);
+ return;
+ }
+
+ switch (connection_type) {
+ case NetworkChangeNotifier::CONNECTION_UNKNOWN:
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), max_bandwidth);
+ break;
+ case NetworkChangeNotifier::CONNECTION_ETHERNET:
+ EXPECT_GE(10.0, max_bandwidth);
+ EXPECT_LE(10000.0, max_bandwidth);
+ break;
+ case NetworkChangeNotifier::CONNECTION_WIFI:
+ EXPECT_GE(1.0, max_bandwidth);
+ EXPECT_LE(7000.0, max_bandwidth);
+ break;
+ case NetworkChangeNotifier::CONNECTION_2G:
+ EXPECT_GE(0.01, max_bandwidth);
+ EXPECT_LE(0.384, max_bandwidth);
+ break;
+ case NetworkChangeNotifier::CONNECTION_3G:
+ EXPECT_GE(2.0, max_bandwidth);
+ EXPECT_LE(42.0, max_bandwidth);
+ break;
+ case NetworkChangeNotifier::CONNECTION_4G:
+ EXPECT_GE(100.0, max_bandwidth);
+ EXPECT_LE(100.0, max_bandwidth);
+ break;
+ case NetworkChangeNotifier::CONNECTION_NONE:
+ EXPECT_EQ(0.0, max_bandwidth);
+ break;
+ case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
+ EXPECT_GE(1.0, max_bandwidth);
+ EXPECT_LE(24.0, max_bandwidth);
+ break;
+ }
+}
+
+} // namespace net
diff --git a/chromium/net/base/network_change_notifier_win.cc b/chromium/net/base/network_change_notifier_win.cc
index 77a72b0d693..1e6c51c7eb2 100644
--- a/chromium/net/base/network_change_notifier_win.cc
+++ b/chromium/net/base/network_change_notifier_win.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "net/base/winsock_init.h"
@@ -36,12 +37,12 @@ class NetworkChangeNotifierWin::DnsConfigServiceThread : public base::Thread {
Stop();
}
- virtual void Init() OVERRIDE {
+ virtual void Init() override {
service_ = DnsConfigService::CreateSystemService();
service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig));
}
- virtual void CleanUp() OVERRIDE {
+ virtual void CleanUp() override {
service_.reset();
}
@@ -218,6 +219,11 @@ void NetworkChangeNotifierWin::SetCurrentConnectionType(
}
void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/418183 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "NetworkChangeNotifierWin_OnObjectSignaled"));
+
DCHECK(CalledOnValidThread());
DCHECK(is_watching_);
is_watching_ = false;
diff --git a/chromium/net/base/network_change_notifier_win.h b/chromium/net/base/network_change_notifier_win.h
index 7b75c15dee3..9de1789f3d3 100644
--- a/chromium/net/base/network_change_notifier_win.h
+++ b/chromium/net/base/network_change_notifier_win.h
@@ -51,11 +51,11 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin
friend class NetworkChangeNotifierWinTest;
// NetworkChangeNotifier methods:
- virtual ConnectionType GetCurrentConnectionType() const OVERRIDE;
+ virtual ConnectionType GetCurrentConnectionType() const override;
// ObjectWatcher::Delegate methods:
// Must only be called on the thread |this| was created on.
- virtual void OnObjectSignaled(HANDLE object) OVERRIDE;
+ virtual void OnObjectSignaled(HANDLE object) override;
// Does the actual work to determine the current connection type.
// It is not thread safe, see crbug.com/324913.
@@ -95,9 +95,6 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin
// Number of times WatchForAddressChange has failed in a row.
int sequential_failures_;
- // Used for calling WatchForAddressChange again on failure.
- base::WeakPtrFactory<NetworkChangeNotifierWin> weak_factory_;
-
// Thread on which we can run DnsConfigService.
scoped_ptr<DnsConfigServiceThread> dns_config_service_thread_;
@@ -110,6 +107,9 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin
// Number of times polled to check if still offline.
int offline_polls_;
+ // Used for calling WatchForAddressChange again on failure.
+ base::WeakPtrFactory<NetworkChangeNotifierWin> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierWin);
};
diff --git a/chromium/net/base/network_change_notifier_win_unittest.cc b/chromium/net/base/network_change_notifier_win_unittest.cc
index 979105f18b2..25873c37f20 100644
--- a/chromium/net/base/network_change_notifier_win_unittest.cc
+++ b/chromium/net/base/network_change_notifier_win_unittest.cc
@@ -32,7 +32,7 @@ class TestNetworkChangeNotifierWin : public NetworkChangeNotifierWin {
// From NetworkChangeNotifierWin.
virtual NetworkChangeNotifier::ConnectionType
- RecomputeCurrentConnectionType() const OVERRIDE {
+ RecomputeCurrentConnectionType() const override {
return NetworkChangeNotifier::CONNECTION_UNKNOWN;
}
diff --git a/chromium/net/base/network_config_watcher_mac.cc b/chromium/net/base/network_config_watcher_mac.cc
index 8579a358391..bdf75c39ad2 100644
--- a/chromium/net/base/network_config_watcher_mac.cc
+++ b/chromium/net/base/network_config_watcher_mac.cc
@@ -31,12 +31,12 @@ void DynamicStoreCallback(SCDynamicStoreRef /* store */,
class NetworkConfigWatcherMacThread : public base::Thread {
public:
NetworkConfigWatcherMacThread(NetworkConfigWatcherMac::Delegate* delegate);
- virtual ~NetworkConfigWatcherMacThread();
+ ~NetworkConfigWatcherMacThread() override;
protected:
// base::Thread
- virtual void Init() OVERRIDE;
- virtual void CleanUp() OVERRIDE;
+ void Init() override;
+ void CleanUp() override;
private:
// The SystemConfiguration calls in this function can lead to contention early
diff --git a/chromium/net/base/network_delegate.cc b/chromium/net/base/network_delegate.cc
index d30a4ab4c88..9cad50a022b 100644
--- a/chromium/net/base/network_delegate.cc
+++ b/chromium/net/base/network_delegate.cc
@@ -5,8 +5,10 @@
#include "net/base/network_delegate.h"
#include "base/logging.h"
+#include "base/profiler/scoped_tracker.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
+#include "net/proxy/proxy_info.h"
#include "net/url_request/url_request.h"
namespace net {
@@ -17,21 +19,71 @@ int NetworkDelegate::NotifyBeforeURLRequest(
DCHECK(CalledOnValidThread());
DCHECK(request);
DCHECK(!callback.is_null());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnBeforeURLRequest"));
return OnBeforeURLRequest(request, callback, new_url);
}
+void NetworkDelegate::NotifyResolveProxy(
+ const GURL& url,
+ int load_flags,
+ const ProxyService& proxy_service,
+ ProxyInfo* result) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(result);
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnResolveProxy"));
+ OnResolveProxy(url, load_flags, proxy_service, result);
+}
+
+void NetworkDelegate::NotifyProxyFallback(
+ const ProxyServer& bad_proxy,
+ int net_error) {
+ DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnProxyFallback"));
+ OnProxyFallback(bad_proxy, net_error);
+}
+
int NetworkDelegate::NotifyBeforeSendHeaders(
URLRequest* request, const CompletionCallback& callback,
HttpRequestHeaders* headers) {
DCHECK(CalledOnValidThread());
DCHECK(headers);
DCHECK(!callback.is_null());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnBeforeSendHeaders"));
return OnBeforeSendHeaders(request, callback, headers);
}
+void NetworkDelegate::NotifyBeforeSendProxyHeaders(
+ URLRequest* request,
+ const ProxyInfo& proxy_info,
+ HttpRequestHeaders* headers) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(headers);
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnBeforeSendProxyHeaders"));
+ OnBeforeSendProxyHeaders(request, proxy_info, headers);
+}
+
void NetworkDelegate::NotifySendHeaders(URLRequest* request,
const HttpRequestHeaders& headers) {
DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnSendHeaders"));
OnSendHeaders(request, headers);
}
@@ -44,6 +96,10 @@ int NetworkDelegate::NotifyHeadersReceived(
DCHECK(CalledOnValidThread());
DCHECK(original_response_headers);
DCHECK(!callback.is_null());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnHeadersReceived"));
return OnHeadersReceived(request,
callback,
original_response_headers,
@@ -54,12 +110,20 @@ int NetworkDelegate::NotifyHeadersReceived(
void NetworkDelegate::NotifyResponseStarted(URLRequest* request) {
DCHECK(CalledOnValidThread());
DCHECK(request);
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnResponseStarted"));
OnResponseStarted(request);
}
void NetworkDelegate::NotifyRawBytesRead(const URLRequest& request,
int bytes_read) {
DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnRawBytesRead"));
OnRawBytesRead(request, bytes_read);
}
@@ -67,24 +131,39 @@ void NetworkDelegate::NotifyBeforeRedirect(URLRequest* request,
const GURL& new_location) {
DCHECK(CalledOnValidThread());
DCHECK(request);
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnBeforeRedirect"));
OnBeforeRedirect(request, new_location);
}
void NetworkDelegate::NotifyCompleted(URLRequest* request, bool started) {
DCHECK(CalledOnValidThread());
DCHECK(request);
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 NetworkDelegate::OnCompleted"));
OnCompleted(request, started);
}
void NetworkDelegate::NotifyURLRequestDestroyed(URLRequest* request) {
DCHECK(CalledOnValidThread());
DCHECK(request);
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnURLRequestDestroyed"));
OnURLRequestDestroyed(request);
}
void NetworkDelegate::NotifyPACScriptError(int line_number,
const base::string16& error) {
DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnPACScriptError"));
OnPACScriptError(line_number, error);
}
@@ -103,6 +182,10 @@ int NetworkDelegate::NotifyBeforeSocketStreamConnect(
DCHECK(CalledOnValidThread());
DCHECK(socket);
DCHECK(!callback.is_null());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnBeforeSocketStreamConnect"));
return OnBeforeSocketStreamConnect(socket, callback);
}
@@ -110,6 +193,10 @@ bool NetworkDelegate::CanGetCookies(const URLRequest& request,
const CookieList& cookie_list) {
DCHECK(CalledOnValidThread());
DCHECK(!(request.load_flags() & net::LOAD_DO_NOT_SEND_COOKIES));
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnCanGetCookies"));
return OnCanGetCookies(request, cookie_list);
}
@@ -118,17 +205,29 @@ bool NetworkDelegate::CanSetCookie(const URLRequest& request,
CookieOptions* options) {
DCHECK(CalledOnValidThread());
DCHECK(!(request.load_flags() & net::LOAD_DO_NOT_SAVE_COOKIES));
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnCanSetCookie"));
return OnCanSetCookie(request, cookie_line, options);
}
bool NetworkDelegate::CanAccessFile(const URLRequest& request,
const base::FilePath& path) const {
DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnCanAccessFile"));
return OnCanAccessFile(request, path);
}
bool NetworkDelegate::CanThrottleRequest(const URLRequest& request) const {
DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnCanThrottleRequest"));
return OnCanThrottleRequest(request);
}
@@ -136,21 +235,55 @@ bool NetworkDelegate::CanEnablePrivacyMode(
const GURL& url,
const GURL& first_party_for_cookies) const {
DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnCanEnablePrivacyMode"));
return OnCanEnablePrivacyMode(url, first_party_for_cookies);
}
+bool NetworkDelegate::CancelURLRequestWithPolicyViolatingReferrerHeader(
+ const URLRequest& request,
+ const GURL& target_url,
+ const GURL& referrer_url) const {
+ DCHECK(CalledOnValidThread());
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 NetworkDelegate::OnCancelURLRequestWithPolicy..."));
+ return OnCancelURLRequestWithPolicyViolatingReferrerHeader(
+ request, target_url, referrer_url);
+}
+
int NetworkDelegate::OnBeforeURLRequest(URLRequest* request,
const CompletionCallback& callback,
GURL* new_url) {
return OK;
}
+void NetworkDelegate::OnResolveProxy(
+ const GURL& url,
+ int load_flags,
+ const ProxyService& proxy_service,
+ ProxyInfo* result) {
+}
+
+void NetworkDelegate::OnProxyFallback(const ProxyServer& bad_proxy,
+ int net_error) {
+}
+
int NetworkDelegate::OnBeforeSendHeaders(URLRequest* request,
const CompletionCallback& callback,
HttpRequestHeaders* headers) {
return OK;
}
+void NetworkDelegate::OnBeforeSendProxyHeaders(
+ URLRequest* request,
+ const ProxyInfo& proxy_info,
+ HttpRequestHeaders* headers) {
+}
+
void NetworkDelegate::OnSendHeaders(URLRequest* request,
const HttpRequestHeaders& headers) {
}
@@ -225,4 +358,11 @@ int NetworkDelegate::OnBeforeSocketStreamConnect(
return OK;
}
+bool NetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
+ const URLRequest& request,
+ const GURL& target_url,
+ const GURL& referrer_url) const {
+ return false;
+}
+
} // namespace net
diff --git a/chromium/net/base/network_delegate.h b/chromium/net/base/network_delegate.h
index 4be320b9305..299989c9dab 100644
--- a/chromium/net/base/network_delegate.h
+++ b/chromium/net/base/network_delegate.h
@@ -35,6 +35,9 @@ namespace net {
class CookieOptions;
class HttpRequestHeaders;
class HttpResponseHeaders;
+class ProxyInfo;
+class ProxyServer;
+class ProxyService;
class SocketStream;
class URLRequest;
@@ -60,9 +63,18 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
int NotifyBeforeURLRequest(URLRequest* request,
const CompletionCallback& callback,
GURL* new_url);
+ void NotifyResolveProxy(const GURL& url,
+ int load_flags,
+ const ProxyService& proxy_service,
+ ProxyInfo* result);
+ void NotifyProxyFallback(const ProxyServer& bad_proxy,
+ int net_error);
int NotifyBeforeSendHeaders(URLRequest* request,
const CompletionCallback& callback,
HttpRequestHeaders* headers);
+ void NotifyBeforeSendProxyHeaders(URLRequest* request,
+ const ProxyInfo& proxy_info,
+ HttpRequestHeaders* headers);
void NotifySendHeaders(URLRequest* request,
const HttpRequestHeaders& headers);
int NotifyHeadersReceived(
@@ -96,6 +108,11 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
int NotifyBeforeSocketStreamConnect(SocketStream* socket,
const CompletionCallback& callback);
+ bool CancelURLRequestWithPolicyViolatingReferrerHeader(
+ const URLRequest& request,
+ const GURL& target_url,
+ const GURL& referrer_url) const;
+
private:
// This is the interface for subclasses of NetworkDelegate to implement. These
// member functions will be called by the respective public notification
@@ -117,6 +134,21 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
const CompletionCallback& callback,
GURL* new_url);
+ // Called as the proxy is being resolved for |url|. Allows the delegate to
+ // override the proxy resolution decision made by ProxyService. The delegate
+ // may override the decision by modifying the ProxyInfo |result|.
+ virtual void OnResolveProxy(const GURL& url,
+ int load_flags,
+ const ProxyService& proxy_service,
+ ProxyInfo* result);
+
+ // Called when use of |bad_proxy| fails due to |net_error|. |net_error| is
+ // the network error encountered, if any, and OK if the fallback was
+ // for a reason other than a network error (e.g. the proxy service was
+ // explicitly directed to skip a proxy).
+ virtual void OnProxyFallback(const ProxyServer& bad_proxy,
+ int net_error);
+
// Called right before the HTTP headers are sent. Allows the delegate to
// read/write |headers| before they get sent out. |callback| and |headers| are
// valid only until OnCompleted or OnURLRequestDestroyed is called for this
@@ -126,6 +158,13 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
const CompletionCallback& callback,
HttpRequestHeaders* headers);
+ // Called after a proxy connection. Allows the delegate to read/write
+ // |headers| before they get sent out. |headers| is valid only until
+ // OnCompleted or OnURLRequestDestroyed is called for this request.
+ virtual void OnBeforeSendProxyHeaders(URLRequest* request,
+ const ProxyInfo& proxy_info,
+ HttpRequestHeaders* headers);
+
// Called right before the HTTP request(s) are being sent to the network.
// |headers| is only valid until OnCompleted or OnURLRequestDestroyed is
// called for this request.
@@ -236,6 +275,16 @@ class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
// See OnBeforeURLRequest for return value description. Returns OK by default.
virtual int OnBeforeSocketStreamConnect(
SocketStream* socket, const CompletionCallback& callback);
+
+ // Called when the |referrer_url| for requesting |target_url| during handling
+ // of the |request| is does not comply with the referrer policy (e.g. a
+ // secure referrer for an insecure initial target).
+ // Returns true if the request should be cancelled. Otherwise, the referrer
+ // header is stripped from the request.
+ virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
+ const URLRequest& request,
+ const GURL& target_url,
+ const GURL& referrer_url) const;
};
} // namespace net
diff --git a/chromium/net/base/openssl_private_key_store_android.cc b/chromium/net/base/openssl_private_key_store_android.cc
index e9851077faa..56a63d23485 100644
--- a/chromium/net/base/openssl_private_key_store_android.cc
+++ b/chromium/net/base/openssl_private_key_store_android.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
#include "net/android/network_library.h"
namespace net {
@@ -29,9 +30,8 @@ bool OpenSSLPrivateKeyStore::StoreKeyPair(const GURL& url,
// in a format that is incompatible with what the platform expects.
unsigned char* private_key = NULL;
int private_len = 0;
- crypto::ScopedOpenSSL<
- PKCS8_PRIV_KEY_INFO,
- PKCS8_PRIV_KEY_INFO_free> pkcs8(EVP_PKEY2PKCS8(pkey));
+ crypto::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type
+ pkcs8(EVP_PKEY2PKCS8(pkey));
if (pkcs8.get() != NULL) {
private_len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &private_key);
}
diff --git a/chromium/net/base/openssl_private_key_store_memory.cc b/chromium/net/base/openssl_private_key_store_memory.cc
index 0913e460bd2..4d6a287c2a7 100644
--- a/chromium/net/base/openssl_private_key_store_memory.cc
+++ b/chromium/net/base/openssl_private_key_store_memory.cc
@@ -36,7 +36,7 @@ class MemoryKeyPairStore {
}
bool StoreKeyPair(EVP_PKEY* pkey) {
- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ EVP_PKEY_dup(pkey);
base::AutoLock lock(lock_);
keys_.push_back(pkey);
return true;
diff --git a/chromium/net/base/prioritized_dispatcher_unittest.cc b/chromium/net/base/prioritized_dispatcher_unittest.cc
index 30360387ab1..40c74257ddc 100644
--- a/chromium/net/base/prioritized_dispatcher_unittest.cc
+++ b/chromium/net/base/prioritized_dispatcher_unittest.cc
@@ -117,7 +117,7 @@ class PrioritizedDispatcherTest : public testing::Test {
}
// PriorityDispatch::Job interface
- virtual void Start() OVERRIDE {
+ void Start() override {
EXPECT_FALSE(running_);
handle_ = PrioritizedDispatcher::Handle();
running_ = true;
diff --git a/chromium/net/base/priority_queue_unittest.cc b/chromium/net/base/priority_queue_unittest.cc
index 8093319fddb..3e68acfb945 100644
--- a/chromium/net/base/priority_queue_unittest.cc
+++ b/chromium/net/base/priority_queue_unittest.cc
@@ -25,7 +25,7 @@ class PriorityQueueTest : public testing::Test {
protected:
PriorityQueueTest() : queue_(kNumPriorities) {}
- virtual void SetUp() OVERRIDE {
+ void SetUp() override {
CheckEmpty();
for (size_t i = 0; i < kNumElements; ++i) {
EXPECT_EQ(i, queue_.size());
diff --git a/chromium/net/base/proxy_delegate.h b/chromium/net/base/proxy_delegate.h
new file mode 100644
index 00000000000..7e00d0ca8c7
--- /dev/null
+++ b/chromium/net/base/proxy_delegate.h
@@ -0,0 +1,76 @@
+// Copyright 2014 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.
+
+#ifndef NET_BASE_PROXY_DELEGATE_H_
+#define NET_BASE_PROXY_DELEGATE_H_
+
+#include "base/macros.h"
+#include "net/base/net_export.h"
+
+class GURL;
+
+namespace net {
+
+class HttpRequestHeaders;
+class HttpResponseHeaders;
+class HostPortPair;
+class ProxyInfo;
+class ProxyServer;
+class ProxyService;
+class URLRequest;
+
+// Delegate for setting up a connection.
+class NET_EXPORT ProxyDelegate {
+ public:
+ ProxyDelegate() {
+ }
+
+ virtual ~ProxyDelegate() {
+ }
+
+ // Called as the proxy is being resolved for |url|. Allows the delegate to
+ // override the proxy resolution decision made by ProxyService. The delegate
+ // may override the decision by modifying the ProxyInfo |result|.
+ virtual void OnResolveProxy(const GURL& url,
+ int load_flags,
+ const ProxyService& proxy_service,
+ ProxyInfo* result) = 0;
+
+ // Called when use of |bad_proxy| fails due to |net_error|. |net_error| is
+ // the network error encountered, if any, and OK if the fallback was
+ // for a reason other than a network error (e.g. the proxy service was
+ // explicitly directed to skip a proxy).
+ virtual void OnFallback(const ProxyServer& bad_proxy,
+ int net_error) = 0;
+
+ // Called after a proxy connection. Allows the delegate to read/write
+ // |headers| before they get sent out. |headers| is valid only until
+ // OnCompleted or OnURLRequestDestroyed is called for this request.
+ virtual void OnBeforeSendHeaders(URLRequest* request,
+ const ProxyInfo& proxy_info,
+ HttpRequestHeaders* headers) = 0;
+
+ // Called immediately before a proxy tunnel request is sent.
+ // Provides the embedder an opportunity to add extra request headers.
+ virtual void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
+ HttpRequestHeaders* extra_headers) = 0;
+
+ // Called when the connect attempt to a CONNECT proxy has completed.
+ virtual void OnTunnelConnectCompleted(const HostPortPair& endpoint,
+ const HostPortPair& proxy_server,
+ int net_error) = 0;
+
+ // Called after the response headers for the tunnel request are received.
+ virtual void OnTunnelHeadersReceived(
+ const HostPortPair& origin,
+ const HostPortPair& proxy_server,
+ const HttpResponseHeaders& response_headers) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProxyDelegate);
+};
+
+}
+
+#endif // NET_BASE_PROXY_DELEGATE_H_
diff --git a/chromium/net/base/registry_controlled_domains/OWNERS b/chromium/net/base/registry_controlled_domains/OWNERS
index 9f8b1799602..2ba05a6168c 100644
--- a/chromium/net/base/registry_controlled_domains/OWNERS
+++ b/chromium/net/base/registry_controlled_domains/OWNERS
@@ -1,2 +1,3 @@
pam@chromium.org
pkasting@chromium.org
+rsleevi@chromium.org
diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
index 4a8664322b8..111ee061c31 100644
--- a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
+++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
@@ -407,7 +407,7 @@ mil.bo
tv.bo
// br : http://registro.br/dominio/categoria.html
-// Submitted by registry <fneves@registro.br> 2014-03-04
+// Submitted by registry <fneves@registro.br> 2014-08-11
br
adm.br
adv.br
@@ -455,7 +455,7 @@ mil.br
mp.br
mus.br
net.br
-nom.br
+*.nom.br
not.br
ntr.br
odo.br
@@ -821,7 +821,14 @@ gob.es
edu.es
// et : http://en.wikipedia.org/wiki/.et
-*.et
+et
+com.et
+gov.et
+org.et
+edu.et
+biz.et
+name.et
+info.et
// eu : http://en.wikipedia.org/wiki/.eu
eu
@@ -1594,7 +1601,7 @@ jobs
// jp : http://en.wikipedia.org/wiki/.jp
// http://jprs.co.jp/en/jpdomain.html
-// Submitted by registry <info@jprs.jp> 2014-02-28
+// Submitted by registry <info@jprs.jp> 2014-10-30
jp
// jp organizational type names
ac.jp
@@ -1606,7 +1613,7 @@ gr.jp
lg.jp
ne.jp
or.jp
-// jp preficture type names
+// jp prefecture type names
aichi.jp
akita.jp
aomori.jp
@@ -1654,6 +1661,53 @@ wakayama.jp
yamagata.jp
yamaguchi.jp
yamanashi.jp
+栃木.jp
+愛知.jp
+愛媛.jp
+兵庫.jp
+熊本.jp
+茨城.jp
+北海道.jp
+千葉.jp
+和歌山.jp
+長崎.jp
+長野.jp
+新潟.jp
+青森.jp
+静岡.jp
+東京.jp
+石川.jp
+埼玉.jp
+三重.jp
+京都.jp
+佐賀.jp
+大分.jp
+大阪.jp
+奈良.jp
+宮城.jp
+宮崎.jp
+富山.jp
+山口.jp
+山形.jp
+山梨.jp
+岩手.jp
+岐阜.jp
+岡山.jp
+島根.jp
+広島.jp
+徳島.jp
+沖縄.jp
+滋賀.jp
+神奈川.jp
+福井.jp
+福岡.jp
+福島.jp
+秋田.jp
+群馬.jp
+香川.jp
+高知.jp
+鳥取.jp
+鹿児島.jp
// jp geographic type names
// http://jprs.jp/doc/rule/saisoku-1.html
*.kawasaki.jp
@@ -5252,27 +5306,30 @@ gop.pk
gos.pk
info.pk
-// pl : http://www.dns.pl/english/
+// pl http://www.dns.pl/english/index.html
+// confirmed on 26.09.2014 from Bogna Tchórzewska <partner@dns.pl>
pl
-// NASK functional domains (nask.pl / dns.pl) : http://www.dns.pl/english/dns-funk.html
+com.pl
+net.pl
+org.pl
+info.pl
+waw.pl
+gov.pl
+// pl functional domains (http://www.dns.pl/english/index.html)
aid.pl
agro.pl
atm.pl
auto.pl
biz.pl
-com.pl
edu.pl
gmina.pl
gsm.pl
-info.pl
mail.pl
miasta.pl
media.pl
mil.pl
-net.pl
nieruchomosci.pl
nom.pl
-org.pl
pc.pl
powiat.pl
priv.pl
@@ -5288,12 +5345,7 @@ tm.pl
tourism.pl
travel.pl
turystyka.pl
-// ICM functional domains (icm.edu.pl)
-6bone.pl
-art.pl
-mbone.pl
// Government domains (administred by ippt.gov.pl)
-gov.pl
uw.gov.pl
um.gov.pl
ug.gov.pl
@@ -5303,11 +5355,7 @@ so.gov.pl
sr.gov.pl
po.gov.pl
pa.gov.pl
-// other functional domains
-ngo.pl
-irc.pl
-usenet.pl
-// NASK geographical domains : http://www.dns.pl/english/dns-regiony.html
+// pl regional domains (http://www.dns.pl/english/index.html)
augustow.pl
babia-gora.pl
bedzin.pl
@@ -5393,7 +5441,6 @@ rybnik.pl
rzeszow.pl
sanok.pl
sejny.pl
-siedlce.pl
slask.pl
slupsk.pl
sosnowiec.pl
@@ -5415,7 +5462,6 @@ ustka.pl
walbrzych.pl
warmia.pl
warszawa.pl
-waw.pl
wegrow.pl
wielun.pl
wlocl.pl
@@ -5428,18 +5474,6 @@ zagan.pl
zarow.pl
zgora.pl
zgorzelec.pl
-// TASK geographical domains (www.task.gda.pl/uslugi/dns)
-gda.pl
-gdansk.pl
-gdynia.pl
-med.pl
-sopot.pl
-// other geographical domains
-gliwice.pl
-krakow.pl
-poznan.pl
-wroc.pl
-zakopane.pl
// pm : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf
pm
@@ -5624,7 +5658,7 @@ mari.ru
mari-el.ru
marine.ru
mordovia.ru
-mosreg.ru
+// mosreg.ru Bug 1090800 - removed at request of Aleksey Konstantinov <konstantinovav@mosreg.ru>
msk.ru
murmansk.ru
nalchik.ru
@@ -6008,11 +6042,35 @@ mil.to
// Submitted by Ryan Sleevi <ryan.sleevi@gmail.com> 2014-01-03
tp
-// tr : http://en.wikipedia.org/wiki/.tr
-*.tr
-!nic.tr
-// Used by government in the TRNC
-// http://en.wikipedia.org/wiki/.nc.tr
+// subTLDs: https://www.nic.tr/forms/eng/policies.pdf
+// and: https://www.nic.tr/forms/politikalar.pdf
+// Submitted by <mehmetgurevin@gmail.com> 2014-07-19
+tr
+com.tr
+info.tr
+biz.tr
+net.tr
+org.tr
+web.tr
+gen.tr
+tv.tr
+av.tr
+dr.tr
+bbs.tr
+name.tr
+tel.tr
+gov.tr
+bel.tr
+pol.tr
+mil.tr
+k12.tr
+edu.tr
+kep.tr
+
+// Used by Northern Cyprus
+nc.tr
+
+// Used by government agencies of Northern Cyprus
gov.nc.tr
// travel : http://en.wikipedia.org/wiki/.travel
@@ -6287,7 +6345,7 @@ k12.mo.us
k12.ms.us
k12.mt.us
k12.nc.us
-k12.nd.us
+// k12.nd.us Bug 1028347 - Removed at request of Travis Rosso <trossow@nd.gov>
k12.ne.us
k12.nh.us
k12.nj.us
@@ -6312,7 +6370,6 @@ k12.wa.us
k12.wi.us
// k12.wv.us Bug 947705 - Removed at request of Verne Britton <verne@wvnet.edu>
k12.wy.us
-
cc.ak.us
cc.al.us
cc.ar.us
@@ -6368,7 +6425,6 @@ cc.wa.us
cc.wi.us
cc.wv.us
cc.wy.us
-
lib.ak.us
lib.al.us
lib.ar.us
@@ -6424,7 +6480,6 @@ lib.wa.us
lib.wi.us
// lib.wv.us Bug 941670 - Removed at request of Larry W Arnold <arnold@wvlc.lib.wv.us>
lib.wy.us
-
// k12.ma.us contains school districts in Massachusetts. The 4LDs are
// managed indepedently except for private (PVT), charter (CHTR) and
// parochial (PAROCH) schools. Those are delegated dorectly to the
@@ -6728,1269 +6783,1726 @@ xxx
*.zw
-// xn--80asehdb : 2013-07-14 CORE Association
-онлайн
+// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2014-11-03T18:02:06Z
-// xn--80aswg : 2013-07-14 CORE Association
-сайт
+// abb : 2014-10-24 ABB Ltd
+abb
-// xn--ngbc5azd : 2013-07-14 International Domain Registry Pty. Ltd.
-شبكة
+// abbott : 2014-07-24 Abbott Laboratories, Inc.
+abbott
-// xn--unup4y : 2013-07-14 Spring Fields, LLC
-游戏
+// abogado : 2014-04-24 Top Level Domain Holdings Limited
+abogado
-// xn--vhquv : 2013-08-28 Dash McCook, LLC
-企业
+// academy : 2013-11-07 Half Oaks, LLC
+academy
-// camera : 2013-08-28 Atomic Maple, LLC
-camera
+// accenture : 2014-08-15 Accenture plc
+accenture
-// clothing : 2013-08-28 Steel Lake, LLC
-clothing
+// accountants : 2014-03-20 Knob Town, LLC
+accountants
-// lighting : 2013-08-28 John McCook, LLC
-lighting
+// active : 2014-05-01 The Active Network, Inc
+active
-// singles : 2013-08-28 Fern Madison, LLC
-singles
+// actor : 2013-12-12 United TLD Holdco Ltd.
+actor
-// ventures : 2013-08-28 Binky Lake, LLC
-ventures
+// adult : 2014-10-16 ICM Registry AD LLC
+adult
-// voyage : 2013-08-28 Ruby House, LLC
-voyage
+// afl : 2014-10-02 Australian Football League
+afl
-// guru : 2013-08-28 Pioneer Cypress, LLC
-guru
+// africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa
+africa
-// holdings : 2013-08-28 John Madison, LLC
-holdings
+// agency : 2013-11-14 Steel Falls, LLC
+agency
-// equipment : 2013-08-28 Corn Station, LLC
-equipment
+// airforce : 2014-03-06 United TLD Holdco Ltd.
+airforce
-// bike : 2013-08-28 Grand Hollow, LLC
-bike
+// airtel : 2014-10-24 Bharti Airtel Limited
+airtel
-// estate : 2013-08-28 Trixy Park, LLC
-estate
+// allfinanz : 2014-07-03 Allfinanz Deutsche Vermögensberatung Aktiengesellschaft
+allfinanz
-// tattoo : 2013-08-30 Uniregistry,Corp.
-tattoo
+// alsace : 2014-07-02 REGION D ALSACE
+alsace
-// xn--3ds443g : 2013-09-09 TLD Registry Limited
-在线
+// amsterdam : 2014-07-24 Gemeente Amsterdam
+amsterdam
-// xn--fiq228c5hs : 2013-09-09 TLD Registry Limited
-中文网
+// android : 2014-08-07 Charleston Road Registry Inc.
+android
-// land : 2013-09-10 Pine Moon, LLC
-land
+// aquarelle : 2014-07-24 Aquarelle.com
+aquarelle
-// plumbing : 2013-09-10 Spring Tigers, LLC
-plumbing
+// archi : 2014-02-06 STARTING DOT LIMITED
+archi
-// contractors : 2013-09-10 Magic Woods, LLC
-contractors
+// army : 2014-03-06 United TLD Holdco Ltd.
+army
-// sexy : 2013-09-11 Uniregistry,Corp.
-sexy
+// associates : 2014-03-06 Baxter Hill, LLC
+associates
-// menu : 2013-09-11 Wedding TLD2, LLC
-menu
+// attorney : 2014-03-20
+attorney
-// xn--rhqv96g : 2013-09-11 Stable Tone Limited
-世界
+// auction : 2014-03-20
+auction
-// uno : 2013-09-11 Dot Latin, LLC
-uno
+// audio : 2014-03-20 Uniregistry, Corp.
+audio
-// gallery : 2013-09-13 Sugar House, LLC
-gallery
+// autos : 2014-01-09 DERAutos, LLC
+autos
-// technology : 2013-09-13 Auburn Falls
-technology
+// axa : 2013-12-19 AXA SA
+axa
-// xn--3bst00m : 2013-09-13 Eagle Horizon Limited
-集团
+// band : 2014-06-12
+band
-// reviews : 2013-09-13 Extra Cover, LLC
-reviews
+// bank : 2014-09-25 fTLD Registry Services LLC
+bank
-// guide : 2013-09-13 Snow Moon, LLC
-guide
+// bar : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+bar
-// xn--6qq986b3x1 : 2013-09-13 Tycoon Treasure Limited
-我爱你
+// barcelona : 2014-07-24 Municipi de Barcelona
+barcelona
-// graphics : 2013-09-13 Over Madison, LLC
-graphics
+// bargains : 2013-11-14 Half Hallow, LLC
+bargains
-// construction : 2013-09-13 Fox Dynamite, LLC
-construction
+// bauhaus : 2014-04-17 Werkhaus GmbH
+bauhaus
-// onl : 2013-09-16 I-Registry Ltd.
-onl
+// bayern : 2014-01-23 Bayern Connect GmbH
+bayern
-// xn--q9jyb4c : 2013-09-17 Charleston Road Registry
-みんな
+// bbva : 2014-10-02 BANCO BILBAO VIZCAYA ARGENTARIA, S.A.
+bbva
-// diamonds : 2013-09-23 John Edge, LLC
-diamonds
+// bcn : 2014-07-24 Municipi de Barcelona
+bcn
-// kiwi : 2013-09-23 Dot Kiwi Limited
-kiwi
+// beer : 2014-01-09 Top Level Domain Holdings Limited
+beer
-// enterprises : 2013-09-23 Snow Oaks LLC
-enterprises
+// berlin : 2013-10-31 dotBERLIN GmbH & Co. KG
+berlin
-// today : 2013-09-23 Pearl Woods, LLC
-today
+// best : 2013-12-19 BestTLD Pty Ltd
+best
-// futbol : 2013-09-23 Atomic Falls, LLC
-futbol
+// bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited
+bharti
-// photography : 2013-09-23 Sugar Glen, LLC
-photography
+// bible : 2014-06-19 American Bible Society
+bible
-// tips : 2013-09-23 Corn Willow, LLC
-tips
+// bid : 2013-12-19 dot Bid Limited
+bid
-// directory : 2013-09-23 Extra Madison, LLC
-directory
+// bike : 2013-08-27 Grand Hollow, LLC
+bike
-// kitchen : 2013-09-23 Just Goodbye, LLC
-kitchen
+// bio : 2014-03-06 STARTING DOT LIMITED
+bio
-// xn--6frz82g : 2013-09-24 Afilias Limited
-移动
+// black : 2014-01-16 Afilias Limited
+black
-// kim : 2013-09-24 Afilias Limited
-kim
+// blackfriday : 2014-01-16 Uniregistry, Corp.
+blackfriday
-// xn--cg4bki : 2013-09-27 Samsung SDS Co., LTD
-삼성
+// bloomberg : 2014-07-17 Bloomberg IP Holdings LLC
+bloomberg
-// monash : 2013-10-01 Monash University
-monash
+// blue : 2013-11-07 Afilias Limited
+blue
-// wed : 2013-10-02 Atgron, Inc.
-wed
+// bms : 2014-10-30 Bristol-Myers Squibb Company
+bms
-// pink : 2013-10-02 Afilias Limited
-pink
+// bmw : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
+bmw
-// ruhr : 2013-10-02 regiodot GmbH & Co. KG
-ruhr
+// bnl : 2014-07-24 Banca Nazionale del Lavoro
+bnl
-// buzz : 2013-10-03 DOTSTRATEGY CO.
-buzz
+// bnpparibas : 2014-05-29 BNP Paribas
+bnpparibas
-// careers : 2013-10-03 Wild Corner, LLC
-careers
+// bom : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+bom
-// shoes : 2013-10-03 Binky Galley, LLC
-shoes
+// bond : 2014-06-05 Bond University Limited
+bond
-// xn--4gbrim : 2013-10-07 Suhub Electronic Establishment
-موقع
+// boo : 2014-01-30 Charleston Road Registry Inc.
+boo
-// career : 2013-10-09 dotCareer, LLC
-career
+// boutique : 2013-11-14 Over Galley, LLC
+boutique
-// otsuka : 2013-10-11 Otsuka Holdings Co. Ltd.
-otsuka
+// brussels : 2014-02-06 DNS.be vzw
+brussels
-// xn--fiQ64b : 2013-10-14 CITIC Group Corporation
-中信
+// budapest : 2013-11-21 Top Level Domain Holdings Limited
+budapest
-// gift : 2013-10-18 Uniregistry Corp.
-gift
+// build : 2013-11-07 Plan Bee LLC
+build
-// recipes : 2013-10-18 Grand Island, LLC
-recipes
+// builders : 2013-11-07 Atomic Madison, LLC
+builders
-// coffee : 2013-10-18 Trixy Cover, LLC
-coffee
+// business : 2013-11-07 Spring Cross, LLC
+business
-// luxury : 2013-10-18 Luxury Partners, LLC
-luxury
+// buzz : 2013-10-02 DOTSTRATEGY CO.
+buzz
-// domains : 2013-10-18 Sugar Cross, LLC
-domains
+// bzh : 2014-02-27 Association www.bzh
+bzh
-// photos : 2013-10-18 Sea Corner, LLC
-photos
+// cab : 2013-10-24 Half Sunset, LLC
+cab
-// limo : 2013-10-18 Hidden Frostbite, LLC
-limo
+// cal : 2014-07-24 Charleston Road Registry Inc.
+cal
-// viajes : 2013-10-18 Black Madison, LLC
-viajes
+// camera : 2013-08-27 Atomic Maple, LLC
+camera
-// wang : 2013-10-24 Zodiac Leo Limited
-wang
+// camp : 2013-11-07 Delta Dynamite, LLC
+camp
-// democrat : 2013-10-24 United TLD Holdco Ltd.
-democrat
+// cancerresearch : 2014-05-15 Australian Cancer Research Foundation
+cancerresearch
-// mango : 2013-10-25 PUNTO FA S.L.
-mango
+// canon : 2014-09-12 Canon Inc.
+canon
-// cab : 2013-10-25 Half Sunset, LLC
-cab
+// capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+capetown
-// support : 2013-10-25 Grand Orchard, LLC
-support
+// capital : 2014-03-06 Delta Mill, LLC
+capital
-// dance : 2013-10-25 United TLD Holdco Ltd.
-dance
+// caravan : 2013-12-12 Caravan International, Inc.
+caravan
-// nagoya : 2013-10-25 GMO Registry, Inc.
-nagoya
+// cards : 2013-12-05 Foggy Hollow, LLC
+cards
-// computer : 2013-10-25 Pine Mill, LLC
-computer
+// care : 2014-03-06 Goose Cross
+care
-// wien : 2013-10-28 punkt.wien GmbH
-wien
+// career : 2013-10-09 dotCareer LLC
+career
-// berlin : 2013-10-31 dotBERLIN GmbH & Co. KG
-berlin
+// careers : 2013-10-02 Wild Corner, LLC
+careers
-// codes : 2013-10-31 Puff Willow, LLC
-codes
+// cartier : 2014-06-23 Richemont DNS Inc.
+cartier
-// email : 2013-10-31 Spring Madison, LLC
-email
+// casa : 2013-11-21 Top Level Domain Holdings Limited
+casa
-// xn--mgbab2bd : 2013-10-31 CORE Association
-بازار
+// cash : 2014-03-06 Delta Lake, LLC
+cash
-// repair : 2013-11-07 Lone Sunset, LLC
-repair
+// catering : 2013-12-05 New Falls. LLC
+catering
-// holiday : 2013-11-07 Goose Woods, LLC
-holiday
+// cba : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+cba
+
+// cbn : 2014-08-22 The Christian Broadcasting Network, Inc.
+cbn
// center : 2013-11-07 Tin Mill, LLC
center
-// systems : 2013-11-07 Dash Cypress, LLC
-systems
-
-// wiki : 2013-11-07 Top Level Design, LLC
-wiki
-
// ceo : 2013-11-07 CEOTLD Pty Ltd
ceo
-// international : 2013-11-07 Wild Way, LLC
-international
+// cern : 2014-06-05 European Organization for Nuclear Research (\
+cern
-// solar : 2013-11-07 Ruby Town, LLC
-solar
+// cfa : 2014-08-28 CFA Institute
+cfa
+
+// channel : 2014-05-08 Charleston Road Registry Inc.
+channel
+
+// cheap : 2013-11-14 Sand Cover, LLC
+cheap
+
+// chloe : 2014-10-16 Richemont DNS Inc.
+chloe
+
+// christmas : 2013-11-21 Uniregistry, Corp.
+christmas
+
+// chrome : 2014-07-24 Charleston Road Registry Inc.
+chrome
+
+// church : 2014-02-06 Holly Fileds, LLC
+church
+
+// citic : 2014-01-09 CITIC Group Corporation
+citic
+
+// city : 2014-05-29 Snow Sky, LLC
+city
+
+// claims : 2014-03-20 Black Corner, LLC
+claims
+
+// cleaning : 2013-12-05 Fox Shadow, LLC
+cleaning
+
+// click : 2014-06-05 Uniregistry, Corp.
+click
+
+// clinic : 2014-03-20 Goose Park, LLC
+clinic
+
+// clothing : 2013-08-27 Steel Lake, LLC
+clothing
+
+// club : 2013-11-08 .CLUB DOMAINS, LLC
+club
+
+// coach : 2014-10-09 Koko Island, LLC
+coach
+
+// codes : 2013-10-31 Puff Willow, LLC
+codes
+
+// coffee : 2013-10-17 Trixy Cover, LLC
+coffee
+
+// college : 2014-01-16 XYZ.COM LLC
+college
+
+// cologne : 2014-02-05 NetCologne Gesellschaft für Telekommunikation mbH
+cologne
+
+// commbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+commbank
+
+// community : 2013-12-05 Fox Orchard, LLC
+community
// company : 2013-11-07 Silver Avenue, LLC
company
-// education : 2013-11-07 Brice Way, LLC
-education
-
-// training : 2013-11-07 Wild Willow, LLC
-training
+// computer : 2013-10-24 Pine Mill, LLC
+computer
-// academy : 2013-11-07 Half Oaks, LLC
-academy
+// condos : 2013-12-05 Pine House, LLC
+condos
-// marketing : 2013-11-07 Fern Pass, LLC
-marketing
+// construction : 2013-09-16 Fox Dynamite, LLC
+construction
-// florist : 2013-11-08 Half Cypress, LLC
-florist
+// consulting : 2013-12-05
+consulting
-// solutions : 2013-11-07 Silver Cover, LLC
-solutions
+// contractors : 2013-09-10 Magic Woods, LLC
+contractors
-// build : 2013-11-07 Plan Bee LLC
-build
+// cooking : 2013-11-21 Top Level Domain Holdings Limited
+cooking
-// institute : 2013-11-07 Outer Maple, LLC
-institute
+// cool : 2013-11-14 Koko Lake, LLC
+cool
-// builders : 2013-11-07 Atomic Madison, LLC
-builders
+// corsica : 2014-09-25 Collectivité Territoriale de Corse
+corsica
-// red : 2013-11-07 Afilias Limited
-red
+// country : 2013-12-19 Top Level Domain Holdings Limited
+country
-// blue : 2013-11-07 Afilias Limited
-blue
+// credit : 2014-03-20 Snow Shadow, LLC
+credit
-// ninja : 2013-11-07 United TLD Holdco Ltd.
-ninja
+// creditcard : 2014-03-20 Binky Frostbite, LLC
+creditcard
-// business : 2013-11-07 Spring Cross, LLC
-business
+// cricket : 2014-10-09 dot Cricket Limited
+cricket
-// gal : 2013-11-07 Asociación puntoGAL
-gal
+// crown : 2014-10-24 Crown Equipment Corporation
+crown
-// social : 2013-11-07 United TLD Holdco Ltd.
-social
+// crs : 2014-04-03 Federated Co-operatives Limited
+crs
-// house : 2013-11-07 Sugar Park, LLC
-house
+// cruises : 2013-12-05 Spring Way, LLC
+cruises
-// camp : 2013-11-07 Delta Dynamite, LLC
-camp
+// csc : 2014-09-25 Alliance-One Services, Inc.
+csc
-// immobilien : 2013-11-07 United TLD Holdco Ltd.
-immobilien
+// cuisinella : 2014-04-03 SALM S.A.S.
+cuisinella
-// moda : 2013-11-07 United TLD Holdco Ltd.
-moda
+// cymru : 2014-05-08 Nominet UK
+cymru
-// glass : 2013-11-07 Black Cover, LLC
-glass
+// dabur : 2014-02-06 Dabur India Limited
+dabur
-// management : 2013-11-07 John Goodbye, LLC
-management
+// dad : 2014-01-23 Charleston Road Registry Inc.
+dad
-// kaufen : 2013-11-07 United TLD Holdco Ltd.
-kaufen
+// dance : 2013-10-24 United TLD Holdco Ltd.
+dance
-// farm : 2013-11-07 Just Maple, LLC
-farm
+// dating : 2013-12-05 Pine Fest, LLC
+dating
-// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center
-公益
+// datsun : 2014-03-27 NISSAN MOTOR CO., LTD.
+datsun
-// xn--zfr164b : 2013-11-08 China Organizational Name Administration Center
-政务
+// day : 2014-01-30 Charleston Road Registry Inc.
+day
-// club : 2013-11-08 .CLUB DOMAINS, LLC
-club
+// deals : 2014-05-22 Sand Sunset, LLC
+deals
-// voting : 2013-11-13 Valuetainment Corp.
-voting
+// degree : 2014-03-06
+degree
-// TOKYO : 2013-11-13 GMO Registry, Inc.
-tokyo
+// delivery : 2014-09-11 Steel Station, LLC
+delivery
-// moe : 2013-11-13 Interlink Co., Ltd.
-moe
+// dell : 2014-10-24 Dell Inc.
+dell
-// guitars : 2013-11-14 Uniregistry, Corp.
-guitars
+// democrat : 2013-10-24 United TLD Holdco Ltd.
+democrat
-// bargains : 2013-11-14 Half Hallow, LLC
-bargains
+// dental : 2014-03-20 Tin Birch, LLC
+dental
-// xn--nqv7fs00ema : 2013-11-14 Public Interest Registry
-组织机构
+// dentist : 2014-03-20
+dentist
// desi : 2013-11-14 Desi Networks LLC
desi
-// cool : 2013-11-14 Koko Lake, LLC
-cool
+// dev : 2014-10-16 Charleston Road Registry Inc.
+dev
-// boutique : 2013-11-14 Over Galley, LLC
-boutique
+// diamonds : 2013-09-22 John Edge, LLC
+diamonds
-// pics : 2013-11-14 Uniregistry, Corp.
-pics
+// diet : 2014-06-26 Uniregistry, Corp.
+diet
-// xn--c1avg : 2013-11-14 Public Interest Registry
-орг
+// digital : 2014-03-06 Dash Park, LLC
+digital
-// xn--55qx5d : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
-公司
+// direct : 2014-04-10 Half Trail, LLC
+direct
-// xn--io0a7i : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
-网络
+// directory : 2013-09-20 Extra Madison, LLC
+directory
-// cheap : 2013-11-14 Sand Cover, LLC
-cheap
+// discount : 2014-03-06 Holly Hill, LLC
+discount
-// xn--xhq521b : 2013-11-14 Guangzhou YU Wei Information Technology Co., Ltd.
-广东
+// dnp : 2013-12-13 Dai Nippon Printing Co., Ltd.
+dnp
-// photo : 2013-11-14 Uniregistry, Corp.
-photo
+// docs : 2014-10-16 Charleston Road Registry Inc.
+docs
-// network : 2013-11-14 Trixy Manor, LLC
-network
+// doha : 2014-09-18 Communications Regulatory Authority (CRA)
+doha
-// zone : 2013-11-14 Outer Falls, LLC
-zone
+// domains : 2013-10-17 Sugar Cross, LLC
+domains
-// xn--nqv7f : 2013-11-14 Public Interest Registry
-机构
+// doosan : 2014-04-03 Doosan Corporation
+doosan
-// link : 2013-11-14 Uniregistry, Corp.
-link
+// durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+durban
-// QPON : 2013-11-14 dotCOOL, Inc.
-qpon
+// dvag : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+dvag
-// xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry
-संगठन
+// eat : 2014-01-23 Charleston Road Registry Inc.
+eat
-// agency : 2013-11-14 Steel Falls, LLC
-agency
+// education : 2013-11-07 Brice Way, LLC
+education
-// tienda : 2013-11-14 Victor Manor, LLC
-tienda
+// email : 2013-10-31 Spring Madison, LLC
+email
-// works : 2013-11-14 Little Dynamite, LLC
-works
+// emerck : 2014-04-03 Merck KGaA
+emerck
-// london : 2013-11-14 Dot London Domains Limited
-london
+// energy : 2014-09-11 Binky Birch, LLC
+energy
-// watch : 2013-11-14 Sand Shadow, LLC
-watch
+// engineer : 2014-03-06 United TLD Holdco Ltd.
+engineer
-// rocks : 2013-11-14 Ruby Moon, LLC
-rocks
+// engineering : 2014-03-06 Romeo Canyon
+engineering
-// SHIKSHA : 2013-11-14 Afilias Limited
-shiksha
+// enterprises : 2013-09-20 Snow Oaks, LLC
+enterprises
-// xn--d1acj3b : 2013-11-21 The Foundation for Network Initiatives “The Smart Internet”
-дети
+// equipment : 2013-08-27 Corn Station, LLC
+equipment
-// budapest : 2013-11-21 Top Level Domain Holdings Limited
-budapest
+// erni : 2014-04-03 ERNI Group Holding AG
+erni
-// nrw : 2013-11-21 Minds + Machines GmbH
-nrw
+// esq : 2014-05-08 Charleston Road Registry Inc.
+esq
-// VOTE : 2013-11-21 Monolith Registry LLC
-vote
+// estate : 2013-08-27 Trixy Park, LLC
+estate
-// fishing : 2013-11-21 Top Level Domain Holdings Limited
-fishing
+// eurovision : 2014-04-24 European Broadcasting Union (EBU)
+eurovision
+
+// eus : 2013-12-12 Puntueus Fundazioa
+eus
+
+// events : 2013-12-05 Pioneer Maple, LLC
+events
+
+// everbank : 2014-05-15 EverBank
+everbank
+
+// exchange : 2014-03-06 Spring Falls, LLC
+exchange
// expert : 2013-11-21 Magic Pass, LLC
expert
-// horse : 2013-11-21 Top Level Domain Holdings Limited
-horse
+// exposed : 2013-12-05 Victor Beach, LLC
+exposed
-// christmas : 2013-11-21 Uniregistry, Corp.
-christmas
+// fail : 2014-03-06 Atomic Pipe, LLC
+fail
-// cooking : 2013-11-21 Top Level Domain Holdings Limited
-cooking
+// fan : 2014-03-06
+fan
-// xn--czru2d : 2013-11-21 Zodiac Capricorn Limited
-商城
+// farm : 2013-11-07 Just Maple, LLC
+farm
-// casa : 2013-11-21 Top Level Domain Holdings Limited
-casa
+// fashion : 2014-07-03 Top Level Domain Holdings Limited
+fashion
-// rich : 2013-11-21 I-REGISTRY Ltd., Niederlassung Deutschland
-rich
+// feedback : 2013-12-19 Top Level Spectrum, Inc.
+feedback
-// VOTO : 2013-11-21 Monolith Registry LLC
-voto
+// final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+final
-// tools : 2013-11-21 Pioneer North, LLC
-tools
+// finance : 2014-03-20 Cotton Cypress, LLC
+finance
-// xn--45q11c : 2013-11-21 Zodiac Scorpio Limited
-八卦
+// financial : 2014-03-06 Just Cover, LLC
+financial
-// praxi : 2013-12-05 Praxi S.p.A.
-praxi
+// firmdale : 2014-03-27 Firmdale Holdings Limited
+firmdale
-// events : 2013-12-05 Pioneer Maple, LLC
-events
+// fish : 2013-12-12 Fox Woods, LLC
+fish
+
+// fishing : 2013-11-21 Top Level Domain Holdings Limited
+fishing
+
+// fitness : 2014-03-06 Brice Orchard, LLC
+fitness
// flights : 2013-12-05 Fox Station, LLC
flights
-// report : 2013-12-05 Binky Glen, LLC
-report
+// florist : 2013-11-07 Half Cypress, LLC
+florist
-// partners : 2013-12-05 Magic Glen, LLC
-partners
+// flowers : 2014-10-09 Uniregistry, Corp.
+flowers
-// neustar : 2013-12-05 NeuStar, Inc.
-neustar
+// flsmidth : 2014-07-24 FLSmidth A/S
+flsmidth
-// rentals : 2013-12-05 Big Hollow,LLC
-rentals
+// fly : 2014-05-08 Charleston Road Registry Inc.
+fly
-// catering : 2013-12-05 New Falls. LLC
-catering
+// foo : 2014-01-23 Charleston Road Registry Inc.
+foo
-// community : 2013-12-05 Fox Orchard, LLC
-community
+// forsale : 2014-05-22
+forsale
-// maison : 2013-12-05 Victor Frostbite, LLC
-maison
+// foundation : 2013-12-05 John Dale, LLC
+foundation
-// parts : 2013-12-05 Sea Goodbye, LLC
-parts
+// frl : 2014-05-15 FRLregistry B.V.
+frl
-// cleaning : 2013-12-05 Fox Shadow, LLC
-cleaning
+// frogans : 2013-12-19 OP3FT
+frogans
-// okinawa : 2013-12-05 BusinessRalliart inc.
-okinawa
+// fund : 2014-03-20 John Castle, LLC
+fund
-// foundation : 2013-12-05 John Dale, LLC
-foundation
+// furniture : 2014-03-20 Lone Fields, LLC
+furniture
-// properties : 2013-12-05 Big Pass, LLC
-properties
+// futbol : 2013-09-20
+futbol
-// vacations : 2013-12-05 Atomic Tigers, LLC
-vacations
+// gal : 2013-11-07 Asociación puntoGAL
+gal
-// productions : 2013-12-05 Magic Birch, LLC
-productions
+// gallery : 2013-09-13 Sugar House, LLC
+gallery
-// industries : 2013-12-05 Outer House, LLC
-industries
+// garden : 2014-06-26 Top Level Domain Holdings Limited
+garden
+
+// gbiz : 2014-07-17 Charleston Road Registry Inc.
+gbiz
+
+// gdn : 2014-07-31 Joint Stock Company \
+gdn
+
+// gent : 2014-01-23 COMBELL GROUP NV/SA
+gent
+
+// ggee : 2014-01-09 GMO Internet, Inc.
+ggee
+
+// gift : 2013-10-17 Uniregistry, Corp.
+gift
+
+// gifts : 2014-07-03 Goose Sky, LLC
+gifts
+
+// gives : 2014-03-06 United TLD Holdco Ltd.
+gives
+
+// glass : 2013-11-07 Black Cover, LLC
+glass
+
+// gle : 2014-07-24 Charleston Road Registry Inc.
+gle
+
+// global : 2014-04-17 Dot GLOBAL AS
+global
+
+// globo : 2013-12-19 Globo Comunicação e Participações S.A
+globo
+
+// gmail : 2014-05-01 Charleston Road Registry Inc.
+gmail
-// haus : 2013-12-05 Pixie Edge, LLC
+// gmo : 2014-01-09 GMO Internet, Inc.
+gmo
+
+// gmx : 2014-04-24 1&1 Mail & Media GmbH
+gmx
+
+// google : 2014-07-24 Charleston Road Registry Inc.
+google
+
+// gop : 2014-01-16 Republican State Leadership Committee, Inc.
+gop
+
+// graphics : 2013-09-13 Over Madison, LLC
+graphics
+
+// gratis : 2014-03-20 Pioneer Tigers, LLC
+gratis
+
+// green : 2014-05-08 Afilias Limited
+green
+
+// gripe : 2014-03-06 Corn Sunset, LLC
+gripe
+
+// group : 2014-08-15 Romeo Town, LLC
+group
+
+// guge : 2014-08-28 Charleston Road Registry Inc.
+guge
+
+// guide : 2013-09-13 Snow Moon, LLC
+guide
+
+// guitars : 2013-11-14 Uniregistry, Corp.
+guitars
+
+// guru : 2013-08-27 Pioneer Cypress, LLC
+guru
+
+// hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH
+hamburg
+
+// haus : 2013-12-05
haus
-// vision : 2013-12-05 Koko Station, LLC
-vision
+// healthcare : 2014-06-12 Silver Glen, LLC
+healthcare
-// mormon : 2013-12-05 IRI Domain Management, LLC (""Applicant"")
-mormon
+// help : 2014-06-26 Uniregistry, Corp.
+help
-// cards : 2013-12-05 Foggy Hollow, LLC
-cards
+// here : 2014-02-06 Charleston Road Registry Inc.
+here
+
+// hermes : 2014-07-10 HERMES INTERNATIONAL
+hermes
+
+// hiphop : 2014-03-06 Uniregistry, Corp.
+hiphop
+
+// hitachi : 2014-10-31 Hitachi, Ltd.
+hitachi
+
+// hiv : 2014-03-13 dotHIV gemeinnuetziger e.V.
+hiv
+
+// holdings : 2013-08-27 John Madison, LLC
+holdings
+
+// holiday : 2013-11-07 Goose Woods, LLC
+holiday
+
+// homes : 2014-01-09 DERHomes, LLC
+homes
+
+// horse : 2013-11-21 Top Level Domain Holdings Limited
+horse
+
+// host : 2014-04-17 DotHost Inc.
+host
+
+// hosting : 2014-05-29 Uniregistry, Corp.
+hosting
+
+// house : 2013-11-07 Sugar Park, LLC
+house
+
+// how : 2014-01-23 Charleston Road Registry Inc.
+how
+
+// hsbc : 2014-10-24 HSBC Holdings PLC
+hsbc
+
+// ibm : 2014-07-31 International Business Machines Corporation
+ibm
+
+// ice : 2014-10-30 IntercontinentalExchange, Inc.
+ice
+
+// ifm : 2014-01-30 ifm electronic gmbh
+ifm
+
+// iinet : 2014-07-03 Connect West Pty. Ltd.
+iinet
+
+// immo : 2014-07-10 Auburn Bloom, LLC
+immo
+
+// immobilien : 2013-11-07 United TLD Holdco Ltd.
+immobilien
+
+// industries : 2013-12-05 Outer House, LLC
+industries
+
+// infiniti : 2014-03-27 NISSAN MOTOR CO., LTD.
+infiniti
+
+// ing : 2014-01-23 Charleston Road Registry Inc.
+ing
// ink : 2013-12-05 Top Level Design, LLC
ink
-// villas : 2013-12-05 New Sky, LLC
-villas
+// institute : 2013-11-07 Outer Maple, LLC
+institute
-// consulting : 2013-12-05 Pixie Station, LLC
-consulting
+// insure : 2014-03-20 Pioneer Willow, LLC
+insure
-// cruises : 2013-12-05 Spring Way, LLC
-cruises
+// international : 2013-11-07 Wild Way, LLC
+international
-// krd : 2013-12-05 KRG Department of Information Technology
-krd
+// investments : 2014-03-20 Holly Glen, LLC
+investments
-// xyz : 2013-12-05 XYZ.COM LLC
-xyz
+// ipiranga : 2014-08-28 Ipiranga Produtos de Petroleo S.A.
+ipiranga
-// dating : 2013-12-05 Pine Fest, LLC
-dating
+// irish : 2014-08-07 Dot-Irish LLC
+irish
-// exposed : 2013-12-05 Victor Beach, LLC
-exposed
+// ist : 2014-08-28 Istanbul Metropolitan Municipality
+ist
-// condos : 2013-12-05 Pine House, LLC
-condos
+// istanbul : 2014-08-28 Istanbul Metropolitan Municipality
+istanbul
-// eus : 2013-12-12 Puntueus Fundazioa
-eus
+// itau : 2014-10-02 Itau Unibanco Holding S.A.
+itau
-// Caravan : 2013-12-12 Caravan International, Inc.
-caravan
+// iwc : 2014-06-23 Richemont DNS Inc.
+iwc
-// actor : 2013-12-12 United TLD Holdco Ltd.
-actor
+// java : 2014-06-19 Oracle Corporation
+java
-// saarland : 2013-12-12 dotSaarland GmbH
-saarland
+// jetzt : 2014-01-09 New TLD Company AB
+jetzt
-// yokohama : 2013-12-12 GMO Registry, Inc.
-yokohama
+// joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+joburg
-// pub : 2013-12-12 United TLD Holdco Ltd.
-pub
+// jprs : 2014-09-18 Japan Registry Services Co., Ltd.
+jprs
-// xn--p1acf : 2013-12-12 Rusnames Limited
-рус
+// juegos : 2014-03-20 Uniregistry, Corp.
+juegos
-// ren : 2013-12-12 Beijing Qianxiang Wangjing Technology Development Co., Ltd.
-ren
+// kaufen : 2013-11-07 United TLD Holdco Ltd.
+kaufen
-// fish : 2013-12-12 Fox Woods, LLC
-fish
+// kddi : 2014-09-12 KDDI CORPORATION
+kddi
-// BAR : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
-bar
+// kim : 2013-09-23 Afilias Limited
+kim
-// DNP : 2013-12-13 Dai Nippon Printing Co., Ltd.
-dnp
+// kitchen : 2013-09-20 Just Goodbye, LLC
+kitchen
-// bid : 2013-12-19 dot Bid Limited
-bid
+// kiwi : 2013-09-20 DOT KIWI LIMITED
+kiwi
-// supply : 2013-12-19 Half Falls, LLC
-supply
+// koeln : 2014-01-09 NetCologne Gesellschaft für Telekommunikation mbH
+koeln
-// Miami : 2013-12-19 Top Level Domain Holdings Limited
-miami
+// krd : 2013-12-05 KRG Department of Information Technology
+krd
-// supplies : 2013-12-19 Atomic Fields, LLC
-supplies
+// kred : 2013-12-19 KredTLD Pty Ltd
+kred
-// quebec : 2013-12-19 PointQuébec Inc
-quebec
+// lacaixa : 2014-01-09 CAIXA D'ESTALVIS I PENSIONS DE BARCELONA
+lacaixa
-// MOSCOW : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
-moscow
+// land : 2013-09-10 Pine Moon, LLC
+land
-// globo : 2013-12-19 Globo Comunicação e Participações S.A
-globo
+// lat : 2014-10-16 ECOM-LAC Federaciòn de Latinoamèrica y el Caribe para Internet y el Comercio Electrònico
+lat
-// AXA : 2013-12-19 AXA SA
-axa
+// latrobe : 2014-06-16 La Trobe University
+latrobe
-// xn--80adxhks : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
-москва
+// lawyer : 2014-03-20
+lawyer
-// xn--czrs0t : 2013-12-19 Wild Island, LLC
-商店
+// lds : 2014-03-20 IRI Domain Management, LLC (\
+lds
-// vodka : 2013-12-19 Top Level Domain Holdings Limited
-vodka
+// lease : 2014-03-06 Victor Trail, LLC
+lease
-// REST : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
-rest
+// leclerc : 2014-08-07 A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc
+leclerc
-// frogans : 2013-12-19 OP3FT
-frogans
+// legal : 2014-10-16 Blue Falls, LLC
+legal
-// WTC : 2013-12-19 World Trade Centers Association, Inc.
-wtc
+// lgbt : 2014-05-08 Afilias Limited
+lgbt
-// rodeo : 2013-12-19 Top Level Domain Holdings Limited
-rodeo
+// liaison : 2014-10-02 Liaison Technologies, Incorporated
+liaison
-// sohu : 2013-12-19 Sohu.com Limited
-sohu
+// lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+lidl
-// BEST : 2013-12-19 BestTLD Pty Ltd
-best
+// life : 2014-02-06 Trixy Oaks, LLC
+life
-// country : 2013-12-19 Top Level Domain Holdings Limited
-country
+// lighting : 2013-08-27 John McCook, LLC
+lighting
-// KRED : 2013-12-19 KredTLD Pty Ltd
-kred
+// limited : 2014-03-06 Big Fest, LLC
+limited
-// feedback : 2013-12-19 Top Level Spectrum, Inc.
-feedback
+// limo : 2013-10-17 Hidden Frostbite, LLC
+limo
-// work : 2013-12-19 Top Level Domain Holdings Limited
-work
+// link : 2013-11-14 Uniregistry, Corp.
+link
+
+// loans : 2014-03-20 June Woods, LLC
+loans
+
+// london : 2013-11-14 Dot London Domains Limited
+london
+
+// lotto : 2014-04-10 Afilias Limited
+lotto
+
+// ltd : 2014-09-25 Over Corner, LLC
+ltd
+
+// ltda : 2014-04-17 DOMAIN ROBOT SERVICOS DE HOSPEDAGEM NA INTERNET LTDA
+ltda
// luxe : 2014-01-09 Top Level Domain Holdings Limited
luxe
-// ryukyu : 2014-01-09 BusinessRalliart inc.
-ryukyu
+// luxury : 2013-10-17 Luxury Partners, LLC
+luxury
-// autos : 2014-01-09 DERAutos, LLC
-autos
+// madrid : 2014-05-01 Comunidad de Madrid
+madrid
-// homes : 2014-01-09 DERHomes, LLC
-homes
+// maif : 2014-10-02 Mutuelle Assurance Instituteur France (MAIF)
+maif
-// jetzt : 2014-01-09 New TLD Company AB
-jetzt
+// maison : 2013-12-05 Victor Frostbite, LLC
+maison
-// yachts : 2014-01-09 DERYachts, LLC
-yachts
+// management : 2013-11-07 John Goodbye, LLC
+management
-// motorcycles : 2014-01-09 DERMotorcycles, LLC
-motorcycles
+// mango : 2013-10-24 PUNTO FA S.L.
+mango
+
+// market : 2014-03-06
+market
+
+// marketing : 2013-11-07 Fern Pass, LLC
+marketing
+
+// marriott : 2014-10-09 Marriott Worldwide Corporation
+marriott
+
+// media : 2014-03-06 Grand Glen, LLC
+media
+
+// meet : 2014-01-16 Afilias Limited
+meet
+
+// melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation
+melbourne
+
+// meme : 2014-01-30 Charleston Road Registry Inc.
+meme
+
+// memorial : 2014-10-16 Dog Beach, LLC
+memorial
+
+// menu : 2013-09-11 Wedding TLD2, LLC
+menu
+
+// miami : 2013-12-19 Top Level Domain Holdings Limited
+miami
// mini : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
mini
-// ggee : 2014-01-09 GMO Internet, Inc.
-ggee
+// moda : 2013-11-07 United TLD Holdco Ltd.
+moda
-// beer : 2014-01-09 Top Level Domain Holdings Limited
-beer
+// moe : 2013-11-13 Interlink Co., Ltd.
+moe
-// xn--1qqw23a : 2014-01-13 Guangzhou YU Wei Information Technology Co., Ltd.
-佛山
+// monash : 2013-09-30 Monash University
+monash
-// college : 2014-01-16 XYZ.COM LLC
-college
+// money : 2014-10-16 Outer McCook, LLC
+money
-// ovh : 2014-01-16 OVH SAS
-ovh
+// montblanc : 2014-06-23 Richemont DNS Inc.
+montblanc
-// meet : 2014-01-16 Afilias Limited
-meet
+// mormon : 2013-12-05 IRI Domain Management, LLC (\
+mormon
-// xn--ses554g : 2014-01-16 HU YI GLOBAL INFORMATION RESOURCES (HOLDING) COMPANY. HONGKONG LIMITED
-网址
+// mortgage : 2014-03-20
+mortgage
-// gop : 2014-01-16 Republican State Leadership Committee, Inc.
-gop
+// moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+moscow
-// blackfriday : 2014-01-16 Uniregistry, Corp.
-blackfriday
+// motorcycles : 2014-01-09 DERMotorcycles, LLC
+motorcycles
-// lacaixa : 2014-01-16 CAIXA D'ESTALVIS I PENSIONS DE BARCELONA
-lacaixa
+// mov : 2014-01-30 Charleston Road Registry Inc.
+mov
-// xn--czr694b : 2014-01-16 HU YI GLOBAL INFORMATION RESOURCES(HOLDING) COMPANY.HONGKONG LIMITED
-商标
+// movistar : 2014-10-16 Telefónica S.A.
+movistar
-// vegas : 2014-01-16 Dot Vegas, Inc.
-vegas
+// nagoya : 2013-10-24 GMO Registry, Inc.
+nagoya
-// black : 2014-01-16 Afilias Limited
-black
+// navy : 2014-03-06 United TLD Holdco Ltd.
+navy
-// soy : 2014-01-23 Charleston Road Registry Inc.
-soy
+// netbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+netbank
-// trade : 2014-01-23 Elite Registry Limited
-trade
+// network : 2013-11-14 Trixy Manor, LLC
+network
-// gent : 2014-01-23 COMBELL GROUP NV/SA
-gent
+// neustar : 2013-12-05 NeuStar, Inc.
+neustar
-// ing : 2014-01-23 Charleston Road Registry Inc.
-ing
+// new : 2014-01-30 Charleston Road Registry Inc.
+new
-// dad : 2014-01-23 Charleston Road Registry Inc.
-dad
+// nexus : 2014-07-24 Charleston Road Registry Inc.
+nexus
-// shriram : 2014-01-23 Shriram Capital Ltd.
-shriram
+// ngo : 2014-03-06 Public Interest Registry
+ngo
-// bayern : 2014-01-23 Bayern Connect GmbH
-bayern
+// nhk : 2014-02-13 Japan Broadcasting Corporation (NHK)
+nhk
-// scot : 2014-01-23 Dot Scot Registry Limited
-scot
+// ninja : 2013-11-07 United TLD Holdco Ltd.
+ninja
-// webcam : 2014-01-23 dot Webcam Limited
-webcam
+// nissan : 2014-03-27 NISSAN MOTOR CO., LTD.
+nissan
-// foo : 2014-01-23 Charleston Road Registry Inc.
-foo
+// nowruz : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+nowruz
-// eat : 2014-01-23 Charleston Road Registry Inc.
-eat
+// nra : 2014-05-22 NRA Holdings Company, INC.
+nra
-// nyc : 2014-01-23 The City of New York
+// nrw : 2013-11-21 Minds + Machines GmbH
+nrw
+
+// ntt : 2014-10-31 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ntt
+
+// nyc : 2014-01-23 The City of New York by and through the New York City Department of Information Technology & Telecommunications
nyc
-// prod : 2014-01-23 Charleston Road Registry Inc.
-prod
+// obi : 2014-09-25 OBI Group Holding SE & Co. KGaA
+obi
-// how : 2014-01-23 Charleston Road Registry Inc.
-how
+// okinawa : 2013-12-05 BusinessRalliart Inc.
+okinawa
-// day : 2014-01-30 Charleston Road Registry Inc.
-day
+// ong : 2014-03-06 Public Interest Registry
+ong
-// meme : 2014-01-30 Charleston Road Registry Inc.
-meme
+// onl : 2013-09-16 I-Registry Ltd.
+onl
-// mov : 2014-01-30 Charleston Road Registry Inc.
-mov
+// ooo : 2014-01-09 INFIBEAM INCORPORATION LIMITED
+ooo
+
+// oracle : 2014-06-19 Oracle Corporation
+oracle
+
+// organic : 2014-03-27 Afilias Limited
+organic
+
+// osaka : 2014-09-04 Interlink Co., Ltd.
+osaka
+
+// otsuka : 2013-10-11 Otsuka Holdings Co., Ltd.
+otsuka
+
+// ovh : 2014-01-16 OVH SAS
+ovh
// paris : 2014-01-30 City of Paris
paris
-// boo : 2014-01-30 Charleston Road Registry Inc.
-boo
+// pars : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+pars
-// new : 2014-01-30 Charleston Road Registry Inc.
-new
+// partners : 2013-12-05 Magic Glen, LLC
+partners
-// ifm : 2014-01-30 ifm electronic gmbh
-ifm
+// parts : 2013-12-05 Sea Goodbye, LLC
+parts
-// life : 2014-02-06 Trixy Oaks, LLC
-life
+// party : 2014-09-11 Blue Sky Registry Limited
+party
-// archi : 2014-02-06 STARTING DOT LIMITED
-archi
+// pharmacy : 2014-06-19 National Association of Boards of Pharmacy
+pharmacy
-// spiegel : 2014-02-06 SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG
-spiegel
+// photo : 2013-11-14 Uniregistry, Corp.
+photo
-// brussels : 2014-02-06 DNS.be vzw
-brussels
+// photography : 2013-09-20 Sugar Glen, LLC
+photography
-// church : 2014-02-06 Holly Fileds, LLC
-church
+// photos : 2013-10-17 Sea Corner, LLC
+photos
-// here : 2014-02-06 Charleston Road Registry Inc.
-here
+// physio : 2014-05-01 PhysBiz Pty Ltd
+physio
-// dabur : 2014-02-06 Dabur India Limited
-dabur
+// piaget : 2014-10-16 Richemont DNS Inc.
+piaget
-// vlaanderen : 2014-02-06 DNS.be vzw
-vlaanderen
+// pics : 2013-11-14 Uniregistry, Corp.
+pics
-// cologne : 2014-02-06 NetCologne Gesellschaft für Telekommunikation mbH
-cologne
+// pictet : 2014-06-26 Pictet Europe S.A.
+pictet
-// xn--kput3i : 2014-02-13 Beijing RITT-Net Technology Development Co., Ltd
-手机
+// pictures : 2014-03-06 Foggy Sky, LLC
+pictures
-// wme : 2014-02-13 William Morris Endeavor Entertainment, LLC
-wme
+// pink : 2013-10-01 Afilias Limited
+pink
-// nhk : 2014-02-13 Japan Broadcasting Corporation (NHK)
-nhk
+// pizza : 2014-06-26 Foggy Moon, LLC
+pizza
-// suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION
-suzuki
+// place : 2014-04-24 Snow Galley, LLC
+place
-// whoswho : 2014-02-20 Who's Who Registry
-whoswho
+// plumbing : 2013-09-10 Spring Tigers, LLC
+plumbing
-// scb : 2014-02-20 The Siam Commercial Bank Public Company Limited ("SCB""\)
-scb
+// pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+pohl
-// hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH
-hamburg
+// poker : 2014-07-03 Afilias Domains No. 5 Limited
+poker
-// services : 2014-02-27 Fox Castle, LLC
-services
+// porn : 2014-10-16 ICM Registry PN LLC
+porn
-// bzh : 2014-02-27 Association www.bzh
-bzh
+// praxi : 2013-12-05 Praxi S.p.A.
+praxi
-// rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO
-rio
+// press : 2014-04-03 DotPress Inc.
+press
-// cash : 2014-03-07 Delta Lake, LLC
-cash
+// prod : 2014-01-23 Charleston Road Registry Inc.
+prod
-// gives : 2014-03-07 United TLD Holdco Ltd.
-gives
+// productions : 2013-12-05 Magic Birch, LLC
+productions
-// hiphop : 2014-03-07 Uniregistry, Corp.
-hiphop
+// prof : 2014-07-24 Charleston Road Registry Inc.
+prof
-// degree : 2014-03-07 Puff House, LLC
-degree
+// properties : 2013-12-05 Big Pass, LLC
+properties
-// digital : 2014-03-07 Dash Park, LLC
-digital
+// property : 2014-05-22 Uniregistry, Corp.
+property
-// rehab : 2014-03-07 United TLD Holdco Ltd.
-rehab
+// pub : 2013-12-12 United TLD Holdco Ltd.
+pub
-// wtf : 2014-03-07 Hidden Way, LLC
-wtf
+// qpon : 2013-11-14 dotCOOL, Inc.
+qpon
-// financial : 2014-03-07 Just Cover, LLC
-financial
+// quebec : 2013-12-19 PointQuébec Inc
+quebec
-// limited : 2014-03-07 Big Fest, LLC
-limited
+// realtor : 2014-05-29 Real Estate Domains LLC
+realtor
-// discount : 2014-03-07 Holly Hill, LLC
-discount
+// recipes : 2013-10-17 Grand Island, LLC
+recipes
-// fail : 2014-03-07 Atomic Pipe, LLC
-fail
+// red : 2013-11-07 Afilias Limited
+red
-// vet : 2014-03-07 Wild Dale, LLC
-vet
+// redstone : 2014-10-31 Redstone Haute Couture Co., Ltd.
+redstone
-// ngo : 2014-03-07 Public Interest Registry
-ngo
+// rehab : 2014-03-06 United TLD Holdco Ltd.
+rehab
-// fitness : 2014-03-07 Brice Orchard, LLC
-fitness
+// reise : 2014-03-13 dotreise GmbH
+reise
-// schule : 2014-03-07 Outer Moon, LLC
-schule
+// reisen : 2014-03-06 New Cypress, LLC
+reisen
-// navy : 2014-03-07 United TLD Holdco Ltd.
-navy
+// reit : 2014-09-04 National Association of Real Estate Investment Trusts, Inc.
+reit
-// bio : 2014-03-07 STARTING DOT LIMITED
-bio
+// ren : 2013-12-12 Beijing Qianxiang Wangjing Technology Development Co., Ltd.
+ren
-// ong : 2014-03-07 Public Interest Registry
-ong
+// rentals : 2013-12-05 Big Hollow,LLC
+rentals
-// town : 2014-03-07 Koko Moon, LLC
-town
+// repair : 2013-11-07 Lone Sunset, LLC
+repair
-// toys : 2014-03-07 Pioneer Orchard, LLC
-toys
+// report : 2013-12-05 Binky Glen, LLC
+report
-// army : 2014-03-07 United TLD Holdco Ltd.
-army
+// republican : 2014-03-20 United TLD Holdco Ltd.
+republican
-// engineering : 2014-03-07 Romeo Canyon
-engineering
+// rest : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+rest
-// capital : 2014-03-07 Delta Mill, LLC
-capital
+// restaurant : 2014-07-03 Snow Avenue, LLC
+restaurant
-// exchange : 2014-03-07 Spring Falls, LLC
-exchange
+// reviews : 2013-09-13
+reviews
-// fan : 2014-03-07 Goose Glen, LLC
-fan
+// rich : 2013-11-21 I-Registry Ltd.
+rich
-// market : 2014-03-07 Victor Way, LLC
-market
+// rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO
+rio
-// media : 2014-03-07 Grand Glen, LLC
-media
+// rip : 2014-07-10 United TLD Holdco Ltd.
+rip
-// lease : 2014-03-07 Victor Trail, LLC
-lease
+// rocks : 2013-11-14
+rocks
-// university : 2014-03-07 Little Station, LLC
-university
+// rodeo : 2013-12-19 Top Level Domain Holdings Limited
+rodeo
-// reisen : 2014-03-07 New Cypress, LLC
-reisen
+// rsvp : 2014-05-08 Charleston Road Registry Inc.
+rsvp
-// airforce : 2014-03-07 United TLD Holdco Ltd.
-airforce
+// ruhr : 2013-10-02 regiodot GmbH & Co. KG
+ruhr
-// pictures : 2014-03-07 Foggy Sky, LLC
-pictures
+// ryukyu : 2014-01-09 BusinessRalliart Inc.
+ryukyu
-// gripe : 2014-03-07 Corn Sunset, LLC
-gripe
+// saarland : 2013-12-12 dotSaarland GmbH
+saarland
-// engineer : 2014-03-07 United TLD Holdco Ltd.
-// CHROMIUM: Filed as bug http://bugzil.la/1024740
-engineer
+// sale : 2014-10-16 Half Bloom, LLC
+sale
-// associates : 2014-03-07 Baxter Hill, LLC
-associates
+// samsung : 2014-04-03 SAMSUNG SDS CO., LTD
+samsung
-// xn--mxtq1m : 2014-03-07 Net-Chinese Co., Ltd.
-政府
+// sanofi : 2014-10-09 Sanofi
+sanofi
-// williamhill : 2014-03-13 William Hill Organization Limited
-williamhill
+// sap : 2014-03-27 SAP AG
+sap
-// hiv : 2014-03-13 dotHIV gemeinnuetziger e.V.
-hiv
+// sarl : 2014-07-03 Delta Orchard, LLC
+sarl
+
+// saxo : 2014-10-31 Saxo Bank A/S
+saxo
// sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ)
sca
-// reise : 2014-03-13 dotreise GmbH
-reise
+// scb : 2014-02-20 The Siam Commercial Bank Public Company Limited (\
+scb
-// accountants : 2014-03-20 Knob Town, LLC
-accountants
+// schmidt : 2014-04-03 SALM S.A.S.
+schmidt
-// clinic : 2014-03-20 Goose Park, LLC
-clinic
+// scholarships : 2014-04-24 Scholarships.com, LLC
+scholarships
-// versicherung : 2014-03-20 dotversicherung-registry GmbH
-versicherung
+// schule : 2014-03-06 Outer Moon, LLC
+schule
-// top : 2014-03-20 Jiangsu Bangning Science & Technology Co.,Ltd.
-top
+// schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+schwarz
-// furniture : 2014-03-20 Lone Fields, LLC
-furniture
+// science : 2014-09-11 dot Science Limited
+science
-// dental : 2014-03-20 Tin Birch, LLC
-dental
+// scor : 2014-10-31 SCOR SE
+scor
-// fund : 2014-03-20 John Castle, LLC
-fund
+// scot : 2014-01-23 Dot Scot Registry Limited
+scot
-// creditcard : 2014-03-20 Binky Frostbite, LLC
-creditcard
+// seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal)
+seat
-// insure : 2014-03-20 Pioneer Willow, LLC
-insure
+// sener : 2014-10-24 Sener Ingeniería y Sistemas, S.A.
+sener
-// audio : 2014-03-20 Uniregistry, Corp.
-audio
+// services : 2014-02-27 Fox Castle, LLC
+services
-// claims : 2014-03-20 Black Corner, LLC
-claims
+// sew : 2014-07-17 SEW-EURODRIVE GmbH & Co KG
+sew
-// loans : 2014-03-20 June Woods, LLC
-loans
+// sexy : 2013-09-11 Uniregistry, Corp.
+sexy
-// auction : 2014-03-20 Sand Galley, LLC
-auction
+// sharp : 2014-05-01 Sharp Corporation
+sharp
-// attorney : 2014-03-20 Victor North, LLC
-attorney
+// shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+shia
-// finance : 2014-03-20 Cotton Cypress, LLC
-finance
+// shiksha : 2013-11-14 Afilias Limited
+shiksha
-// investments : 2014-03-20 Holly Glen, LLC
-investments
+// shoes : 2013-10-02 Binky Galley, LLC
+shoes
-// juegos : 2014-03-20 Uniregistry, Corp.
-juegos
+// shriram : 2014-01-23 Shriram Capital Ltd.
+shriram
-// dentist : 2014-03-20 Outer Lake, LLC
-dentist
+// singles : 2013-08-27 Fern Madison, LLC
+singles
-// lds : 2014-03-20 IRI Domain Management, LLC
-lds
+// sky : 2014-06-19 Sky IP International Ltd, a company incorporated in England and Wales, operating via its registered Swiss branch
+sky
-// lawyer : 2014-03-20 Atomic Station, LLC
-lawyer
+// social : 2013-11-07 United TLD Holdco Ltd.
+social
-// surgery : 2014-03-20 Tin Avenue, LLC
+// software : 2014-03-20
+software
+
+// sohu : 2013-12-19 Sohu.com Limited
+sohu
+
+// solar : 2013-11-07 Ruby Town, LLC
+solar
+
+// solutions : 2013-11-07 Silver Cover, LLC
+solutions
+
+// soy : 2014-01-23 Charleston Road Registry Inc.
+soy
+
+// space : 2014-04-03 DotSpace Inc.
+space
+
+// spiegel : 2014-02-05 SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG
+spiegel
+
+// stc : 2014-10-09 Saudi Telecom Company
+stc
+
+// stcgroup : 2014-10-09 Saudi Telecom Company
+stcgroup
+
+// supplies : 2013-12-19 Atomic Fields, LLC
+supplies
+
+// supply : 2013-12-19 Half Falls, LLC
+supply
+
+// support : 2013-10-24 Grand Orchard, LLC
+support
+
+// surf : 2014-01-09 Top Level Domain Holdings Limited
+surf
+
+// surgery : 2014-03-20 Tin Avenue, LLC
surgery
-// gratis : 2014-03-20 Pioneer Tigers, LLC
-gratis
+// suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION
+suzuki
-// software : 2014-03-20 Over Birch, LLC
-software
+// swiss : 2014-10-16 Swiss Confederation
+swiss
-// mortgage : 2014-03-20 Outer Gardens, LLC
-mortgage
+// sydney : 2014-09-18 State of New South Wales, Department of Premier and Cabinet
+sydney
-// republican : 2014-03-20 United TLD Holdco Ltd.
-republican
+// systems : 2013-11-07 Dash Cypress, LLC
+systems
-// credit : 2014-03-20 Snow Shadow, LLC
-credit
+// taipei : 2014-07-10 Taipei City Government
+taipei
-// tax : 2014-03-20 Storm Orchard, LLC
+// tatar : 2014-04-24 Limited Liability Company \
+tatar
+
+// tattoo : 2013-08-30 Uniregistry, Corp.
+tattoo
+
+// tax : 2014-03-20 Storm Orchard, LLC
tax
-// africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa
-africa
+// tci : 2014-09-12 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+tci
-// joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
-joburg
+// technology : 2013-09-13 Auburn Falls
+technology
-// durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
-durban
+// telefonica : 2014-10-16 Telefónica S.A.
+telefonica
-// capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
-capetown
+// temasek : 2014-08-07 Temasek Holdings (Private) Limited
+temasek
-// sap : 2014-03-27 SAP AG
-sap
+// tienda : 2013-11-14 Victor Manor, LLC
+tienda
-// datsun : 2014-03-27 NISSAN MOTOR CO., LTD.
-datsun
+// tips : 2013-09-20 Corn Willow, LLC
+tips
-// infiniti : 2014-03-27 NISSAN MOTOR CO., LTD.
-infiniti
+// tirol : 2014-04-24 punkt Tirol GmbH
+tirol
-// firmdale : 2014-03-27 Firmdale Holdings Limited
-firmdale
+// today : 2013-09-20 Pearl Woods, LLC
+today
-// organic : 2014-03-27 Afilias Limited
-organic
+// tokyo : 2013-11-13 GMO Registry, Inc.
+tokyo
-// nissan : 2014-03-27 NISSAN MOTOR CO., LTD.
-nissan
+// tools : 2013-11-21 Pioneer North, LLC
+tools
-// website : 2014-04-03 DotWebsite Inc.
-website
+// top : 2014-03-20 Jiangsu Bangning Science & Technology Co.,Ltd.
+top
-// space : 2014-04-03 DotSpace Inc.
-space
+// toshiba : 2014-04-10 TOSHIBA Corporation
+toshiba
-// schmidt : 2014-04-03 SALM S.A.S.
-schmidt
+// town : 2014-03-06 Koko Moon, LLC
+town
-// cuisinella : 2014-04-03 SALM S.A.S.
-cuisinella
+// toys : 2014-03-06 Pioneer Orchard, LLC
+toys
-// samsung : 2014-04-03 SAMSUNG SDS CO., LTD
-samsung
+// trade : 2014-01-23 Elite Registry Limited
+trade
-// crs : 2014-04-03 Federated Co operatives Limited
-crs
+// training : 2013-11-07 Wild Willow, LLC
+training
-// doosan : 2014-04-03 Doosan Corporation
-doosan
+// trust : 2014-10-16
+trust
-// press : 2014-04-03 DotPress Inc.
-press
+// tui : 2014-07-03 TUI AG
+tui
-// emerck : 2014-04-03 Merck KGaA
-emerck
+// university : 2014-03-06 Little Station, LLC
+university
-// erni : 2014-04-03 ERNI Group Holding AG
-erni
+// uno : 2013-09-11 Dot Latin LLC
+uno
-// direct : 2014-04-10 Half Trail, LLC
-direct
+// uol : 2014-05-01 UBN INTERNET LTDA.
+uol
-// yandex : 2014-04-10 YANDEX, LLC
-yandex
+// vacations : 2013-12-05 Atomic Tigers, LLC
+vacations
-// lotto : 2014-04-10 Afilias Limited
-lotto
+// vegas : 2014-01-16 Dot Vegas, Inc.
+vegas
-// toshiba : 2014-04-10 TOSHIBA Corporation
-toshiba
+// ventures : 2013-08-27 Binky Lake, LLC
+ventures
-// bauhaus : 2014-04-17 Werkhaus GmbH
-bauhaus
+// versicherung : 2014-03-20 dotversicherung-registry GmbH
+versicherung
-// host : 2014-04-17 DotHost Inc.
-host
+// vet : 2014-03-06
+vet
-// ltda : 2014-04-17 DOMAIN ROBOT SERVICOS DE HOSPEDAGEM NA INTERNET LTDA
-ltda
+// viajes : 2013-10-17 Black Madison, LLC
+viajes
-// global : 2014-04-17 Dot GLOBAL AS
-global
+// video : 2014-10-16 Lone Tigers, LLC
+video
-// abogado : 2014-04-24 Top Level Domain Holdings Limited
-abogado
+// villas : 2013-12-05 New Sky, LLC
+villas
-// place : 2014-04-24 Snow Galley, LLC
-place
+// virgin : 2014-09-25 Virgin Enterprises Limited
+virgin
-// tirol : 2014-04-24 punkt Tirol GmbH
-tirol
+// vision : 2013-12-05 Koko Station, LLC
+vision
-// gmx : 2014-04-24 1&1 Mail & Media GmbH
-gmx
+// vista : 2014-09-18 Vistaprint Limited
+vista
-// tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic"
-tatar
+// vistaprint : 2014-09-18 Vistaprint Limited
+vistaprint
-// scholarships : 2014-04-24 Scholarships.com, LLC
-scholarships
+// vlaanderen : 2014-02-06 DNS.be vzw
+vlaanderen
-// eurovision : 2014-04-24 European Broadcasting Union (EBU)
-eurovision
+// vodka : 2013-12-19 Top Level Domain Holdings Limited
+vodka
-// wedding : 2014-04-24 Top Level Domain Holdings Limited
+// vote : 2013-11-21 Monolith Registry LLC
+vote
+
+// voting : 2013-11-13 Valuetainment Corp.
+voting
+
+// voto : 2013-11-21 Monolith Registry LLC
+voto
+
+// voyage : 2013-08-27 Ruby House, LLC
+voyage
+
+// wales : 2014-05-08 Nominet UK
+wales
+
+// wang : 2013-10-24 Zodiac Leo Limited
+wang
+
+// watch : 2013-11-14 Sand Shadow, LLC
+watch
+
+// webcam : 2014-01-23 dot Webcam Limited
+webcam
+
+// website : 2014-04-03 DotWebsite Inc.
+website
+
+// wed : 2013-10-01 Atgron, Inc.
+wed
+
+// wedding : 2014-04-24 Top Level Domain Holdings Limited
wedding
-// active : 2014-05-01 The Active Network, Inc
-active
+// whoswho : 2014-02-20 Who's Who Registry
+whoswho
-// madrid : 2014-05-01 Comunidad de Madrid
-madrid
+// wien : 2013-10-28 punkt.wien GmbH
+wien
-// youtube : 2014-05-01 Charleston Road Registry Inc.
-youtube
+// wiki : 2013-11-07 Top Level Design, LLC
+wiki
-// sharp : 2014-05-01 Sharp Corporation
-sharp
+// williamhill : 2014-03-13 William Hill Organization Limited
+williamhill
-// uol : 2014-05-01 UBN INTERNET LTDA.
-uol
+// wme : 2014-02-13 William Morris Endeavor Entertainment, LLC
+wme
-// physio : 2014-05-01 PhysBiz Pty Ltd
-physio
+// work : 2013-12-19 Top Level Domain Holdings Limited
+work
-// gmail : 2014-05-01 Charleston Road Registry Inc.
-gmail
+// works : 2013-11-14 Little Dynamite, LLC
+works
-// channel : 2014-05-08 Charleston Road Registry Inc.
-channel
+// world : 2014-06-12 Bitter Fields, LLC
+world
-// fly : 2014-05-08 Charleston Road Registry Inc.
-fly
+// wtc : 2013-12-19 World Trade Centers Association, Inc.
+wtc
-// zip : 2014-05-08 Charleston Road Registry Inc.
-zip
+// wtf : 2014-03-06 Hidden Way, LLC
+wtf
-// esq : 2014-05-08 Charleston Road Registry Inc.
-esq
+// xerox : 2014-10-24 Xerox DNHC LLC
+xerox
-// rsvp : 2014-05-08 Charleston Road Registry Inc.
-rsvp
+// xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd.
+佛山
-// wales : 2014-05-08 Nominet UK
-wales
+// xn--30rr7y : 2014-06-12 Excellent First Limited
+慈善
-// cymru : 2014-05-08 Nominet UK
-cymru
+// xn--3bst00m : 2013-09-13 Eagle Horizon Limited
+集团
-// green : 2014-05-08 Afilias Limited
-green
+// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED
+在线
-// lgbt : 2014-05-08 Afilias Limited
-lgbt
+// xn--45q11c : 2013-11-21 Zodiac Scorpio Limited
+八卦
-// xn--hxt814e : 2014-05-15 Zodiac Libra Limited
-网店
+// xn--4gbrim : 2013-10-04 Suhub Electronic Establishment
+موقع
-// cancerresearch : 2014-05-15 Australian Cancer Research Foundation
-cancerresearch
+// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center
+公益
-// everbank : 2014-05-15 EverBank
-everbank
+// xn--55qx5d : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
+公司
-// frl : 2014-05-15 FRLregistry B.V.
-frl
+// xn--6frz82g : 2013-09-23 Afilias Limited
+移动
-// property : 2014-05-22 Uniregistry, Corp.
-property
+// xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited
+我爱你
-// forsale : 2014-05-22 Sea Oaks, LLC
-forsale
+// xn--80adxhks : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+москва
-// seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal)
-seat
+// xn--80asehdb : 2013-07-14 CORE Association
+онлайн
-// deals : 2014-05-22 Sand Sunset, LLC
-deals
+// xn--80aswg : 2013-07-14 CORE Association
+сайт
-// nra : 2014-05-22 NRA Holdings Company, INC.
-nra
+// xn--9et52u : 2014-06-12 RISE VICTORY LIMITED
+时尚
-// xn--fjq720a : 2014-05-22 Will Bloom, LLC
+// xn--b4w605ferd : 2014-08-07 Temasek Holdings (Private) Limited
+淡马锡
+
+// xn--c1avg : 2013-11-14 Public Interest Registry
+орг
+
+// xn--cg4bki : 2013-09-27 SAMSUNG SDS CO., LTD
+삼성
+
+// xn--czr694b : 2014-01-16 HU YI GLOBAL INFORMATION RESOURCES(HOLDING) COMPANY.HONGKONG LIMITED
+商标
+
+// xn--czrs0t : 2013-12-19 Wild Island, LLC
+商店
+
+// xn--czru2d : 2013-11-21 Zodiac Capricorn Limited
+商城
+
+// xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet”
+дети
+
+// xn--efvy88h : 2014-08-22 Xinhua News Agency Guangdong Branch 新华通讯社广东分社
+新闻
+
+// xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED
+中文网
+
+// xn--fiq64b : 2013-10-14 CITIC Group Corporation
+中信
+
+// xn--fjq720a : 2014-05-22 Will Bloom, LLC
娱乐
-// realtor : 2014-05-29 Real Estate Domains LLC
-realtor
+// xn--flw351e : 2014-07-31 Charleston Road Registry Inc.
+谷歌
-// bnpparibas : 2014-05-29 BNP Paribas
-bnpparibas
+// xn--hxt814e : 2014-05-15 Zodiac Libra Limited
+网店
-// melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation
-melbourne
+// xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry
+संगठन
-// hosting : 2014-05-29 Uniregistry, Corp.
-hosting
+// xn--io0a7i : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
+网络
+
+// xn--kput3i : 2014-02-13 Beijing RITT-Net Technology Development Co., Ltd
+手机
+
+// xn--mgbab2bd : 2013-10-31 CORE Association
+بازار
+
+// xn--mgbt3dhd : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+همراه
+
+// xn--mxtq1m : 2014-03-06 Net-Chinese Co., Ltd.
+政府
+
+// xn--ngbc5azd : 2013-07-13 International Domain Registry Pty. Ltd.
+شبكة
+
+// xn--nqv7f : 2013-11-14 Public Interest Registry
+机构
+
+// xn--nqv7fs00ema : 2013-11-14 Public Interest Registry
+组织机构
+
+// xn--p1acf : 2013-12-12 Rusnames Limited
+рус
+
+// xn--q9jyb4c : 2013-09-17 Charleston Road Registry Inc.
+みんな
+
+// xn--qcka1pmc : 2014-07-31 Charleston Road Registry Inc.
+グーグル
+
+// xn--rhqv96g : 2013-09-11 Stable Tone Limited
+世界
+
+// xn--ses554g : 2014-01-16 HU YI GLOBAL INFORMATION RESOURCES (HOLDING) COMPANY. HONGKONG LIMITED
+网址
+
+// xn--unup4y : 2013-07-14 Spring Fields, LLC
+游戏
+
+// xn--vermgensberater-ctb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+vermögensberater
+
+// xn--vermgensberatung-pwb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+vermögensberatung
+
+// xn--vhquv : 2013-08-27 Dash McCook, LLC
+企业
+
+// xn--vuq861b : 2014-10-16 Beijing Tele-info Network Technology Co., Ltd.
+信息
+
+// xn--xhq521b : 2013-11-14 Guangzhou YU Wei Information Technology Co., Ltd.
+广东
+
+// xn--zfr164b : 2013-11-08 China Organizational Name Administration Center
+政务
+
+// xyz : 2013-12-05 XYZ.COM LLC
+xyz
-// yoga : 2014-05-29 Top Level Domain Holdings Limited
+// yachts : 2014-01-09 DERYachts, LLC
+yachts
+
+// yandex : 2014-04-10 YANDEX, LLC
+yandex
+
+// yoga : 2014-05-29 Top Level Domain Holdings Limited
yoga
-// city : 2014-05-29 Snow Sky, LLC
-city
+// yokohama : 2013-12-12 GMO Registry, Inc.
+yokohama
-// bond : 2014-06-05 Bond University Limited
-bond
+// youtube : 2014-05-01 Charleston Road Registry Inc.
+youtube
-// click : 2014-06-05 Uniregistry, Corp.
-click
+// zip : 2014-05-08 Charleston Road Registry Inc.
+zip
-// cern : 2014-06-05 European Organization for Nuclear Research ("CERN")
-cern
+// zone : 2013-11-14 Outer Falls, LLC
+zone
// ===END ICANN DOMAINS===
// ===BEGIN PRIVATE DOMAINS===
@@ -8418,6 +8930,10 @@ global.prod.fastly.net
// Submitted by Chris Raynor <chris@firebase.com> 2014-01-21
firebaseapp.com
+// Flynn : https://flynn.io
+// Submitted by Jonathan Rudenberg <jonathan@flynn.io> 2014-07-12
+flynnhub.com
+
// GitHub, Inc.
// Submitted by Ben Toews <btoews@github.com> 2014-02-06
github.io
@@ -8430,6 +8946,7 @@ ro.com
// Google, Inc.
// Submitted by Eduardo Vela <evn@google.com> 2012-10-24
appspot.com
+blogspot.ae
blogspot.be
blogspot.bj
blogspot.ca
@@ -8444,6 +8961,7 @@ blogspot.com.ar
blogspot.com.au
blogspot.com.br
blogspot.com.es
+blogspot.com.tr
blogspot.cv
blogspot.cz
blogspot.de
@@ -8465,6 +8983,7 @@ blogspot.no
blogspot.pt
blogspot.re
blogspot.ro
+blogspot.ru
blogspot.se
blogspot.sg
blogspot.sk
@@ -8517,14 +9036,37 @@ operaunite.com
// Submitted by Duarte Santos <domain-admin@outsystemscloud.com> 2014-03-11
outsystemscloud.com
+// .pl domains (grandfathered)
+art.pl
+gliwice.pl
+krakow.pl
+poznan.pl
+wroc.pl
+zakopane.pl
+
// Red Hat, Inc. OpenShift : https://openshift.redhat.com/
// Submitted by Tim Kramer <tkramer@rhcloud.com> 2012-10-24
rhcloud.com
+// GDS : https://www.gov.uk/service-manual/operations/operating-servicegovuk-subdomains
+// Submitted by David Illsley <david.illsley@digital.cabinet-office.gov.uk> 2014-08-28
+service.gov.uk
+
// priv.at : http://www.nic.priv.at/
// Submitted by registry <lendl@nic.at> 2008-06-09
priv.at
+// TASK geographical domains (www.task.gda.pl/uslugi/dns)
+gda.pl
+gdansk.pl
+gdynia.pl
+med.pl
+sopot.pl
+
+// Yola : https://www.yola.com/
+// Submitted by Stefano Rivera <stefano@yola.com> 2014-07-09
+yolasite.com
+
// ZaNiC : http://www.za.net/
// Submitted by registry <hostmaster@nic.za.net> 2009-10-03
za.net
diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
index 6bee195507e..b3b6afda455 100644
--- a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
+++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
@@ -19,7 +19,6 @@ struct DomainRule {
4.bg, 0
5.bg, 0
6.bg, 0
-6bone.pl, 0
7.bg, 0
8.bg, 0
9.bg, 0
@@ -31,6 +30,8 @@ aa.no, 0
aarborte.no, 0
ab.ca, 0
abashiri.hokkaido.jp, 0
+abb, 0
+abbott, 0
abeno.osaka.jp, 0
abiko.chiba.jp, 0
abira.hokkaido.jp, 0
@@ -74,6 +75,7 @@ ac.vn, 0
aca.pro, 0
academy, 0
academy.museum, 0
+accenture, 0
accident-investigation.aero, 0
accident-prevention.aero, 0
accountants, 0
@@ -86,6 +88,7 @@ ad, 0
ad.jp, 0
adachi.tokyo.jp, 0
adm.br, 0
+adult, 0
adult.ht, 0
adv.br, 0
adygeya.ru, 0
@@ -101,6 +104,7 @@ aerodrome.aero, 0
aeroport.fr, 0
af, 0
afjord.no, 0
+afl, 0
africa, 0
africa.com, 4
ag, 0
@@ -136,6 +140,7 @@ airforce, 0
airguard.museum, 0
airline.aero, 0
airport.aero, 0
+airtel, 0
airtraffic.aero, 0
aisai.aichi.jp, 0
aisho.shiga.jp, 0
@@ -169,6 +174,8 @@ alaska.museum, 0
alessandria.it, 0
alesund.no, 0
algard.no, 0
+allfinanz, 0
+alsace, 0
alstahaug.no, 0
alta.no, 0
altai.ru, 0
@@ -192,6 +199,7 @@ americanart.museum, 0
ami.ibaraki.jp, 0
amli.no, 0
amot.no, 0
+amsterdam, 0
amsterdam.museum, 0
amur.ru, 0
amursk.ru, 0
@@ -211,6 +219,7 @@ andria-barletta-trani.it, 0
andria-trani-barletta.it, 0
andriabarlettatrani.it, 0
andriatranibarletta.it, 0
+android, 0
anjo.aichi.jp, 0
annaka.gunma.jp, 0
annefrank.museum, 0
@@ -236,6 +245,7 @@ ap.it, 0
appspot.com, 4
aq, 0
aq.it, 0
+aquarelle, 0
aquarium.museum, 0
aquila.it, 0
ar, 0
@@ -269,7 +279,7 @@ art.do, 0
art.dz, 0
art.ht, 0
art.museum, 0
-art.pl, 0
+art.pl, 4
art.sn, 0
artanddesign.museum, 0
artcenter.museum, 0
@@ -366,6 +376,7 @@ auto.pl, 0
automotive.museum, 0
autos, 0
av.it, 0
+av.tr, 0
avellino.it, 0
averoy.no, 0
aviation.museum, 0
@@ -410,10 +421,13 @@ balsan.it, 0
balsfjord.no, 0
baltimore.museum, 0
bamble.no, 0
+band, 0
bandai.fukushima.jp, 0
bando.ibaraki.jp, 0
+bank, 0
bar, 0
bar.pro, 0
+barcelona, 0
barcelona.museum, 0
bardu.no, 0
bargains, 0
@@ -436,7 +450,10 @@ bauern.museum, 0
bauhaus, 0
bayern, 0
bb, 0
+bbs.tr, 0
+bbva, 0
bc.ca, 0
+bcn, 0
bd, 2
bd.se, 0
be, 0
@@ -447,6 +464,7 @@ bedzin.pl, 0
beeldengeluid.museum, 0
beer, 0
beiarn.no, 0
+bel.tr, 0
belau.pw, 0
belgorod.ru, 0
bellevue.museum, 0
@@ -470,11 +488,13 @@ bf, 0
bg, 0
bg.it, 0
bh, 0
+bharti, 0
bi, 0
bi.it, 0
bialowieza.pl, 0
bialystok.pl, 0
bibai.hokkaido.jp, 0
+bible, 0
bible.museum, 0
bid, 0
biei.hokkaido.jp, 0
@@ -499,6 +519,7 @@ biz, 0
biz.at, 4
biz.az, 0
biz.bb, 0
+biz.et, 0
biz.id, 0
biz.ki, 0
biz.mv, 0
@@ -508,6 +529,7 @@ biz.pk, 0
biz.pl, 0
biz.pr, 0
biz.tj, 0
+biz.tr, 0
biz.tt, 0
biz.vn, 0
bizen.okayama.jp, 0
@@ -524,6 +546,7 @@ blogdns.com, 4
blogdns.net, 4
blogdns.org, 4
blogsite.org, 4
+blogspot.ae, 4
blogspot.be, 4
blogspot.bj, 4
blogspot.ca, 4
@@ -538,6 +561,7 @@ blogspot.com.ar, 4
blogspot.com.au, 4
blogspot.com.br, 4
blogspot.com.es, 4
+blogspot.com.tr, 4
blogspot.cv, 4
blogspot.cz, 4
blogspot.de, 4
@@ -559,16 +583,21 @@ blogspot.no, 4
blogspot.pt, 4
blogspot.re, 4
blogspot.ro, 4
+blogspot.ru, 4
blogspot.se, 4
blogspot.sg, 4
blogspot.sk, 4
blogspot.td, 4
blogspot.tw, 4
+bloomberg, 0
blue, 0
bm, 0
bmd.br, 0
+bms, 0
+bmw, 0
bn, 2
bn.it, 0
+bnl, 0
bnpparibas, 0
bo, 0
bo.it, 0
@@ -581,6 +610,7 @@ boleslawiec.pl, 0
bologna.it, 0
bolt.hu, 0
bolzano.it, 0
+bom, 0
bomlo.no, 0
bond, 0
bonn.museum, 0
@@ -662,6 +692,7 @@ cab, 0
cadaques.museum, 0
cagliari.it, 0
cahcesuolo.no, 0
+cal, 0
cal.it, 0
calabria.it, 0
california.museum, 0
@@ -677,6 +708,7 @@ campobasso.it, 0
can.museum, 0
canada.museum, 0
cancerresearch, 0
+canon, 0
capebreton.museum, 0
capetown, 0
capital, 0
@@ -684,12 +716,14 @@ caravan, 0
carbonia-iglesias.it, 0
carboniaiglesias.it, 0
cards, 0
+care, 0
career, 0
careers, 0
cargo.aero, 0
carrara-massa.it, 0
carraramassa.it, 0
carrier.museum, 0
+cartier, 0
cartoonart.museum, 0
casa, 0
casadelamoneda.museum, 0
@@ -704,7 +738,9 @@ catanzaro.it, 0
catering, 0
catering.aero, 0
cb.it, 0
+cba, 0
cbg.ru, 0
+cbn, 0
cc, 0
cc.ak.us, 0
cc.al.us, 0
@@ -775,6 +811,7 @@ certification.aero, 0
cesena-forli.it, 0
cesenaforli.it, 0
cf, 0
+cfa, 0
cg, 0
ch, 0
ch.it, 0
@@ -823,6 +860,7 @@ chitose.hokkaido.jp, 0
chiyoda.gunma.jp, 0
chiyoda.tokyo.jp, 0
chizu.tottori.jp, 0
+chloe, 0
chocolate.museum, 0
chofu.tokyo.jp, 0
chonan.chiba.jp, 0
@@ -831,6 +869,7 @@ choshi.chiba.jp, 0
choyo.kumamoto.jp, 0
christiansburg.museum, 0
christmas, 0
+chrome, 0
chtr.k12.ma.us, 0
chukotka.ru, 0
chungbuk.kr, 0
@@ -849,6 +888,7 @@ cim.br, 0
cincinnati.museum, 0
cinema.museum, 0
circus.museum, 0
+citic, 0
city, 0
city.hu, 0
city.kawasaki.jp, 1
@@ -945,6 +985,7 @@ co.us, 0
co.uz, 0
co.ve, 0
co.vi, 0
+coach, 0
coal.museum, 0
coastaldefence.museum, 0
codes, 0
@@ -995,6 +1036,7 @@ com.ec, 0
com.ee, 0
com.eg, 0
com.es, 0
+com.et, 0
com.fr, 0
com.ge, 0
com.gh, 0
@@ -1074,6 +1116,7 @@ com.tj, 0
com.tm, 0
com.tn, 0
com.to, 0
+com.tr, 0
com.tt, 0
com.tw, 0
com.ua, 0
@@ -1086,6 +1129,7 @@ com.vi, 0
com.vn, 0
com.vu, 0
com.ws, 0
+commbank, 0
communication.museum, 0
communications.museum, 0
community, 0
@@ -1124,6 +1168,7 @@ coop.py, 0
coop.tt, 0
copenhagen.museum, 0
corporation.museum, 0
+corsica, 0
corvette.museum, 0
cosenza.it, 0
costume.museum, 0
@@ -1144,11 +1189,14 @@ creditcard, 0
cremona.it, 0
crew.aero, 0
cri.nz, 0
+cricket, 0
crimea.ua, 0
crotone.it, 0
+crown, 0
crs, 0
cruises, 0
cs.it, 0
+csc, 0
ct.it, 0
ct.us, 0
cu, 0
@@ -1204,6 +1252,8 @@ decorativearts.museum, 0
defense.tn, 0
degree, 0
delaware.museum, 0
+delivery, 0
+dell, 0
dell-ogliastra.it, 0
dellogliastra.it, 0
delmenhorst.museum, 0
@@ -1218,9 +1268,11 @@ desi, 0
design.aero, 0
design.museum, 0
detroit.museum, 0
+dev, 0
dgca.aero, 0
diamonds, 0
dielddanuorri.no, 0
+diet, 0
digital, 0
dinosaur.museum, 0
direct, 0
@@ -1245,9 +1297,11 @@ dnsdojo.com, 4
dnsdojo.net, 4
dnsdojo.org, 4
do, 0
+docs, 0
does-it.net, 4
doesntexist.com, 4
doesntexist.org, 4
+doha, 0
dolls.museum, 0
domains, 0
dominic.ua, 0
@@ -1264,6 +1318,7 @@ doshi.yamanashi.jp, 0
dovre.no, 0
dp.ua, 0
dr.na, 0
+dr.tr, 0
drammen.no, 0
drangedal.no, 0
dreamhosters.com, 4
@@ -1271,6 +1326,7 @@ drobak.no, 0
dudinka.ru, 0
durban, 0
durham.museum, 0
+dvag, 0
dvrdns.org, 4
dyn-o-saur.com, 4
dynalias.com, 4
@@ -1350,6 +1406,7 @@ edu.ec, 0
edu.ee, 0
edu.eg, 0
edu.es, 0
+edu.et, 0
edu.ge, 0
edu.gh, 0
edu.gi, 0
@@ -1422,6 +1479,7 @@ edu.sy, 0
edu.tj, 0
edu.tm, 0
edu.to, 0
+edu.tr, 0
edu.tt, 0
edu.tw, 0
edu.ua, 0
@@ -1473,6 +1531,7 @@ endofinternet.net, 4
endofinternet.org, 4
endoftheinternet.org, 4
enebakk.no, 0
+energy, 0
eng.br, 0
eng.pro, 0
engerdal.no, 0
@@ -1511,7 +1570,7 @@ est-mon-blogueur.com, 4
est.pr, 0
estate, 0
estate.museum, 0
-et, 2
+et, 0
etajima.hiroshima.jp, 0
etc.br, 0
ethnology.museum, 0
@@ -1552,6 +1611,7 @@ farmequipment.museum, 0
farmers.museum, 0
farmstead.museum, 0
farsund.no, 0
+fashion, 0
fauske.no, 0
fc.it, 0
fe.it, 0
@@ -1579,6 +1639,7 @@ film.hu, 0
film.museum, 0
fin.ec, 0
fin.tn, 0
+final, 0
finance, 0
financial, 0
fineart.museum, 0
@@ -1618,7 +1679,10 @@ florence.it, 0
florida.museum, 0
florist, 0
floro.no, 0
+flowers, 0
+flsmidth, 0
fly, 0
+flynnhub.com, 4
fm, 0
fm.br, 0
fm.it, 0
@@ -1816,6 +1880,7 @@ gamo.shiga.jp, 0
gamvik.no, 0
gangaviika.no, 0
gangwon.kr, 0
+garden, 0
garden.museum, 0
gateway.museum, 0
gaular.no, 0
@@ -1823,12 +1888,14 @@ gausdal.no, 0
gb, 0
gb.com, 4
gb.net, 4
+gbiz, 0
gc.ca, 0
gd, 0
gd.cn, 0
-gda.pl, 0
-gdansk.pl, 0
-gdynia.pl, 0
+gda.pl, 4
+gdansk.pl, 4
+gdn, 0
+gdynia.pl, 4
ge, 0
ge.it, 0
geek.nz, 0
@@ -1837,6 +1904,7 @@ geisei.kochi.jp, 0
gemological.museum, 0
gen.in, 0
gen.nz, 0
+gen.tr, 0
genkai.saga.jp, 0
genoa.it, 0
genova.it, 0
@@ -1855,6 +1923,7 @@ gi, 0
giehtavuoatna.no, 0
giessen.museum, 0
gift, 0
+gifts, 0
gifu.gifu.jp, 0
gifu.jp, 0
gildeskal.no, 0
@@ -1874,8 +1943,9 @@ gl, 0
glas.museum, 0
glass, 0
glass.museum, 0
+gle, 0
gliding.aero, 0
-gliwice.pl, 0
+gliwice.pl, 4
global, 0
global.prod.fastly.net, 4
global.ssl.fastly.net, 4
@@ -1885,6 +1955,7 @@ gloppen.no, 0
gm, 0
gmail, 0
gmina.pl, 0
+gmo, 0
gmx, 0
gn, 0
gniezno.pl, 0
@@ -1922,6 +1993,7 @@ gokase.miyazaki.jp, 0
gol.no, 0
gon.pk, 0
gonohe.aomori.jp, 0
+google, 0
googleapis.com, 4
googlecode.com, 4
gop, 0
@@ -1979,6 +2051,7 @@ gov.dz, 0
gov.ec, 0
gov.ee, 0
gov.eg, 0
+gov.et, 0
gov.ge, 0
gov.gh, 0
gov.gi, 0
@@ -2051,6 +2124,7 @@ gov.tl, 0
gov.tm, 0
gov.tn, 0
gov.to, 0
+gov.tr, 0
gov.tt, 0
gov.tw, 0
gov.ua, 0
@@ -2085,6 +2159,7 @@ groks-this.info, 4
grong.no, 0
grosseto.it, 0
groundhandling.aero, 0
+group, 0
group.aero, 0
grozny.ru, 0
grp.lk, 0
@@ -2118,6 +2193,7 @@ gu, 2
gu.us, 0
gub.uy, 0
guernsey.museum, 0
+guge, 0
guide, 0
guitars, 0
gujo.gifu.jp, 0
@@ -2215,10 +2291,12 @@ he.cn, 0
health.museum, 0
health.nz, 0
health.vn, 0
+healthcare, 0
heguri.nara.jp, 0
heimatunduhren.museum, 0
hekinan.aichi.jp, 0
hellas.museum, 0
+help, 0
helsinki.museum, 0
hembygdsforbund.museum, 0
hemne.no, 0
@@ -2228,6 +2306,7 @@ herad.no, 0
here, 0
here-for-more.info, 4
heritage.museum, 0
+hermes, 0
herokuapp.com, 4
herokussl.com, 4
heroy.more-og-romsdal.no, 0
@@ -2306,6 +2385,7 @@ historisches.museum, 0
history.museum, 0
historyofscience.museum, 0
hita.oita.jp, 0
+hitachi, 0
hitachi.ibaraki.jp, 0
hitachinaka.ibaraki.jp, 0
hitachiomiya.ibaraki.jp, 0
@@ -2378,6 +2458,7 @@ hoyanger.no, 0
hoylandet.no, 0
hr, 0
hs.kr, 0
+hsbc, 0
ht, 0
hu, 0
hu.com, 4
@@ -2401,6 +2482,8 @@ ibaraki.jp, 0
ibaraki.osaka.jp, 0
ibestad.no, 0
ibigawa.gifu.jp, 0
+ibm, 0
+ice, 0
ichiba.tokushima.jp, 0
ichihara.chiba.jp, 0
ichikai.tochigi.jp, 0
@@ -2430,6 +2513,7 @@ iheya.okinawa.jp, 0
iida.nagano.jp, 0
iide.yamagata.jp, 0
iijima.nagano.jp, 0
+iinet, 0
iitate.fukushima.jp, 0
iiyama.nagano.jp, 0
iizuka.fukuoka.jp, 0
@@ -2458,6 +2542,7 @@ imakane.hokkaido.jp, 0
imari.saga.jp, 0
imb.br, 0
imizu.toyama.jp, 0
+immo, 0
immobilien, 0
imperia.it, 0
in, 0
@@ -2504,6 +2589,7 @@ info.az, 0
info.bb, 0
info.co, 0
info.ec, 0
+info.et, 0
info.ht, 0
info.hu, 0
info.ki, 0
@@ -2518,6 +2604,7 @@ info.pr, 0
info.ro, 0
info.sd, 0
info.tn, 0
+info.tr, 0
info.tt, 0
info.tz, 0
info.ve, 0
@@ -2557,11 +2644,12 @@ investments, 0
inzai.chiba.jp, 0
io, 0
ip6.arpa, 0
+ipiranga, 0
iq, 0
ir, 0
iraq.museum, 0
-irc.pl, 0
iris.arpa, 0
+irish, 0
irkutsk.ru, 0
iron.museum, 0
iruma.saitama.jp, 0
@@ -2664,6 +2752,8 @@ isla.pr, 0
isleofman.museum, 0
isshiki.aichi.jp, 0
issmarterthanyou.com, 4
+ist, 0
+istanbul, 0
isteingeek.de, 4
istmein.de, 4
isumi.chiba.jp, 0
@@ -2674,6 +2764,7 @@ itako.ibaraki.jp, 0
itakura.gunma.jp, 0
itami.hyogo.jp, 0
itano.tokushima.jp, 0
+itau, 0
itayanagi.aomori.jp, 0
ito.shizuoka.jp, 0
itoigawa.niigata.jp, 0
@@ -2697,6 +2788,7 @@ iwata.shizuoka.jp, 0
iwate.iwate.jp, 0
iwate.jp, 0
iwatsuki.saitama.jp, 0
+iwc, 0
iwi.nz, 0
iyo.ehime.jp, 0
iz.hr, 0
@@ -2716,6 +2808,7 @@ jamal.ru, 0
jamison.museum, 0
jan-mayen.no, 0
jar.ru, 0
+java, 0
jaworzno.pl, 0
je, 0
jefferson.museum, 0
@@ -2756,6 +2849,7 @@ joyo.kyoto.jp, 0
jp, 0
jp.net, 4
jpn.com, 4
+jprs, 0
js.cn, 0
judaica.museum, 0
judygarland.museum, 0
@@ -2798,7 +2892,6 @@ k12.mo.us, 0
k12.ms.us, 0
k12.mt.us, 0
k12.nc.us, 0
-k12.nd.us, 0
k12.ne.us, 0
k12.nh.us, 0
k12.nj.us, 0
@@ -2813,6 +2906,7 @@ k12.pr.us, 0
k12.ri.us, 0
k12.sc.us, 0
k12.tn.us, 0
+k12.tr, 0
k12.tx.us, 0
k12.ut.us, 0
k12.va.us, 0
@@ -2977,10 +3071,12 @@ kazimierz-dolny.pl, 0
kazo.saitama.jp, 0
kazuno.akita.jp, 0
kchr.ru, 0
+kddi, 0
ke, 2
keisen.fukuoka.jp, 0
kembuchi.hokkaido.jp, 0
kemerovo.ru, 0
+kep.tr, 0
kepno.pl, 0
kesennuma.miyagi.jp, 0
ketrzyn.pl, 0
@@ -3073,6 +3169,7 @@ kochi.jp, 0
kochi.kochi.jp, 0
kodaira.tokyo.jp, 0
koebenhavn.museum, 0
+koeln, 0
koeln.museum, 0
koenig.ru, 0
kofu.yamanashi.jp, 0
@@ -3136,7 +3233,7 @@ kr.it, 0
kr.ua, 0
kraanghke.no, 0
kragero.no, 0
-krakow.pl, 0
+krakow.pl, 4
krasnoyarsk.ru, 0
krd, 0
kred, 0
@@ -3248,7 +3345,9 @@ lardal.no, 0
larsson.museum, 0
larvik.no, 0
laspezia.it, 0
+lat, 0
latina.it, 0
+latrobe, 0
lavagis.no, 0
lavangen.no, 0
law.pro, 0
@@ -3268,7 +3367,9 @@ lebork.pl, 0
lebtimnetz.de, 4
lecce.it, 0
lecco.it, 0
+leclerc, 0
leg.br, 0
+legal, 0
legnica.pl, 0
leikanger.no, 0
leirfjord.no, 0
@@ -3288,6 +3389,7 @@ lg.ua, 0
lgbt, 0
li, 0
li.it, 0
+liaison, 0
lib.ak.us, 0
lib.al.us, 0
lib.ar.us, 0
@@ -3343,6 +3445,7 @@ lib.vt.us, 0
lib.wa.us, 0
lib.wi.us, 0
lib.wy.us, 0
+lidl, 0
lier.no, 0
lierne.no, 0
life, 0
@@ -3394,6 +3497,7 @@ ls, 0
lt, 0
lt.it, 0
lt.ua, 0
+ltd, 0
ltd.co.im, 0
ltd.gi, 0
ltd.lk, 0
@@ -3436,6 +3540,7 @@ magadan.ru, 0
magazine.aero, 0
magnitka.ru, 0
maibara.shiga.jp, 0
+maif, 0
mail.pl, 0
maintenance.aero, 0
maison, 0
@@ -3473,6 +3578,7 @@ market, 0
marketing, 0
marketplace.aero, 0
marnardal.no, 0
+marriott, 0
marugame.kagawa.jp, 0
marumori.miyagi.jp, 0
maryland.museum, 0
@@ -3509,7 +3615,6 @@ mazowsze.pl, 0
mazury.pl, 0
mb.ca, 0
mb.it, 0
-mbone.pl, 0
mc, 0
mc.it, 0
md, 0
@@ -3527,7 +3632,7 @@ med.ht, 0
med.ly, 0
med.om, 0
med.pa, 0
-med.pl, 0
+med.pl, 4
med.pro, 0
med.sa, 0
med.sd, 0
@@ -3553,6 +3658,7 @@ meldal.no, 0
melhus.no, 0
meloy.no, 0
meme, 0
+memorial, 0
memorial.museum, 0
menu, 0
meraker.no, 0
@@ -3640,6 +3746,7 @@ mil.sy, 0
mil.tj, 0
mil.tm, 0
mil.to, 0
+mil.tr, 0
mil.tw, 0
mil.tz, 0
mil.uy, 0
@@ -3770,8 +3877,10 @@ molise.it, 0
moma.museum, 0
mombetsu.hokkaido.jp, 0
monash, 0
+money, 0
money.museum, 0
monmouth.museum, 0
+montblanc, 0
monticello.museum, 0
montreal.museum, 0
monza-brianza.it, 0
@@ -3796,7 +3905,6 @@ moscow.museum, 0
moseushi.hokkaido.jp, 0
mosjoen.no, 0
moskenes.no, 0
-mosreg.ru, 0
moss.no, 0
mosvik.no, 0
motegi.tochigi.jp, 0
@@ -3806,6 +3914,7 @@ motorcycles, 0
motosu.gifu.jp, 0
motoyama.kochi.jp, 0
mov, 0
+movistar, 0
mp, 0
mp.br, 0
mq, 0
@@ -3925,6 +4034,7 @@ namdalseid.no, 0
name, 0
name.az, 0
name.eg, 0
+name.et, 0
name.hr, 0
name.jo, 0
name.mk, 0
@@ -3935,6 +4045,7 @@ name.ng, 0
name.pr, 0
name.qa, 0
name.tj, 0
+name.tr, 0
name.tt, 0
name.vn, 0
namegata.ibaraki.jp, 0
@@ -3993,6 +4104,7 @@ navy, 0
nayoro.hokkaido.jp, 0
nb.ca, 0
nc, 0
+nc.tr, 0
nc.us, 0
nd.us, 0
ne, 0
@@ -4120,6 +4232,7 @@ net.tj, 0
net.tm, 0
net.tn, 0
net.to, 0
+net.tr, 0
net.tt, 0
net.tw, 0
net.ua, 0
@@ -4132,6 +4245,7 @@ net.vi, 0
net.vn, 0
net.vu, 0
net.ws, 0
+netbank, 0
network, 0
neues.museum, 0
neustar, 0
@@ -4143,6 +4257,7 @@ newport.museum, 0
news.hu, 0
newspaper.museum, 0
newyork.museum, 0
+nexus, 0
neyagawa.osaka.jp, 0
nf, 0
nf.ca, 0
@@ -4151,14 +4266,12 @@ ng, 0
ngo, 0
ngo.lk, 0
ngo.ph, 0
-ngo.pl, 0
nh.us, 0
nhk, 0
nhs.uk, 0
ni, 2
nic.in, 0
nic.tj, 0
-nic.tr, 1
nichinan.miyazaki.jp, 0
nichinan.tottori.jp, 0
nid.io, 4
@@ -4224,7 +4337,7 @@ nogi.tochigi.jp, 0
noheji.aomori.jp, 0
nom.ad, 0
nom.ag, 0
-nom.br, 0
+nom.br, 2
nom.co, 0
nom.es, 0
nom.fr, 0
@@ -4264,6 +4377,7 @@ nov.ru, 0
novara.it, 0
novosibirsk.ru, 0
nowaruda.pl, 0
+nowruz, 0
nozawaonsen.nagano.jp, 0
np, 2
nr, 0
@@ -4281,6 +4395,7 @@ nt.edu.au, 0
nt.no, 0
nt.ro, 0
ntr.br, 0
+ntt, 0
nu, 0
nu.ca, 0
nu.it, 0
@@ -4307,6 +4422,7 @@ oarai.ibaraki.jp, 0
obama.fukui.jp, 0
obama.nagasaki.jp, 0
obanazawa.yamagata.jp, 0
+obi, 0
obihiro.hokkaido.jp, 0
obira.hokkaido.jp, 0
obu.aichi.jp, 0
@@ -4423,6 +4539,7 @@ onojo.fukuoka.jp, 0
onomichi.hiroshima.jp, 0
ontario.museum, 0
ookuwa.nagano.jp, 0
+ooo, 0
ooshika.nagano.jp, 0
openair.museum, 0
operaunite.com, 4
@@ -4446,6 +4563,7 @@ or.tz, 0
or.ug, 0
or.us, 0
ora.gunma.jp, 0
+oracle, 0
oregon.museum, 0
oregontrail.museum, 0
orenburg.ru, 0
@@ -4483,6 +4601,7 @@ org.ec, 0
org.ee, 0
org.eg, 0
org.es, 0
+org.et, 0
org.ge, 0
org.gg, 0
org.gh, 0
@@ -4569,6 +4688,7 @@ org.tj, 0
org.tm, 0
org.tn, 0
org.to, 0
+org.tr, 0
org.tt, 0
org.tw, 0
org.ua, 0
@@ -4592,6 +4712,7 @@ orsta.no, 0
oryol.ru, 0
os.hedmark.no, 0
os.hordaland.no, 0
+osaka, 0
osaka.jp, 0
osakasayama.osaka.jp, 0
osaki.miyagi.jp, 0
@@ -4677,9 +4798,11 @@ paris.museum, 0
parliament.nz, 0
parma.it, 0
paroch.k12.ma.us, 0
+pars, 0
parti.se, 0
partners, 0
parts, 0
+party, 0
pasadena.museum, 0
passenger-association.aero, 0
pavia.it, 0
@@ -4709,6 +4832,7 @@ pg.it, 0
ph, 0
pharmacien.fr, 0
pharmaciens.km, 0
+pharmacy, 0
pharmacy.museum, 0
philadelphia.museum, 0
philadelphiaarea.museum, 0
@@ -4721,7 +4845,9 @@ photos, 0
physio, 0
pi.it, 0
piacenza.it, 0
+piaget, 0
pics, 0
+pictet, 0
pictures, 0
piedmont.it, 0
piemonte.it, 0
@@ -4734,6 +4860,7 @@ pisa.it, 0
pistoia.it, 0
pisz.pl, 0
pittsburgh.museum, 0
+pizza, 0
pk, 0
pl, 0
pl.ua, 0
@@ -4757,14 +4884,18 @@ podhale.pl, 0
podlasie.pl, 0
podzone.net, 4
podzone.org, 4
+pohl, 0
+poker, 0
pol.dz, 0
pol.ht, 0
+pol.tr, 0
police.uk, 0
polkowice.pl, 0
poltava.ua, 0
pomorskie.pl, 0
pomorze.pl, 0
pordenone.it, 0
+porn, 0
porsanger.no, 0
porsangu.no, 0
porsgrunn.no, 0
@@ -4776,7 +4907,7 @@ post, 0
posts-and-telecommunications.museum, 0
potenza.it, 0
powiat.pl, 0
-poznan.pl, 0
+poznan.pl, 4
pp.az, 0
pp.ru, 0
pp.se, 0
@@ -4823,6 +4954,7 @@ prochowice.pl, 0
prod, 0
production.aero, 0
productions, 0
+prof, 0
prof.pr, 0
project.museum, 0
properties, 0
@@ -4902,6 +5034,7 @@ recipes, 0
recreation.aero, 0
red, 0
red.sv, 0
+redstone, 0
reggio-calabria.it, 0
reggio-emilia.it, 0
reggiocalabria.it, 0
@@ -4909,6 +5042,7 @@ reggioemilia.it, 0
rehab, 0
reise, 0
reisen, 0
+reit, 0
reklam.hu, 0
rel.ht, 0
rel.pl, 0
@@ -4928,6 +5062,7 @@ research.aero, 0
research.museum, 0
resistance.museum, 0
rest, 0
+restaurant, 0
reviews, 0
rg.it, 0
rhcloud.com, 4
@@ -4946,6 +5081,7 @@ ringerike.no, 0
ringsaker.no, 0
rio, 0
riodejaneiro.museum, 0
+rip, 0
rishiri.hokkaido.jp, 0
rishirifuji.hokkaido.jp, 0
risor.no, 0
@@ -5069,6 +5205,7 @@ sakurai.nara.jp, 0
sakyo.kyoto.jp, 0
salangen.no, 0
salat.no, 0
+sale, 0
salem.museum, 0
salerno.it, 0
saltdal.no, 0
@@ -5095,6 +5232,7 @@ sanjo.niigata.jp, 0
sannan.hyogo.jp, 0
sannohe.aomori.jp, 0
sano.tochigi.jp, 0
+sanofi, 0
sanok.pl, 0
santabarbara.museum, 0
santacruz.museum, 0
@@ -5107,6 +5245,7 @@ sar.it, 0
saratov.ru, 0
sardegna.it, 0
sardinia.it, 0
+sarl, 0
saroma.hokkaido.jp, 0
sarpsborg.no, 0
sarufutsu.hokkaido.jp, 0
@@ -5124,6 +5263,7 @@ sauherad.no, 0
savannahga.museum, 0
saves-the-whales.com, 4
savona.it, 0
+saxo, 0
sayama.osaka.jp, 0
sayama.saitama.jp, 0
sayo.hyogo.jp, 0
@@ -5156,8 +5296,10 @@ school.museum, 0
school.na, 0
school.nz, 0
schule, 0
+schwarz, 0
schweiz.museum, 0
sci.eg, 0
+science, 0
science-fiction.museum, 0
science.museum, 0
scienceandhistory.museum, 0
@@ -5168,6 +5310,7 @@ sciencehistory.museum, 0
sciences.museum, 0
sciencesnaturelles.museum, 0
scientist.aero, 0
+scor, 0
scot, 0
scotland.museum, 0
scrapper-site.net, 4
@@ -5207,6 +5350,7 @@ sellsyourhome.org, 4
semboku.akita.jp, 0
semine.miyagi.jp, 0
sendai.jp, 2
+sener, 0
sennan.osaka.jp, 0
seoul.kr, 0
sera.hiroshima.jp, 0
@@ -5217,6 +5361,7 @@ servebbs.org, 4
serveftp.net, 4
serveftp.org, 4
servegame.org, 4
+service.gov.uk, 4
services, 0
services.aero, 0
setagaya.tokyo.jp, 0
@@ -5226,6 +5371,7 @@ settlement.museum, 0
settlers.museum, 0
settsu.osaka.jp, 0
sevastopol.ua, 0
+sew, 0
sex.hu, 0
sex.pl, 0
sexy, 0
@@ -5239,6 +5385,7 @@ shari.hokkaido.jp, 0
sharp, 0
shell.museum, 0
sherbrooke.museum, 0
+shia, 0
shibata.miyagi.jp, 0
shibata.niigata.jp, 0
shibecha.hokkaido.jp, 0
@@ -5343,7 +5490,6 @@ sibenik.museum, 0
sic.it, 0
sicilia.it, 0
sicily.it, 0
-siedlce.pl, 0
siellak.no, 0
siena.it, 0
sigdal.no, 0
@@ -5373,6 +5519,7 @@ sklep.pl, 0
skoczow.pl, 0
skodje.no, 0
skole.museum, 0
+sky, 0
skydiving.aero, 0
sl, 0
slask.pl, 0
@@ -5421,7 +5568,7 @@ sondrio.it, 0
songdalen.no, 0
soni.nara.jp, 0
soo.kagoshima.jp, 0
-sopot.pl, 0
+sopot.pl, 4
sor-aurdal.no, 0
sor-fron.no, 0
sor-odal.no, 0
@@ -5472,6 +5619,8 @@ station.museum, 0
stavanger.no, 0
stavern.no, 0
stavropol.ru, 0
+stc, 0
+stcgroup, 0
steam.museum, 0
steiermark.museum, 0
steigen.no, 0
@@ -5523,6 +5672,7 @@ sunndal.no, 0
supplies, 0
supply, 0
support, 0
+surf, 0
surgeonshall.museum, 0
surgery, 0
surgut.ru, 0
@@ -5546,9 +5696,11 @@ sweden.museum, 0
swidnica.pl, 0
swiebodzin.pl, 0
swinoujscie.pl, 0
+swiss, 0
sx, 0
sx.cn, 0
sy, 0
+sydney, 0
sydney.museum, 0
sykkylven.no, 0
systems, 0
@@ -5577,6 +5729,7 @@ taiji.wakayama.jp, 0
taiki.hokkaido.jp, 0
taiki.mie.jp, 0
tainai.niigata.jp, 0
+taipei, 0
taira.toyama.jp, 0
taishi.hyogo.jp, 0
taishi.osaka.jp, 0
@@ -5663,6 +5816,7 @@ tax, 0
taxi.aero, 0
taxi.br, 0
tc, 0
+tci, 0
tcm.museum, 0
td, 0
te.it, 0
@@ -5672,9 +5826,12 @@ tec.ve, 0
technology, 0
technology.museum, 0
tel, 0
+tel.tr, 0
teledata.mz, 1
+telefonica, 0
telekommunikation.museum, 0
television.museum, 0
+temasek, 0
tempio-olbia.it, 0
tempioolbia.it, 0
tendo.yamagata.jp, 0
@@ -5826,7 +5983,7 @@ tozawa.yamagata.jp, 0
tozsde.hu, 0
tp, 0
tp.it, 0
-tr, 2
+tr, 0
tr.it, 0
tr.no, 0
tra.kp, 0
@@ -5880,6 +6037,7 @@ trolley.museum, 0
tromsa.no, 0
tromso.no, 0
trondheim.no, 0
+trust, 0
trust.museum, 0
trustee.museum, 0
trysil.no, 0
@@ -5915,6 +6073,7 @@ tsuwano.shimane.jp, 0
tsuyama.okayama.jp, 0
tt, 0
tt.im, 0
+tui, 0
tula.ru, 0
tur.ar, 0
tur.br, 0
@@ -5932,6 +6091,7 @@ tv.im, 0
tv.it, 0
tv.na, 0
tv.sd, 0
+tv.tr, 0
tv.tz, 0
tvedestrand.no, 0
tver.ru, 0
@@ -6028,7 +6188,6 @@ usarts.museum, 0
uscountryestate.museum, 0
usculture.museum, 0
usdecorativearts.museum, 0
-usenet.pl, 0
usgarden.museum, 0
ushiku.ibaraki.jp, 0
ushistory.museum, 0
@@ -6136,6 +6295,7 @@ vic.au, 0
vic.edu.au, 0
vic.gov.au, 0
vicenza.it, 0
+video, 0
video.hu, 0
vik.no, 0
viking.museum, 0
@@ -6145,10 +6305,13 @@ villas, 0
vindafjord.no, 0
vinnica.ua, 0
vinnytsia.ua, 0
+virgin, 0
virginia.museum, 0
virtual.museum, 0
virtuel.museum, 0
vision, 0
+vista, 0
+vistaprint, 0
viterbo.it, 0
vlaanderen, 0
vlaanderen.museum, 0
@@ -6222,6 +6385,7 @@ web.lk, 0
web.nf, 0
web.pk, 0
web.tj, 0
+web.tr, 0
web.ve, 0
webcam, 0
webhop.biz, 4
@@ -6257,9 +6421,10 @@ workinggroup.aero, 0
works, 0
works.aero, 0
workshop.museum, 0
+world, 0
worse-than.tv, 4
writesthisblog.com, 4
-wroc.pl, 0
+wroc.pl, 4
wroclaw.pl, 0
ws, 0
ws.na, 0
@@ -6271,29 +6436,49 @@ www.ro, 0
wy.us, 0
x.bg, 0
x.se, 0
+xerox, 0
xj.cn, 0
+xn--0trq7p7nn.jp, 0
+xn--1ctwo.jp, 0
+xn--1lqs03n.jp, 0
+xn--1lqs71d.jp, 0
xn--1qqw23a, 0
+xn--2m4a15e.jp, 0
+xn--30rr7y, 0
+xn--32vp30h.jp, 0
xn--3bst00m, 0
xn--3ds443g, 0
xn--3e0b707e, 0
xn--45brj9c, 0
xn--45q11c, 0
xn--4gbrim, 0
+xn--4it168d.jp, 0
+xn--4it797k.jp, 0
+xn--4pvxs.jp, 0
xn--54b7fta0cc, 0
xn--55qw42g, 0
xn--55qx5d, 0
xn--55qx5d.cn, 0
xn--55qx5d.hk, 0
+xn--5js045d.jp, 0
+xn--5rtp49c.jp, 0
+xn--5rtq34k.jp, 0
+xn--6btw5a.jp, 0
xn--6frz82g, 0
+xn--6orx2r.jp, 0
xn--6qq986b3xl, 0
+xn--7t0a264c.jp, 0
xn--80adxhks, 0
xn--80ao21a, 0
xn--80asehdb, 0
xn--80aswg, 0
xn--80au.xn--90a3ac, 0
+xn--8ltr62k.jp, 0
+xn--8pvr4u.jp, 0
xn--90a3ac, 0
xn--90azh.xn--90a3ac, 0
xn--9dbhblg6di.museum, 0
+xn--9et52u, 0
xn--andy-ira.no, 0
xn--aroport-bya.ci, 0
xn--asky-ira.no, 0
@@ -6301,6 +6486,7 @@ xn--aurskog-hland-jnb.no, 0
xn--avery-yua.no, 0
xn--b-5ga.nordland.no, 0
xn--b-5ga.telemark.no, 0
+xn--b4w605ferd, 0
xn--bdddj-mrabd.no, 0
xn--bearalvhki-y4a.no, 0
xn--berlevg-jxa.no, 0
@@ -6319,6 +6505,7 @@ xn--brum-voa.no, 0
xn--btsfjord-9za.no, 0
xn--c1avg, 0
xn--c1avg.xn--90a3ac, 0
+xn--c3s14m.jp, 0
xn--cg4bki, 0
xn--ciqpn.hk, 0
xn--clchc0ea0b2g2a9gcd, 0
@@ -6330,11 +6517,19 @@ xn--czru2d, 0
xn--czrw28b.tw, 0
xn--d1acj3b, 0
xn--d1at.xn--90a3ac, 0
+xn--d5qv7z876c.jp, 0
xn--davvenjrga-y4a.no, 0
+xn--djrs72d6uy.jp, 0
+xn--djty4k.jp, 0
xn--dnna-gra.no, 0
xn--drbak-wua.no, 0
xn--dyry-ira.no, 0
+xn--efvn9s.jp, 0
+xn--efvy88h, 0
+xn--ehqz56n.jp, 0
+xn--elqq16h.jp, 0
xn--eveni-0qa01ga.no, 0
+xn--f6qx53a.jp, 0
xn--finny-yua.no, 0
xn--fiq228c5hs, 0
xn--fiq64b, 0
@@ -6344,6 +6539,7 @@ xn--fjord-lra.no, 0
xn--fjq720a, 0
xn--fl-zia.no, 0
xn--flor-jra.no, 0
+xn--flw351e, 0
xn--fpcrj9c3d, 0
xn--frde-gra.no, 0
xn--frna-woa.no, 0
@@ -6382,9 +6578,15 @@ xn--j1amh, 0
xn--j6w193g, 0
xn--jlster-bya.no, 0
xn--jrpeland-54a.no, 0
+xn--k7yn95e.jp, 0
xn--karmy-yua.no, 0
+xn--kbrq7o.jp, 0
xn--kfjord-iua.no, 0
xn--klbu-woa.no, 0
+xn--klt787d.jp, 0
+xn--kltp7d.jp, 0
+xn--kltx9a.jp, 0
+xn--klty5x.jp, 0
xn--koluokta-7ya57h.no, 0
xn--kprw13d, 0
xn--kpry57d, 0
@@ -6434,10 +6636,12 @@ xn--mgberp4a5d4a87g, 0
xn--mgberp4a5d4ar, 0
xn--mgbqly7c0a67fbc, 0
xn--mgbqly7cvafr, 0
+xn--mgbt3dhd, 0
xn--mgbtf8fl, 0
xn--mgbx4cd0ab, 0
xn--mjndalen-64a.no, 0
xn--mk0axi.hk, 0
+xn--mkru45i.jp, 0
xn--mlatvuopmi-s4a.no, 0
xn--mli-tla.no, 0
xn--mlselv-iua.no, 0
@@ -6451,12 +6655,15 @@ xn--muost-0qa.no, 0
xn--mxtq1m, 0
xn--mxtq1m.hk, 0
xn--ngbc5azd, 0
+xn--nit225k.jp, 0
xn--nmesjevuemie-tcba.no, 0
xn--nnx388a, 0
xn--node, 0
xn--nqv7f, 0
xn--nqv7fs00ema, 0
xn--nry-yla5g.no, 0
+xn--ntso0iqx3a.jp, 0
+xn--ntsq17g.jp, 0
xn--nttery-byae.no, 0
xn--nvuotna-hwa.no, 0
xn--o1ac.xn--90a3ac, 0
@@ -6473,7 +6680,10 @@ xn--p1acf, 0
xn--p1ai, 0
xn--pgbs0dh, 0
xn--porsgu-sta26f.no, 0
+xn--pssu33l.jp, 0
xn--q9jyb4c, 0
+xn--qcka1pmc, 0
+xn--qqqt11m.jp, 0
xn--rady-ira.no, 0
xn--rdal-poa.no, 0
xn--rde-ula.no, 0
@@ -6482,11 +6692,15 @@ xn--rennesy-v1a.no, 0
xn--rhkkervju-01af.no, 0
xn--rholt-mra.no, 0
xn--rhqv96g, 0
+xn--rht27z.jp, 0
+xn--rht3d.jp, 0
+xn--rht61e.jp, 0
xn--risa-5na.no, 0
xn--risr-ira.no, 0
xn--rland-uua.no, 0
xn--rlingen-mxa.no, 0
xn--rmskog-bya.no, 0
+xn--rny31h.jp, 0
xn--rros-gra.no, 0
xn--rskog-uua.no, 0
xn--rst-0na.no, 0
@@ -6526,6 +6740,7 @@ xn--stre-toten-zcb.no, 0
xn--tjme-hra.no, 0
xn--tn0ag.hk, 0
xn--tnsberg-q1a.no, 0
+xn--tor131o.jp, 0
xn--trany-yua.no, 0
xn--trgstad-r1a.no, 0
xn--trna-woa.no, 0
@@ -6534,21 +6749,28 @@ xn--tysvr-vra.no, 0
xn--uc0atv.hk, 0
xn--uc0atv.tw, 0
xn--uc0ay4a.hk, 0
+xn--uist22h.jp, 0
+xn--uisz3g.jp, 0
xn--unjrga-rta.no, 0
xn--unup4y, 0
+xn--uuwu58a.jp, 0
xn--vads-jra.no, 0
xn--vard-jra.no, 0
xn--vegrshei-c0a.no, 0
+xn--vermgensberater-ctb, 0
+xn--vermgensberatung-pwb, 0
xn--vestvgy-ixa6o.no, 0
xn--vg-yiab.no, 0
xn--vgan-qoa.no, 0
xn--vgsy-qoa0j.no, 0
+xn--vgu402c.jp, 0
xn--vhquv, 0
xn--vler-qoa.hedmark.no, 0
xn--vler-qoa.xn--stfold-9xa.no, 0
xn--vre-eiker-k8a.no, 0
xn--vrggt-xqad.no, 0
xn--vry-yla5g.no, 0
+xn--vuq861b, 0
xn--wcvs22d.hk, 0
xn--wgbh1c, 0
xn--wgbl6a, 0
@@ -6560,6 +6782,7 @@ xn--yfro4i67o, 0
xn--ygarden-p1a.no, 0
xn--ygbi2ammx, 0
xn--ystre-slidre-ujb.no, 0
+xn--zbx025d.jp, 0
xn--zf0ao64a.tw, 0
xn--zf0avx.hk, 0
xn--zfr164b, 0
@@ -6648,6 +6871,7 @@ yokoshibahikari.chiba.jp, 0
yokosuka.kanagawa.jp, 0
yokote.akita.jp, 0
yokoze.saitama.jp, 0
+yolasite.com, 4
yomitan.okinawa.jp, 0
yonabaru.okinawa.jp, 0
yonago.tottori.jp, 0
@@ -6695,7 +6919,7 @@ za.net, 4
za.org, 4
zachpomor.pl, 0
zagan.pl, 0
-zakopane.pl, 0
+zakopane.pl, 4
zama.kanagawa.jp, 0
zamami.okinawa.jp, 0
zao.miyagi.jp, 0
diff --git a/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc b/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc
index 7a4a5283a81..22bd963ad4b 100644
--- a/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc
+++ b/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc
@@ -82,7 +82,7 @@ class RegistryControlledDomainTest : public testing::Test {
SetFindDomainGraph(graph, sizeof(Graph));
}
- virtual void TearDown() { SetFindDomainGraph(); }
+ void TearDown() override { SetFindDomainGraph(); }
};
TEST_F(RegistryControlledDomainTest, TestGetDomainAndRegistry) {
diff --git a/chromium/net/base/request_priority.h b/chromium/net/base/request_priority.h
index e663610fff4..dcf77936423 100644
--- a/chromium/net/base/request_priority.h
+++ b/chromium/net/base/request_priority.h
@@ -11,6 +11,10 @@ namespace net {
// Prioritization used in various parts of the networking code such
// as connection prioritization and resource loading prioritization.
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: RequestPriority
+// GENERATED_JAVA_PREFIX_TO_STRIP:
enum RequestPriority {
IDLE = 0,
MINIMUM_PRIORITY = IDLE,
diff --git a/chromium/net/base/sdch_dictionary_fetcher.cc b/chromium/net/base/sdch_dictionary_fetcher.cc
deleted file mode 100644
index aa2061eba8e..00000000000
--- a/chromium/net/base/sdch_dictionary_fetcher.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2014 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/sdch_dictionary_fetcher.h"
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
-#include "net/base/load_flags.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_status.h"
-
-namespace net {
-
-SdchDictionaryFetcher::SdchDictionaryFetcher(
- SdchManager* manager,
- URLRequestContextGetter* context)
- : manager_(manager),
- weak_factory_(this),
- task_is_pending_(false),
- context_(context) {
- DCHECK(CalledOnValidThread());
- DCHECK(manager);
-}
-
-SdchDictionaryFetcher::~SdchDictionaryFetcher() {
- DCHECK(CalledOnValidThread());
-}
-
-void SdchDictionaryFetcher::Schedule(const GURL& dictionary_url) {
- DCHECK(CalledOnValidThread());
-
- // Avoid pushing duplicate copy onto queue. We may fetch this url again later
- // and get a different dictionary, but there is no reason to have it in the
- // queue twice at one time.
- if (!fetch_queue_.empty() && fetch_queue_.back() == dictionary_url) {
- SdchManager::SdchErrorRecovery(
- SdchManager::DICTIONARY_ALREADY_SCHEDULED_TO_DOWNLOAD);
- return;
- }
- if (attempted_load_.find(dictionary_url) != attempted_load_.end()) {
- SdchManager::SdchErrorRecovery(
- SdchManager::DICTIONARY_ALREADY_TRIED_TO_DOWNLOAD);
- return;
- }
- attempted_load_.insert(dictionary_url);
- fetch_queue_.push(dictionary_url);
- ScheduleDelayedRun();
-}
-
-void SdchDictionaryFetcher::Cancel() {
- DCHECK(CalledOnValidThread());
-
- while (!fetch_queue_.empty())
- fetch_queue_.pop();
- attempted_load_.clear();
- weak_factory_.InvalidateWeakPtrs();
- current_fetch_.reset(NULL);
-}
-
-void SdchDictionaryFetcher::ScheduleDelayedRun() {
- if (fetch_queue_.empty() || current_fetch_.get() || task_is_pending_)
- return;
- base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
- base::Bind(&SdchDictionaryFetcher::StartFetching,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kMsDelayFromRequestTillDownload));
- task_is_pending_ = true;
-}
-
-void SdchDictionaryFetcher::StartFetching() {
- DCHECK(CalledOnValidThread());
- DCHECK(task_is_pending_);
- task_is_pending_ = false;
-
- // Handle losing the race against Cancel().
- if (fetch_queue_.empty())
- return;
-
- DCHECK(context_.get());
- current_fetch_.reset(URLFetcher::Create(
- fetch_queue_.front(), URLFetcher::GET, this));
- fetch_queue_.pop();
- current_fetch_->SetRequestContext(context_.get());
- current_fetch_->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES |
- LOAD_DO_NOT_SAVE_COOKIES);
- current_fetch_->Start();
-}
-
-void SdchDictionaryFetcher::OnURLFetchComplete(
- const URLFetcher* source) {
- DCHECK(CalledOnValidThread());
- if ((200 == source->GetResponseCode()) &&
- (source->GetStatus().status() == URLRequestStatus::SUCCESS)) {
- std::string data;
- source->GetResponseAsString(&data);
- manager_->AddSdchDictionary(data, source->GetURL());
- }
- current_fetch_.reset(NULL);
- ScheduleDelayedRun();
-}
-
-} // namespace net
diff --git a/chromium/net/base/sdch_dictionary_fetcher.h b/chromium/net/base/sdch_dictionary_fetcher.h
deleted file mode 100644
index b657b8f80c3..00000000000
--- a/chromium/net/base/sdch_dictionary_fetcher.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2014 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.
-
-// Support modularity by calling to load a new SDCH filter dictionary.
-// Note that this sort of calling can't be done in the /net directory, as it has
-// no concept of the HTTP cache (which is only visible at the browser level).
-
-#ifndef NET_BASE_SDCH_DICTIONARY_FETCHER_H_
-#define NET_BASE_SDCH_DICTIONARY_FETCHER_H_
-
-#include <queue>
-#include <set>
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/non_thread_safe.h"
-#include "net/base/sdch_manager.h"
-#include "net/url_request/url_fetcher_delegate.h"
-
-namespace net {
-
-class URLFetcher;
-class URLRequestContextGetter;
-
-class NET_EXPORT SdchDictionaryFetcher
- : public URLFetcherDelegate,
- public SdchFetcher,
- public base::NonThreadSafe {
- public:
- // Consumer must guarantee that the SdchManager pointer outlives
- // this object. The current implementation guarantees this by
- // the SdchManager owning this object.
- SdchDictionaryFetcher(SdchManager* manager,
- URLRequestContextGetter* context);
- virtual ~SdchDictionaryFetcher();
-
- // Implementation of SdchFetcher class.
- virtual void Schedule(const GURL& dictionary_url) OVERRIDE;
- virtual void Cancel() OVERRIDE;
-
- private:
- // Delay in ms between Schedule and actual download.
- // This leaves the URL in a queue, which is de-duped, so that there is less
- // chance we'll try to load the same URL multiple times when a pile of
- // page subresources (or tabs opened in parallel) all suggest the dictionary.
- static const int kMsDelayFromRequestTillDownload = 100;
-
- // Ensure the download after the above delay.
- void ScheduleDelayedRun();
-
- // Make sure we're processing (or waiting for) the the arrival of the next URL
- // in the |fetch_queue_|.
- void StartFetching();
-
- // Implementation of URLFetcherDelegate. Called after transmission
- // completes (either successfully or with failure).
- virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
-
- SdchManager* const manager_;
-
- // A queue of URLs that are being used to download dictionaries.
- std::queue<GURL> fetch_queue_;
- // The currently outstanding URL fetch of a dicitonary.
- // If this is null, then there is no outstanding request.
- scoped_ptr<URLFetcher> current_fetch_;
-
- // Always spread out the dictionary fetches, so that they don't steal
- // bandwidth from the actual page load. Create delayed tasks to spread out
- // the download.
- base::WeakPtrFactory<SdchDictionaryFetcher> weak_factory_;
- bool task_is_pending_;
-
- // Althought the SDCH spec does not preclude a server from using a single URL
- // to load several distinct dictionaries (by telling a client to load a
- // dictionary from an URL several times), current implementations seem to have
- // that 1-1 relationship (i.e., each URL points at a single dictionary, and
- // the dictionary content does not change over time, and hence is not worth
- // trying to load more than once). In addition, some dictionaries prove
- // unloadable only after downloading them (because they are too large? ...or
- // malformed?). As a protective element, Chromium will *only* load a
- // dictionary at most once from a given URL (so that it doesn't waste
- // bandwidth trying repeatedly).
- // The following set lists all the dictionary URLs that we've tried to load,
- // so that we won't try to load from an URL more than once.
- // TODO(jar): Try to augment the SDCH proposal to include this restiction.
- std::set<GURL> attempted_load_;
-
- // Store the system_url_request_context_getter to use it when we start
- // fetching.
- scoped_refptr<URLRequestContextGetter> context_;
-
- DISALLOW_COPY_AND_ASSIGN(SdchDictionaryFetcher);
-};
-
-} // namespace net
-
-#endif // NET_BASE_SDCH_DICTIONARY_FETCHER_H_
diff --git a/chromium/net/base/sdch_manager.cc b/chromium/net/base/sdch_manager.cc
index 8892c13a7c4..1285ad9383a 100644
--- a/chromium/net/base/sdch_manager.cc
+++ b/chromium/net/base/sdch_manager.cc
@@ -11,8 +11,30 @@
#include "base/strings/string_util.h"
#include "crypto/sha2.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "net/base/sdch_observer.h"
#include "net/url_request/url_request_http_job.h"
+namespace {
+
+void StripTrailingDot(GURL* gurl) {
+ std::string host(gurl->host());
+
+ if (host.empty())
+ return;
+
+ if (*host.rbegin() != '.')
+ return;
+
+ host.resize(host.size() - 1);
+
+ GURL::Replacements replacements;
+ replacements.SetHostStr(host);
+ *gurl = gurl->ReplaceComponents(replacements);
+ return;
+}
+
+} // namespace
+
namespace net {
//------------------------------------------------------------------------------
@@ -22,7 +44,7 @@ namespace net {
#if defined(OS_ANDROID) || defined(OS_IOS)
// static
const size_t SdchManager::kMaxDictionaryCount = 1;
-const size_t SdchManager::kMaxDictionarySize = 150 * 1000;
+const size_t SdchManager::kMaxDictionarySize = 500 * 1000;
#else
// static
const size_t SdchManager::kMaxDictionaryCount = 20;
@@ -33,7 +55,7 @@ const size_t SdchManager::kMaxDictionarySize = 1000 * 1000;
bool SdchManager::g_sdch_enabled_ = true;
// static
-bool SdchManager::g_secure_scheme_supported_ = false;
+bool SdchManager::g_secure_scheme_supported_ = true;
//------------------------------------------------------------------------------
SdchManager::Dictionary::Dictionary(const std::string& dictionary_text,
@@ -69,7 +91,8 @@ bool SdchManager::Dictionary::CanAdvertise(const GURL& target_url) {
3. The request URI path-matches the path header of the dictionary.
4. The request is not an HTTPS request.
We can override (ignore) item (4) only when we have explicitly enabled
- HTTPS support AND dictionary has been acquired over HTTPS.
+ HTTPS support AND the dictionary acquisition scheme matches the target
+ url scheme.
*/
if (!DomainMatch(target_url, domain_))
return false;
@@ -79,7 +102,7 @@ bool SdchManager::Dictionary::CanAdvertise(const GURL& target_url) {
return false;
if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
return false;
- if (target_url.SchemeIsSecure() && !url_.SchemeIsSecure())
+ if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
return false;
if (base::Time::Now() > expiration_)
return false;
@@ -158,8 +181,9 @@ bool SdchManager::Dictionary::CanUse(const GURL& referring_url) {
3. The request URL path-matches the path attribute of the dictionary.
4. The request is not an HTTPS request.
We can override (ignore) item (4) only when we have explicitly enabled
- HTTPS support AND dictionary has been acquired over HTTPS.
-*/
+ HTTPS support AND the dictionary acquisition scheme matches the target
+ url scheme.
+ */
if (!DomainMatch(referring_url, domain_)) {
SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_DOMAIN);
return false;
@@ -178,7 +202,7 @@ bool SdchManager::Dictionary::CanUse(const GURL& referring_url) {
SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME);
return false;
}
- if (referring_url.SchemeIsSecure() && !url_.SchemeIsSecure()) {
+ if (referring_url.SchemeIsSecure() != url_.SchemeIsSecure()) {
SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME);
return false;
}
@@ -219,11 +243,11 @@ bool SdchManager::Dictionary::DomainMatch(const GURL& gurl,
//------------------------------------------------------------------------------
SdchManager::SdchManager() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
}
SdchManager::~SdchManager() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
while (!dictionaries_.empty()) {
DictionaryMap::iterator it = dictionaries_.begin();
dictionaries_.erase(it->first);
@@ -232,16 +256,15 @@ SdchManager::~SdchManager() {
void SdchManager::ClearData() {
blacklisted_domains_.clear();
- exponential_blacklist_count_.clear();
allow_latency_experiment_.clear();
- if (fetcher_.get())
- fetcher_->Cancel();
// Note that this may result in not having dictionaries we've advertised
// for incoming responses. The window is relatively small (as ClearData()
// is not expected to be called frequently), so we rely on meta-refresh
// to handle this case.
dictionaries_.clear();
+
+ FOR_EACH_OBSERVER(SdchObserver, observers_, OnClearDictionaries(this));
}
// static
@@ -249,11 +272,6 @@ void SdchManager::SdchErrorRecovery(ProblemCodes problem) {
UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE);
}
-void SdchManager::set_sdch_fetcher(SdchFetcher* fetcher) {
- DCHECK(CalledOnValidThread());
- fetcher_.reset(fetcher);
-}
-
// static
void SdchManager::EnableSdchSupport(bool enabled) {
g_sdch_enabled_ = enabled;
@@ -264,55 +282,67 @@ void SdchManager::EnableSecureSchemeSupport(bool enabled) {
g_secure_scheme_supported_ = enabled;
}
-void SdchManager::BlacklistDomain(const GURL& url) {
+void SdchManager::BlacklistDomain(const GURL& url,
+ ProblemCodes blacklist_reason) {
SetAllowLatencyExperiment(url, false);
- std::string domain(StringToLowerASCII(url.host()));
- int count = blacklisted_domains_[domain];
- if (count > 0)
+ BlacklistInfo* blacklist_info =
+ &blacklisted_domains_[base::StringToLowerASCII(url.host())];
+
+ if (blacklist_info->count > 0)
return; // Domain is already blacklisted.
- count = 1 + 2 * exponential_blacklist_count_[domain];
- if (count > 0)
- exponential_blacklist_count_[domain] = count;
- else
- count = INT_MAX;
+ if (blacklist_info->exponential_count > (INT_MAX - 1) / 2) {
+ blacklist_info->exponential_count = INT_MAX;
+ } else {
+ blacklist_info->exponential_count =
+ blacklist_info->exponential_count * 2 + 1;
+ }
- blacklisted_domains_[domain] = count;
+ blacklist_info->count = blacklist_info->exponential_count;
+ blacklist_info->reason = blacklist_reason;
}
-void SdchManager::BlacklistDomainForever(const GURL& url) {
+void SdchManager::BlacklistDomainForever(const GURL& url,
+ ProblemCodes blacklist_reason) {
SetAllowLatencyExperiment(url, false);
- std::string domain(StringToLowerASCII(url.host()));
- exponential_blacklist_count_[domain] = INT_MAX;
- blacklisted_domains_[domain] = INT_MAX;
+ BlacklistInfo* blacklist_info =
+ &blacklisted_domains_[base::StringToLowerASCII(url.host())];
+ blacklist_info->count = INT_MAX;
+ blacklist_info->exponential_count = INT_MAX;
+ blacklist_info->reason = blacklist_reason;
}
void SdchManager::ClearBlacklistings() {
blacklisted_domains_.clear();
- exponential_blacklist_count_.clear();
}
void SdchManager::ClearDomainBlacklisting(const std::string& domain) {
- blacklisted_domains_.erase(StringToLowerASCII(domain));
+ BlacklistInfo* blacklist_info = &blacklisted_domains_[
+ base::StringToLowerASCII(domain)];
+ blacklist_info->count = 0;
+ blacklist_info->reason = MIN_PROBLEM_CODE;
}
int SdchManager::BlackListDomainCount(const std::string& domain) {
- if (blacklisted_domains_.end() == blacklisted_domains_.find(domain))
+ std::string domain_lower(base::StringToLowerASCII(domain));
+
+ if (blacklisted_domains_.end() == blacklisted_domains_.find(domain_lower))
return 0;
- return blacklisted_domains_[StringToLowerASCII(domain)];
+ return blacklisted_domains_[domain_lower].count;
}
int SdchManager::BlacklistDomainExponential(const std::string& domain) {
- if (exponential_blacklist_count_.end() ==
- exponential_blacklist_count_.find(domain))
+ std::string domain_lower(base::StringToLowerASCII(domain));
+
+ if (blacklisted_domains_.end() == blacklisted_domains_.find(domain_lower))
return 0;
- return exponential_blacklist_count_[StringToLowerASCII(domain)];
+ return blacklisted_domains_[domain_lower].exponential_count;
}
bool SdchManager::IsInSupportedDomain(const GURL& url) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
if (!g_sdch_enabled_ )
return false;
@@ -322,30 +352,39 @@ bool SdchManager::IsInSupportedDomain(const GURL& url) {
if (blacklisted_domains_.empty())
return true;
- std::string domain(StringToLowerASCII(url.host()));
- DomainCounter::iterator it = blacklisted_domains_.find(domain);
- if (blacklisted_domains_.end() == it)
+ DomainBlacklistInfo::iterator it =
+ blacklisted_domains_.find(base::StringToLowerASCII(url.host()));
+ if (blacklisted_domains_.end() == it || it->second.count == 0)
return true;
- int count = it->second - 1;
- if (count > 0)
- blacklisted_domains_[domain] = count;
- else
- blacklisted_domains_.erase(domain);
+ UMA_HISTOGRAM_ENUMERATION("Sdch3.BlacklistReason", it->second.reason,
+ MAX_PROBLEM_CODE);
SdchErrorRecovery(DOMAIN_BLACKLIST_INCLUDES_TARGET);
+
+ int count = it->second.count - 1;
+ if (count > 0) {
+ it->second.count = count;
+ } else {
+ it->second.count = 0;
+ it->second.reason = MIN_PROBLEM_CODE;
+ }
+
return false;
}
-void SdchManager::FetchDictionary(const GURL& request_url,
+void SdchManager::OnGetDictionary(const GURL& request_url,
const GURL& dictionary_url) {
- DCHECK(CalledOnValidThread());
- if (CanFetchDictionary(request_url, dictionary_url) && fetcher_.get())
- fetcher_->Schedule(dictionary_url);
+ if (!CanFetchDictionary(request_url, dictionary_url))
+ return;
+
+ FOR_EACH_OBSERVER(SdchObserver,
+ observers_,
+ OnGetDictionary(this, request_url, dictionary_url));
}
bool SdchManager::CanFetchDictionary(const GURL& referring_url,
const GURL& dictionary_url) const {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
/* The user agent may retrieve a dictionary from the dictionary URL if all of
the following are true:
1 The dictionary URL host name matches the referrer URL host name and
@@ -354,7 +393,6 @@ bool SdchManager::CanFetchDictionary(const GURL& referring_url,
referrer URL host name
3 The parent domain of the referrer URL host name is not a top level
domain
- 4 The dictionary URL is not an HTTPS URL.
*/
// Item (1) above implies item (2). Spec should be updated.
// I take "host name match" to be "is identical to"
@@ -378,15 +416,101 @@ bool SdchManager::CanFetchDictionary(const GURL& referring_url,
return true;
}
-bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
+void SdchManager::GetVcdiffDictionary(
+ const std::string& server_hash,
+ const GURL& referring_url,
+ scoped_refptr<Dictionary>* dictionary) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ *dictionary = NULL;
+ DictionaryMap::iterator it = dictionaries_.find(server_hash);
+ if (it == dictionaries_.end()) {
+ return;
+ }
+ scoped_refptr<Dictionary> matching_dictionary = it->second;
+ if (!IsInSupportedDomain(referring_url))
+ return;
+ if (!matching_dictionary->CanUse(referring_url))
+ return;
+ *dictionary = matching_dictionary;
+}
+
+// TODO(jar): If we have evictions from the dictionaries_, then we need to
+// change this interface to return a list of reference counted Dictionary
+// instances that can be used if/when a server specifies one.
+void SdchManager::GetAvailDictionaryList(const GURL& target_url,
+ std::string* list) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ int count = 0;
+ for (DictionaryMap::iterator it = dictionaries_.begin();
+ it != dictionaries_.end(); ++it) {
+ if (!IsInSupportedDomain(target_url))
+ continue;
+ if (!it->second->CanAdvertise(target_url))
+ continue;
+ ++count;
+ if (!list->empty())
+ list->append(",");
+ list->append(it->second->client_hash());
+ }
+ // Watch to see if we have corrupt or numerous dictionaries.
+ if (count > 0)
+ UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
+}
+
+// static
+void SdchManager::GenerateHash(const std::string& dictionary_text,
+ std::string* client_hash, std::string* server_hash) {
+ char binary_hash[32];
+ crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash));
+
+ std::string first_48_bits(&binary_hash[0], 6);
+ std::string second_48_bits(&binary_hash[6], 6);
+ UrlSafeBase64Encode(first_48_bits, client_hash);
+ UrlSafeBase64Encode(second_48_bits, server_hash);
+
+ DCHECK_EQ(server_hash->length(), 8u);
+ DCHECK_EQ(client_hash->length(), 8u);
+}
+
+//------------------------------------------------------------------------------
+// Methods for supporting latency experiments.
+
+bool SdchManager::AllowLatencyExperiment(const GURL& url) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return allow_latency_experiment_.end() !=
+ allow_latency_experiment_.find(url.host());
+}
+
+void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (enable) {
+ allow_latency_experiment_.insert(url.host());
+ return;
+ }
+ ExperimentSet::iterator it = allow_latency_experiment_.find(url.host());
+ if (allow_latency_experiment_.end() == it)
+ return; // It was already erased, or never allowed.
+ SdchErrorRecovery(LATENCY_TEST_DISALLOWED);
+ allow_latency_experiment_.erase(it);
+}
+
+void SdchManager::AddObserver(SdchObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void SdchManager::RemoveObserver(SdchObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void SdchManager::AddSdchDictionary(const std::string& dictionary_text,
const GURL& dictionary_url) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
std::string client_hash;
std::string server_hash;
GenerateHash(dictionary_text, &client_hash, &server_hash);
if (dictionaries_.find(server_hash) != dictionaries_.end()) {
SdchErrorRecovery(DICTIONARY_ALREADY_LOADED);
- return false; // Already loaded.
+ return; // Already loaded.
}
std::string domain, path;
@@ -395,13 +519,13 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
if (dictionary_text.empty()) {
SdchErrorRecovery(DICTIONARY_HAS_NO_TEXT);
- return false; // Missing header.
+ return; // Missing header.
}
size_t header_end = dictionary_text.find("\n\n");
if (std::string::npos == header_end) {
SdchErrorRecovery(DICTIONARY_HAS_NO_HEADER);
- return false; // Missing header.
+ return; // Missing header.
}
size_t line_start = 0; // Start of line being parsed.
while (1) {
@@ -412,7 +536,7 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
size_t colon_index = dictionary_text.find(':', line_start);
if (std::string::npos == colon_index) {
SdchErrorRecovery(DICTIONARY_HEADER_LINE_MISSING_COLON);
- return false; // Illegal line missing a colon.
+ return; // Illegal line missing a colon.
}
if (colon_index > line_end)
@@ -425,14 +549,14 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
break;
std::string name(dictionary_text, line_start, colon_index - line_start);
std::string value(dictionary_text, value_start, line_end - value_start);
- name = StringToLowerASCII(name);
+ name = base::StringToLowerASCII(name);
if (name == "domain") {
domain = value;
} else if (name == "path") {
path = value;
} else if (name == "format-version") {
if (value != "1.0")
- return false;
+ return;
} else if (name == "max-age") {
int64 seconds;
base::StringToInt64(value, &seconds);
@@ -450,11 +574,15 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
line_start = line_end + 1;
}
- if (!IsInSupportedDomain(dictionary_url))
- return false;
+ // Narrow fix for http://crbug.com/389451.
+ GURL dictionary_url_normalized(dictionary_url);
+ StripTrailingDot(&dictionary_url_normalized);
- if (!Dictionary::CanSet(domain, path, ports, dictionary_url))
- return false;
+ if (!IsInSupportedDomain(dictionary_url_normalized))
+ return;
+
+ if (!Dictionary::CanSet(domain, path, ports, dictionary_url_normalized))
+ return;
// TODO(jar): Remove these hacks to preclude a DOS attack involving piles of
// useless dictionaries. We should probably have a cache eviction plan,
@@ -462,11 +590,11 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
// is probably not worth doing eviction handling.
if (kMaxDictionarySize < dictionary_text.size()) {
SdchErrorRecovery(DICTIONARY_IS_TOO_LARGE);
- return false;
+ return;
}
if (kMaxDictionaryCount <= dictionaries_.size()) {
SdchErrorRecovery(DICTIONARY_COUNT_EXCEEDED);
- return false;
+ return;
}
UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size());
@@ -474,87 +602,10 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
<< " and server hash " << server_hash;
Dictionary* dictionary =
new Dictionary(dictionary_text, header_end + 2, client_hash,
- dictionary_url, domain, path, expiration, ports);
+ dictionary_url_normalized, domain,
+ path, expiration, ports);
dictionaries_[server_hash] = dictionary;
- return true;
-}
-
-void SdchManager::GetVcdiffDictionary(
- const std::string& server_hash,
- const GURL& referring_url,
- scoped_refptr<Dictionary>* dictionary) {
- DCHECK(CalledOnValidThread());
- *dictionary = NULL;
- DictionaryMap::iterator it = dictionaries_.find(server_hash);
- if (it == dictionaries_.end()) {
- return;
- }
- scoped_refptr<Dictionary> matching_dictionary = it->second;
- if (!IsInSupportedDomain(referring_url))
- return;
- if (!matching_dictionary->CanUse(referring_url))
- return;
- *dictionary = matching_dictionary;
-}
-
-// TODO(jar): If we have evictions from the dictionaries_, then we need to
-// change this interface to return a list of reference counted Dictionary
-// instances that can be used if/when a server specifies one.
-void SdchManager::GetAvailDictionaryList(const GURL& target_url,
- std::string* list) {
- DCHECK(CalledOnValidThread());
- int count = 0;
- for (DictionaryMap::iterator it = dictionaries_.begin();
- it != dictionaries_.end(); ++it) {
- if (!IsInSupportedDomain(target_url))
- continue;
- if (!it->second->CanAdvertise(target_url))
- continue;
- ++count;
- if (!list->empty())
- list->append(",");
- list->append(it->second->client_hash());
- }
- // Watch to see if we have corrupt or numerous dictionaries.
- if (count > 0)
- UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
-}
-
-// static
-void SdchManager::GenerateHash(const std::string& dictionary_text,
- std::string* client_hash, std::string* server_hash) {
- char binary_hash[32];
- crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash));
-
- std::string first_48_bits(&binary_hash[0], 6);
- std::string second_48_bits(&binary_hash[6], 6);
- UrlSafeBase64Encode(first_48_bits, client_hash);
- UrlSafeBase64Encode(second_48_bits, server_hash);
-
- DCHECK_EQ(server_hash->length(), 8u);
- DCHECK_EQ(client_hash->length(), 8u);
-}
-
-//------------------------------------------------------------------------------
-// Methods for supporting latency experiments.
-
-bool SdchManager::AllowLatencyExperiment(const GURL& url) const {
- DCHECK(CalledOnValidThread());
- return allow_latency_experiment_.end() !=
- allow_latency_experiment_.find(url.host());
-}
-
-void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) {
- DCHECK(CalledOnValidThread());
- if (enable) {
- allow_latency_experiment_.insert(url.host());
- return;
- }
- ExperimentSet::iterator it = allow_latency_experiment_.find(url.host());
- if (allow_latency_experiment_.end() == it)
- return; // It was already erased, or never allowed.
- SdchErrorRecovery(LATENCY_TEST_DISALLOWED);
- allow_latency_experiment_.erase(it);
+ return;
}
// static
@@ -563,18 +614,8 @@ void SdchManager::UrlSafeBase64Encode(const std::string& input,
// Since this is only done during a dictionary load, and hashes are only 8
// characters, we just do the simple fixup, rather than rewriting the encoder.
base::Base64Encode(input, output);
- for (size_t i = 0; i < output->size(); ++i) {
- switch (output->data()[i]) {
- case '+':
- (*output)[i] = '-';
- continue;
- case '/':
- (*output)[i] = '_';
- continue;
- default:
- continue;
- }
- }
+ std::replace(output->begin(), output->end(), '+', '-');
+ std::replace(output->begin(), output->end(), '/', '_');
}
} // namespace net
diff --git a/chromium/net/base/sdch_manager.h b/chromium/net/base/sdch_manager.h
index 6f2ea5af6de..ff157e52a32 100644
--- a/chromium/net/base/sdch_manager.h
+++ b/chromium/net/base/sdch_manager.h
@@ -2,21 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Provides global database of differential decompression dictionaries for the
-// SDCH filter (processes sdch enconded content).
-
-// Exactly one instance of SdchManager is built, and all references are made
-// into that collection.
-//
-// The SdchManager maintains a collection of memory resident dictionaries. It
-// can find a dictionary (based on a server specification of a hash), store a
-// dictionary, and make judgements about what URLs can use, set, etc. a
-// dictionary.
-
-// These dictionaries are acquired over the net, and include a header
-// (containing metadata) as well as a VCDIFF dictionary (for use by a VCDIFF
-// module) to decompress data.
-
#ifndef NET_BASE_SDCH_MANAGER_H_
#define NET_BASE_SDCH_MANAGER_H_
@@ -27,40 +12,28 @@
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/observer_list.h"
+#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "url/gurl.h"
namespace net {
-//------------------------------------------------------------------------------
-// Create a public interface to help us load SDCH dictionaries.
-// The SdchManager class allows registration to support this interface.
-// A browser may register a fetcher that is used by the dictionary managers to
-// get data from a specified URL. This allows us to use very high level browser
-// functionality in this base (when the functionaity can be provided).
-class NET_EXPORT SdchFetcher {
- public:
- SdchFetcher() {}
- virtual ~SdchFetcher() {}
-
- // The Schedule() method is called when there is a need to get a dictionary
- // from a server. The callee is responsible for getting that dictionary_text,
- // and then calling back to AddSdchDictionary() to the SdchManager instance.
- virtual void Schedule(const GURL& dictionary_url) = 0;
-
- // The Cancel() method is called to cancel all pending dictionary fetches.
- // This is used for implementation of ClearData() below.
- virtual void Cancel() = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SdchFetcher);
-};
+class SdchObserver;
-//------------------------------------------------------------------------------
+// Provides global database of differential decompression dictionaries for the
+// SDCH filter (processes sdch enconded content).
+//
+// The SdchManager maintains a collection of memory resident dictionaries. It
+// can find a dictionary (based on a server specification of a hash), store a
+// dictionary, and make judgements about what URLs can use, set, etc. a
+// dictionary.
-class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
+// These dictionaries are acquired over the net, and include a header
+// (containing metadata) as well as a VCDIFF dictionary (for use by a VCDIFF
+// module) to decompress data.
+class NET_EXPORT SdchManager {
public:
// A list of errors that appeared and were either resolved, or used to turn
// off sdch encoding.
@@ -111,6 +84,7 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
DICTIONARY_COUNT_EXCEEDED = 35,
DICTIONARY_ALREADY_SCHEDULED_TO_DOWNLOAD = 36,
DICTIONARY_ALREADY_TRIED_TO_DOWNLOAD = 37,
+ DICTIONARY_FETCH_READ_FAILED = 38,
// Failsafe hack.
ATTEMPT_TO_DECODE_NON_HTTP_DATA = 40,
@@ -127,7 +101,8 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
META_REFRESH_RECOVERY = 70, // Dictionary not found.
// defunct = 71, // Almost the same as META_REFRESH_UNSUPPORTED.
// defunct = 72, // Almost the same as CACHED_META_REFRESH_UNSUPPORTED.
- // defunct = 73, // PASSING_THROUGH_NON_SDCH plus DISCARD_TENTATIVE_SDCH.
+ // defunct = 73, // PASSING_THROUGH_NON_SDCH plus
+ // RESPONSE_TENTATIVE_SDCH in ../filter/sdch_filter.cc.
META_REFRESH_UNSUPPORTED = 74, // Unrecoverable error.
CACHED_META_REFRESH_UNSUPPORTED = 75, // As above, but pulled from cache.
PASSING_THROUGH_NON_SDCH = 76, // Tagged sdch but missing dictionary-hash.
@@ -140,7 +115,7 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
// Common decoded recovery methods.
META_REFRESH_CACHED_RECOVERY = 80, // Probably startup tab loading.
- DISCARD_TENTATIVE_SDCH = 81, // Server decided not to use sdch.
+ // defunct = 81, // Now tracked by ResponseCorruptionDetectionCause histo.
// Non SDCH problems, only accounted for to make stat counting complete
// (i.e., be able to be sure all dictionary advertisements are accounted
@@ -178,7 +153,7 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
FRIEND_TEST_ALL_PREFIXES(SdchManagerTest, PathMatch);
// Construct a vc-diff usable dictionary from the dictionary_text starting
- // at the given offset. The supplied client_hash should be used to
+ // at the given offset. The supplied client_hash should be used to
// advertise the dictionary's availability relative to the suppplied URL.
Dictionary(const std::string& dictionary_text,
size_t offset,
@@ -188,7 +163,7 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
const std::string& path,
const base::Time& expiration,
const std::set<int>& ports);
- ~Dictionary();
+ virtual ~Dictionary();
const GURL& url() const { return url_; }
const std::string& client_hash() const { return client_hash_; }
@@ -227,7 +202,7 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
// Metadate "headers" in before dictionary text contained the following:
// Each dictionary payload consists of several headers, followed by the text
- // of the dictionary. The following are the known headers.
+ // of the dictionary. The following are the known headers.
const std::string domain_;
const std::string path_;
const base::Time expiration_; // Implied by max-age.
@@ -245,9 +220,6 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
// Record stats on various errors.
static void SdchErrorRecovery(ProblemCodes problem);
- // Register a fetcher that this class can use to obtain dictionaries.
- void set_sdch_fetcher(SdchFetcher* fetcher);
-
// Enables or disables SDCH compression.
static void EnableSdchSupport(bool enabled);
@@ -260,16 +232,16 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
// Briefly prevent further advertising of SDCH on this domain (if SDCH is
// enabled). After enough calls to IsInSupportedDomain() the blacklisting
- // will be removed. Additional blacklists take exponentially more calls
+ // will be removed. Additional blacklists take exponentially more calls
// to IsInSupportedDomain() before the blacklisting is undone.
// Used when filter errors are found from a given domain, but it is plausible
// that the cause is temporary (such as application startup, where cached
// entries are used, but a dictionary is not yet loaded).
- void BlacklistDomain(const GURL& url);
+ void BlacklistDomain(const GURL& url, ProblemCodes blacklist_reason);
// Used when SEVERE filter errors are found from a given domain, to prevent
// further use of SDCH on that domain.
- void BlacklistDomainForever(const GURL& url);
+ void BlacklistDomainForever(const GURL& url, ProblemCodes blacklist_reason);
// Unit test only, this function resets enabling of sdch, and clears the
// blacklist.
@@ -286,30 +258,17 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
// Check to see if SDCH is enabled (globally), and the given URL is in a
// supported domain (i.e., not blacklisted, and either the specific supported
- // domain, or all domains were assumed supported). If it is blacklist, reduce
+ // domain, or all domains were assumed supported). If it is blacklist, reduce
// by 1 the number of times it will be reported as blacklisted.
bool IsInSupportedDomain(const GURL& url);
- // Schedule the URL fetching to load a dictionary. This will always return
- // before the dictionary is actually loaded and added.
- // After the implied task does completes, the dictionary will have been
- // cached in memory.
- void FetchDictionary(const GURL& request_url, const GURL& dictionary_url);
-
- // Security test function used before initiating a FetchDictionary.
- // Return true if fetch is legal.
- bool CanFetchDictionary(const GURL& referring_url,
- const GURL& dictionary_url) const;
-
- // Add an SDCH dictionary to our list of availible dictionaries. This addition
- // will fail (return false) if addition is illegal (data in the dictionary is
- // not acceptable from the dictionary_url; dictionary already added, etc.).
- bool AddSdchDictionary(const std::string& dictionary_text,
- const GURL& dictionary_url);
+ // Send out appropriate events notifying observers that a Get-Dictionary
+ // header has been seen.
+ void OnGetDictionary(const GURL& request_url, const GURL& dictionary_url);
// Find the vcdiff dictionary (the body of the sdch dictionary that appears
// after the meta-data headers like Domain:...) with the given |server_hash|
- // to use to decompreses data that arrived as SDCH encoded content. Check to
+ // to use to decompreses data that arrived as SDCH encoded content. Check to
// be sure the returned |dictionary| can be used for decoding content supplied
// in response to a request for |referring_url|.
// Return null in |dictionary| if there is no matching legal dictionary.
@@ -318,28 +277,56 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
scoped_refptr<Dictionary>* dictionary);
// Get list of available (pre-cached) dictionaries that we have already loaded
- // into memory. The list is a comma separated list of (client) hashes per
+ // into memory. The list is a comma separated list of (client) hashes per
// the SDCH spec.
void GetAvailDictionaryList(const GURL& target_url, std::string* list);
// Construct the pair of hashes for client and server to identify an SDCH
- // dictionary. This is only made public to facilitate unit testing, but is
+ // dictionary. This is only made public to facilitate unit testing, but is
// otherwise private
static void GenerateHash(const std::string& dictionary_text,
std::string* client_hash, std::string* server_hash);
// For Latency testing only, we need to know if we've succeeded in doing a
- // round trip before starting our comparative tests. If ever we encounter
+ // round trip before starting our comparative tests. If ever we encounter
// problems with SDCH, we opt-out of the test unless/until we perform a
// complete SDCH decoding.
bool AllowLatencyExperiment(const GURL& url) const;
void SetAllowLatencyExperiment(const GURL& url, bool enable);
+ // Add an SDCH dictionary to our list of availible
+ // dictionaries. This addition will fail if addition is illegal
+ // (data in the dictionary is not acceptable from the
+ // dictionary_url; dictionary already added, etc.).
+ void AddSdchDictionary(const std::string& dictionary_text,
+ const GURL& dictionary_url);
+
+ // Registration for events generated by the SDCH subsystem.
+ void AddObserver(SdchObserver* observer);
+ void RemoveObserver(SdchObserver* observer);
+
private:
- typedef std::map<std::string, int> DomainCounter;
+ struct BlacklistInfo {
+ BlacklistInfo()
+ : count(0),
+ exponential_count(0),
+ reason(MIN_PROBLEM_CODE) {}
+
+ int count; // # of times to refuse SDCH advertisement.
+ int exponential_count; // Current exponential backoff ratchet.
+ ProblemCodes reason; // Why domain was blacklisted.
+
+ };
+ typedef std::map<std::string, BlacklistInfo> DomainBlacklistInfo;
typedef std::set<std::string> ExperimentSet;
+ // Determines whether a "Get-Dictionary" header is legal (dictionary
+ // url has appropriate relationship to referrer url) in the SDCH
+ // protocol. Return true if fetch is legal.
+ bool CanFetchDictionary(const GURL& referring_url,
+ const GURL& dictionary_url) const;
+
// A map of dictionaries info indexed by the hash that the server provides.
typedef std::map<std::string, scoped_refptr<Dictionary> > DictionaryMap;
@@ -355,21 +342,21 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
std::string* output);
DictionaryMap dictionaries_;
- // An instance that can fetch a dictionary given a URL.
- scoped_ptr<SdchFetcher> fetcher_;
-
- // List domains where decode failures have required disabling sdch, along with
- // count of how many additonal uses should be blacklisted.
- DomainCounter blacklisted_domains_;
-
- // Support exponential backoff in number of domain accesses before
- // blacklisting expires.
- DomainCounter exponential_blacklist_count_;
+ // List domains where decode failures have required disabling sdch.
+ DomainBlacklistInfo blacklisted_domains_;
// List of hostnames for which a latency experiment is allowed (because a
// round trip test has recently passed).
ExperimentSet allow_latency_experiment_;
+ // Observers that want to be notified of SDCH events.
+ // Assert list is empty on destruction since if there is an observer
+ // that hasn't removed itself from the list, that observer probably
+ // has a reference to the SdchManager.
+ ObserverList<SdchObserver, true> observers_;
+
+ base::ThreadChecker thread_checker_;
+
DISALLOW_COPY_AND_ASSIGN(SdchManager);
};
diff --git a/chromium/net/base/sdch_manager_unittest.cc b/chromium/net/base/sdch_manager_unittest.cc
index 87b01f4f7ae..d986879aaa4 100644
--- a/chromium/net/base/sdch_manager_unittest.cc
+++ b/chromium/net/base/sdch_manager_unittest.cc
@@ -9,7 +9,9 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/sdch_manager.h"
+#include "net/base/sdch_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
namespace net {
@@ -21,25 +23,72 @@ static const char kTestVcdiffDictionary[] = "DictionaryFor"
//------------------------------------------------------------------------------
+class MockSdchObserver : public SdchObserver {
+ public:
+ MockSdchObserver() : get_dictionary_notifications_(0) {}
+
+ const GURL& last_dictionary_request_url() {
+ return last_dictionary_request_url_;
+ }
+ const GURL& last_dictionary_url() { return last_dictionary_url_; }
+ int get_dictionary_notifications() { return get_dictionary_notifications_; }
+
+ // SdchObserver implementation
+ void OnGetDictionary(SdchManager* manager,
+ const GURL& request_url,
+ const GURL& dictionary_url) override {
+ ++get_dictionary_notifications_;
+ last_dictionary_request_url_ = request_url;
+ last_dictionary_url_ = dictionary_url;
+ }
+ void OnClearDictionaries(SdchManager* manager) override {}
+
+ private:
+ int get_dictionary_notifications_;
+ GURL last_dictionary_request_url_;
+ GURL last_dictionary_url_;
+};
+
class SdchManagerTest : public testing::Test {
protected:
SdchManagerTest()
- : sdch_manager_(new SdchManager) {
+ : sdch_manager_(new SdchManager),
+ default_support_(false),
+ default_https_support_(false) {
+ default_support_ = sdch_manager_->sdch_enabled();
+ default_https_support_ = sdch_manager_->secure_scheme_supported();
}
+ virtual ~SdchManagerTest() {}
+
SdchManager* sdch_manager() { return sdch_manager_.get(); }
// Reset globals back to default state.
- virtual void TearDown() {
- SdchManager::EnableSdchSupport(true);
- SdchManager::EnableSecureSchemeSupport(false);
+ void TearDown() override {
+ SdchManager::EnableSdchSupport(default_support_);
+ SdchManager::EnableSecureSchemeSupport(default_https_support_);
+ }
+
+ // Attempt to add a dictionary to the manager and probe for success or
+ // failure.
+ bool AddSdchDictionary(const std::string& dictionary_text,
+ const GURL& gurl) {
+ std::string list;
+ sdch_manager_->GetAvailDictionaryList(gurl, &list);
+ sdch_manager_->AddSdchDictionary(dictionary_text, gurl);
+ std::string list2;
+ sdch_manager_->GetAvailDictionaryList(gurl, &list2);
+
+ // The list of hashes should change iff the addition succeeds.
+ return (list != list2);
}
private:
scoped_ptr<SdchManager> sdch_manager_;
+ bool default_support_;
+ bool default_https_support_;
};
-//------------------------------------------------------------------------------
static std::string NewSdchDictionary(const std::string& domain) {
std::string dictionary;
if (!domain.empty()) {
@@ -65,11 +114,11 @@ TEST_F(SdchManagerTest, DomainBlacklisting) {
GURL test_url("http://www.test.com");
GURL google_url("http://www.google.com");
- sdch_manager()->BlacklistDomain(test_url);
+ sdch_manager()->BlacklistDomain(test_url, SdchManager::MIN_PROBLEM_CODE);
EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(test_url));
EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(google_url));
- sdch_manager()->BlacklistDomain(google_url);
+ sdch_manager()->BlacklistDomain(google_url, SdchManager::MIN_PROBLEM_CODE);
EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(google_url));
}
@@ -79,7 +128,7 @@ TEST_F(SdchManagerTest, DomainBlacklistingCaseSensitivity) {
EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(test_url));
EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(test2_url));
- sdch_manager()->BlacklistDomain(test_url);
+ sdch_manager()->BlacklistDomain(test_url, SdchManager::MIN_PROBLEM_CODE);
EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(test2_url));
}
@@ -98,7 +147,7 @@ TEST_F(SdchManagerTest, BlacklistingSingleBlacklist) {
std::string domain(gurl.host());
sdch_manager()->ClearBlacklistings();
- sdch_manager()->BlacklistDomain(gurl);
+ sdch_manager()->BlacklistDomain(gurl, SdchManager::MIN_PROBLEM_CODE);
EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 1);
EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 1);
@@ -115,7 +164,7 @@ TEST_F(SdchManagerTest, BlacklistingExponential) {
int exponential = 1;
for (int i = 1; i < 100; ++i) {
- sdch_manager()->BlacklistDomain(gurl);
+ sdch_manager()->BlacklistDomain(gurl, SdchManager::MIN_PROBLEM_CODE);
EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), exponential);
EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential);
@@ -140,16 +189,16 @@ TEST_F(SdchManagerTest, CanSetExactMatchDictionary) {
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
// Perfect match should work.
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
}
TEST_F(SdchManagerTest, CanAdvertiseDictionaryOverHTTP) {
std::string dictionary_domain("x.y.z.google.com");
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
std::string dictionary_list;
// HTTP target URL can advertise dictionary.
@@ -163,8 +212,8 @@ TEST_F(SdchManagerTest, CanNotAdvertiseDictionaryOverHTTPS) {
std::string dictionary_domain("x.y.z.google.com");
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
std::string dictionary_list;
// HTTPS target URL should NOT advertise dictionary.
@@ -178,11 +227,12 @@ TEST_F(SdchManagerTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) {
std::string dictionary_domain("x.y.z.google.com");
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
- EXPECT_FALSE(sdch_manager()->AddSdchDictionary(
- dictionary_text, GURL("https://" + dictionary_domain)));
+ SdchManager::EnableSecureSchemeSupport(false);
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("https://" + dictionary_domain)));
SdchManager::EnableSecureSchemeSupport(true);
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
- dictionary_text, GURL("https://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("https://" + dictionary_domain)));
GURL target_url("https://" + dictionary_domain + "/test");
std::string dictionary_list;
@@ -197,15 +247,15 @@ TEST_F(SdchManagerTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) {
std::string server_hash;
sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
- EXPECT_TRUE(dictionary != NULL);
+ EXPECT_TRUE(dictionary.get() != NULL);
}
TEST_F(SdchManagerTest, CanNotUseHTTPDictionaryOverHTTPS) {
std::string dictionary_domain("x.y.z.google.com");
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
GURL target_url("https://" + dictionary_domain + "/test");
std::string dictionary_list;
@@ -220,7 +270,30 @@ TEST_F(SdchManagerTest, CanNotUseHTTPDictionaryOverHTTPS) {
std::string server_hash;
sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
- EXPECT_TRUE(dictionary == NULL);
+ EXPECT_TRUE(dictionary.get() == NULL);
+}
+
+TEST_F(SdchManagerTest, CanNotUseHTTPSDictionaryOverHTTP) {
+ std::string dictionary_domain("x.y.z.google.com");
+ std::string dictionary_text(NewSdchDictionary(dictionary_domain));
+
+ SdchManager::EnableSecureSchemeSupport(true);
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("https://" + dictionary_domain)));
+
+ GURL target_url("http://" + dictionary_domain + "/test");
+ std::string dictionary_list;
+ // HTTP target URL should not advertise dictionary acquired over HTTPS even if
+ // secure scheme support is enabled.
+ sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
+ EXPECT_TRUE(dictionary_list.empty());
+
+ scoped_refptr<SdchManager::Dictionary> dictionary;
+ std::string client_hash;
+ std::string server_hash;
+ sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
+ sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
+ EXPECT_TRUE(dictionary.get() == NULL);
}
TEST_F(SdchManagerTest, FailToSetDomainMismatchDictionary) {
@@ -228,8 +301,8 @@ TEST_F(SdchManagerTest, FailToSetDomainMismatchDictionary) {
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
// Fail the "domain match" requirement.
- EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://y.z.google.com")));
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("http://y.z.google.com")));
}
TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionary) {
@@ -237,8 +310,17 @@ TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionary) {
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
// Fail the HD with D being the domain and H having a dot requirement.
- EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://w.x.y.z.google.com")));
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("http://w.x.y.z.google.com")));
+}
+
+TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionaryTrailingDot) {
+ std::string dictionary_domain("x.y.z.google.com");
+ std::string dictionary_text(NewSdchDictionary(dictionary_domain));
+
+ // Fail the HD with D being the domain and H having a dot requirement.
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("http://w.x.y.z.google.com.")));
}
TEST_F(SdchManagerTest, FailToSetRepeatPrefixWithDotDictionary) {
@@ -248,8 +330,8 @@ TEST_F(SdchManagerTest, FailToSetRepeatPrefixWithDotDictionary) {
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
// Fail the HD with D being the domain and H having a dot requirement.
- EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://www.google.com.www.google.com")));
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("http://www.google.com.www.google.com")));
}
TEST_F(SdchManagerTest, CanSetLeadingDotDomainDictionary) {
@@ -260,8 +342,43 @@ TEST_F(SdchManagerTest, CanSetLeadingDotDomainDictionary) {
// Verify that a leading dot in the domain is acceptable, as long as the host
// name does not contain any dots preceding the matched domain name.
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://www.google.com")));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text, GURL("http://www.google.com")));
+}
+
+TEST_F(SdchManagerTest,
+ CanSetLeadingDotDomainDictionaryFromURLWithTrailingDot) {
+ // Make sure that a prefix that matches the domain postfix won't confuse
+ // the validation checks.
+ std::string dictionary_domain(".google.com");
+ std::string dictionary_text(NewSdchDictionary(dictionary_domain));
+
+ // Verify that a leading dot in the domain is acceptable, as long as the host
+ // name does not contain any dots preceding the matched domain name.
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://www.google.com.")));
+}
+
+TEST_F(SdchManagerTest, CannotSetLeadingDotDomainDictionary) {
+ // Make sure that a prefix that matches the domain postfix won't confuse
+ // the validation checks.
+ std::string dictionary_domain(".google.com");
+ std::string dictionary_text(NewSdchDictionary(dictionary_domain));
+
+ // Verify that a leading dot in the domain does not affect the name containing
+ // dots failure.
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("http://www.subdomain.google.com")));
+}
+
+TEST_F(SdchManagerTest, CannotSetLeadingDotDomainDictionaryTrailingDot) {
+ // Make sure that a prefix that matches the domain postfix won't confuse
+ // the validation checks.
+ std::string dictionary_domain(".google.com");
+ std::string dictionary_text(NewSdchDictionary(dictionary_domain));
+
+ // Verify that a trailing period in the URL doesn't affect the check.
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("http://www.subdomain.google.com.")));
}
// Make sure the order of the tests is not helping us or confusing things.
@@ -271,8 +388,8 @@ TEST_F(SdchManagerTest, CanStillSetExactMatchDictionary) {
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
// Perfect match should *STILL* work.
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
}
// Make sure the DOS protection precludes the addition of too many dictionaries.
@@ -280,16 +397,13 @@ TEST_F(SdchManagerTest, TooManyDictionaries) {
std::string dictionary_domain(".google.com");
std::string dictionary_text(NewSdchDictionary(dictionary_domain));
- size_t count = 0;
- while (count <= SdchManager::kMaxDictionaryCount + 1) {
- if (!sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://www.google.com")))
- break;
-
+ for (size_t count = 0; count < SdchManager::kMaxDictionaryCount; ++count) {
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://www.google.com")));
dictionary_text += " "; // Create dictionary with different SHA signature.
- ++count;
}
- EXPECT_EQ(SdchManager::kMaxDictionaryCount, count);
+ EXPECT_FALSE(
+ AddSdchDictionary(dictionary_text, GURL("http://www.google.com")));
}
TEST_F(SdchManagerTest, DictionaryNotTooLarge) {
@@ -298,8 +412,8 @@ TEST_F(SdchManagerTest, DictionaryNotTooLarge) {
dictionary_text.append(
SdchManager::kMaxDictionarySize - dictionary_text.size(), ' ');
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
}
TEST_F(SdchManagerTest, DictionaryTooLarge) {
@@ -308,8 +422,8 @@ TEST_F(SdchManagerTest, DictionaryTooLarge) {
dictionary_text.append(
SdchManager::kMaxDictionarySize + 1 - dictionary_text.size(), ' ');
- EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
- GURL("http://" + dictionary_domain)));
+ EXPECT_FALSE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
}
TEST_F(SdchManagerTest, PathMatch) {
@@ -399,46 +513,50 @@ TEST_F(SdchManagerTest, CanUseMultipleManagers) {
// Confirm that if you add directories to one manager, you
// can't get them from the other.
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
- dictionary_text_1, GURL("http://" + dictionary_domain_1)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text_1,
+ GURL("http://" + dictionary_domain_1)));
scoped_refptr<SdchManager::Dictionary> dictionary;
sdch_manager()->GetVcdiffDictionary(
server_hash_1,
GURL("http://" + dictionary_domain_1 + "/random_url"),
&dictionary);
- EXPECT_TRUE(dictionary);
+ EXPECT_TRUE(dictionary.get());
- EXPECT_TRUE(second_manager.AddSdchDictionary(
- dictionary_text_2, GURL("http://" + dictionary_domain_2)));
+ second_manager.AddSdchDictionary(
+ dictionary_text_2, GURL("http://" + dictionary_domain_2));
second_manager.GetVcdiffDictionary(
server_hash_2,
GURL("http://" + dictionary_domain_2 + "/random_url"),
&dictionary);
- EXPECT_TRUE(dictionary);
+ EXPECT_TRUE(dictionary.get());
sdch_manager()->GetVcdiffDictionary(
server_hash_2,
GURL("http://" + dictionary_domain_2 + "/random_url"),
&dictionary);
- EXPECT_FALSE(dictionary);
+ EXPECT_FALSE(dictionary.get());
second_manager.GetVcdiffDictionary(
server_hash_1,
GURL("http://" + dictionary_domain_1 + "/random_url"),
&dictionary);
- EXPECT_FALSE(dictionary);
+ EXPECT_FALSE(dictionary.get());
}
TEST_F(SdchManagerTest, HttpsCorrectlySupported) {
GURL url("http://www.google.com");
GURL secure_url("https://www.google.com");
+ bool expect_https_support = true;
+
EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
- EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(secure_url));
+ EXPECT_EQ(expect_https_support,
+ sdch_manager()->IsInSupportedDomain(secure_url));
- SdchManager::EnableSecureSchemeSupport(true);
+ SdchManager::EnableSecureSchemeSupport(!expect_https_support);
EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
- EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(secure_url));
+ EXPECT_NE(expect_https_support,
+ sdch_manager()->IsInSupportedDomain(secure_url));
}
TEST_F(SdchManagerTest, ClearDictionaryData) {
@@ -451,16 +569,17 @@ TEST_F(SdchManagerTest, ClearDictionaryData) {
SdchManager::GenerateHash(dictionary_text, &tmp_hash, &server_hash);
- EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
- dictionary_text, GURL("http://" + dictionary_domain)));
+ EXPECT_TRUE(AddSdchDictionary(dictionary_text,
+ GURL("http://" + dictionary_domain)));
scoped_refptr<SdchManager::Dictionary> dictionary;
sdch_manager()->GetVcdiffDictionary(
server_hash,
GURL("http://" + dictionary_domain + "/random_url"),
&dictionary);
- EXPECT_TRUE(dictionary);
+ EXPECT_TRUE(dictionary.get());
- sdch_manager()->BlacklistDomain(GURL(blacklist_url));
+ sdch_manager()->BlacklistDomain(GURL(blacklist_url),
+ SdchManager::MIN_PROBLEM_CODE);
EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(blacklist_url));
sdch_manager()->ClearData();
@@ -470,9 +589,27 @@ TEST_F(SdchManagerTest, ClearDictionaryData) {
server_hash,
GURL("http://" + dictionary_domain + "/random_url"),
&dictionary);
- EXPECT_FALSE(dictionary);
+ EXPECT_FALSE(dictionary.get());
EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(blacklist_url));
}
-} // namespace net
+TEST_F(SdchManagerTest, GetDictionaryNotification) {
+ GURL test_request_gurl(GURL("http://www.example.com/data"));
+ GURL test_dictionary_gurl(GURL("http://www.example.com/dict"));
+ MockSdchObserver observer;
+ sdch_manager()->AddObserver(&observer);
+
+ EXPECT_EQ(0, observer.get_dictionary_notifications());
+ sdch_manager()->OnGetDictionary(test_request_gurl, test_dictionary_gurl);
+ EXPECT_EQ(1, observer.get_dictionary_notifications());
+ EXPECT_EQ(test_request_gurl, observer.last_dictionary_request_url());
+ EXPECT_EQ(test_dictionary_gurl, observer.last_dictionary_url());
+
+ sdch_manager()->RemoveObserver(&observer);
+ sdch_manager()->OnGetDictionary(test_request_gurl, test_dictionary_gurl);
+ EXPECT_EQ(1, observer.get_dictionary_notifications());
+ EXPECT_EQ(test_request_gurl, observer.last_dictionary_request_url());
+ EXPECT_EQ(test_dictionary_gurl, observer.last_dictionary_url());
+}
+} // namespace net
diff --git a/chromium/net/base/sdch_observer.cc b/chromium/net/base/sdch_observer.cc
new file mode 100644
index 00000000000..9bf44addd68
--- /dev/null
+++ b/chromium/net/base/sdch_observer.cc
@@ -0,0 +1,14 @@
+// Copyright 2014 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/sdch_observer.h"
+
+#include "base/logging.h"
+#include "net/base/sdch_manager.h"
+
+namespace net {
+
+SdchObserver::~SdchObserver() {
+}
+}
diff --git a/chromium/net/base/sdch_observer.h b/chromium/net/base/sdch_observer.h
new file mode 100644
index 00000000000..2c5987d8698
--- /dev/null
+++ b/chromium/net/base/sdch_observer.h
@@ -0,0 +1,34 @@
+// Copyright 2014 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.
+
+#ifndef NET_BASE_SDCH_OBSERVER_H_
+#define NET_BASE_SDCH_OBSERVER_H_
+
+#include "net/base/net_export.h"
+
+class GURL;
+
+namespace net {
+
+class SdchManager;
+
+// Observer interface for SDCH. Observers can register with
+// the SdchManager to receive notifications of various SDCH events.
+class NET_EXPORT SdchObserver {
+ public:
+ virtual ~SdchObserver();
+
+ // Notification that SDCH has seen a "Get-Dictionary" header.
+ virtual void OnGetDictionary(SdchManager* manager,
+ const GURL& request_url,
+ const GURL& dictionary_url) = 0;
+
+ // Notification that SDCH has received a request to clear all
+ // its dictionaries.
+ virtual void OnClearDictionaries(SdchManager* manager) = 0;
+};
+
+} // namespace net
+
+#endif // NET_BASE_SDCH_MANAGER_H_
diff --git a/chromium/net/base/test_completion_callback.cc b/chromium/net/base/test_completion_callback.cc
index 4fcff74faac..7094592d1dd 100644
--- a/chromium/net/base/test_completion_callback.cc
+++ b/chromium/net/base/test_completion_callback.cc
@@ -35,11 +35,21 @@ TestCompletionCallbackBaseInternal::TestCompletionCallbackBaseInternal()
waiting_for_result_(false) {
}
+TestCompletionCallbackBaseInternal::~TestCompletionCallbackBaseInternal() {
+}
+
} // namespace internal
+TestClosure::TestClosure()
+ : closure_(base::Bind(&TestClosure::DidSetResult, base::Unretained(this))) {
+}
+
+TestClosure::~TestClosure() {
+}
+
TestCompletionCallback::TestCompletionCallback()
: callback_(base::Bind(&TestCompletionCallback::SetResult,
- base::Unretained(this))) {
+ base::Unretained(this))) {
}
TestCompletionCallback::~TestCompletionCallback() {
@@ -47,7 +57,7 @@ TestCompletionCallback::~TestCompletionCallback() {
TestInt64CompletionCallback::TestInt64CompletionCallback()
: callback_(base::Bind(&TestInt64CompletionCallback::SetResult,
- base::Unretained(this))) {
+ base::Unretained(this))) {
}
TestInt64CompletionCallback::~TestInt64CompletionCallback() {
diff --git a/chromium/net/base/test_completion_callback.h b/chromium/net/base/test_completion_callback.h
index 4a0afe13359..c1f715c9dfa 100644
--- a/chromium/net/base/test_completion_callback.h
+++ b/chromium/net/base/test_completion_callback.h
@@ -5,6 +5,7 @@
#ifndef NET_BASE_TEST_COMPLETION_CALLBACK_H_
#define NET_BASE_TEST_COMPLETION_CALLBACK_H_
+#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/tuple.h"
#include "net/base/completion_callback.h"
@@ -34,6 +35,8 @@ class TestCompletionCallbackBaseInternal {
protected:
TestCompletionCallbackBaseInternal();
+ virtual ~TestCompletionCallbackBaseInternal();
+
void DidSetResult();
void WaitForResult();
@@ -48,7 +51,7 @@ template <typename R>
class TestCompletionCallbackTemplate
: public TestCompletionCallbackBaseInternal {
public:
- virtual ~TestCompletionCallbackTemplate() {}
+ virtual ~TestCompletionCallbackTemplate() override {}
R WaitForResult() {
TestCompletionCallbackBaseInternal::WaitForResult();
@@ -77,6 +80,22 @@ class TestCompletionCallbackTemplate
} // namespace internal
+class TestClosure
+ : public internal::TestCompletionCallbackBaseInternal {
+ public:
+ using internal::TestCompletionCallbackBaseInternal::WaitForResult;
+
+ TestClosure();
+ virtual ~TestClosure() override;
+
+ const base::Closure& closure() const { return closure_; }
+
+ private:
+ const base::Closure closure_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestClosure);
+};
+
// Base class overridden by custom implementations of TestCompletionCallback.
typedef internal::TestCompletionCallbackTemplate<int>
TestCompletionCallbackBase;
@@ -87,7 +106,7 @@ typedef internal::TestCompletionCallbackTemplate<int64>
class TestCompletionCallback : public TestCompletionCallbackBase {
public:
TestCompletionCallback();
- virtual ~TestCompletionCallback();
+ virtual ~TestCompletionCallback() override;
const CompletionCallback& callback() const { return callback_; }
@@ -100,7 +119,7 @@ class TestCompletionCallback : public TestCompletionCallbackBase {
class TestInt64CompletionCallback : public TestInt64CompletionCallbackBase {
public:
TestInt64CompletionCallback();
- virtual ~TestInt64CompletionCallback();
+ virtual ~TestInt64CompletionCallback() override;
const Int64CompletionCallback& callback() const { return callback_; }
@@ -114,10 +133,10 @@ class TestInt64CompletionCallback : public TestInt64CompletionCallbackBase {
class ReleaseBufferCompletionCallback: public TestCompletionCallback {
public:
explicit ReleaseBufferCompletionCallback(IOBuffer* buffer);
- virtual ~ReleaseBufferCompletionCallback();
+ virtual ~ReleaseBufferCompletionCallback() override;
private:
- virtual void SetResult(int result) OVERRIDE;
+ void SetResult(int result) override;
IOBuffer* buffer_;
DISALLOW_COPY_AND_ASSIGN(ReleaseBufferCompletionCallback);
diff --git a/chromium/net/base/test_completion_callback_unittest.cc b/chromium/net/base/test_completion_callback_unittest.cc
index 704273ebc7f..b0c8565b112 100644
--- a/chromium/net/base/test_completion_callback_unittest.cc
+++ b/chromium/net/base/test_completion_callback_unittest.cc
@@ -13,10 +13,18 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
-typedef PlatformTest TestCompletionCallbackTest;
+namespace {
const int kMagicResult = 8888;
+void CallClosureAfterCheckingResult(const base::Closure& closure,
+ bool* did_check_result,
+ int result) {
+ DCHECK_EQ(result, kMagicResult);
+ *did_check_result = true;
+ closure.Run();
+}
+
// ExampleEmployer is a toy version of HostResolver
// TODO: restore damage done in extracting example from real code
// (e.g. bring back real destructor, bring back comments)
@@ -111,13 +119,32 @@ bool ExampleEmployer::DoSomething(const net::CompletionCallback& callback) {
return true;
}
+} // namespace
+
+typedef PlatformTest TestCompletionCallbackTest;
+
TEST_F(TestCompletionCallbackTest, Simple) {
ExampleEmployer boss;
net::TestCompletionCallback callback;
bool queued = boss.DoSomething(callback.callback());
- EXPECT_EQ(queued, true);
+ EXPECT_TRUE(queued);
int result = callback.WaitForResult();
EXPECT_EQ(result, kMagicResult);
}
+TEST_F(TestCompletionCallbackTest, Closure) {
+ ExampleEmployer boss;
+ net::TestClosure closure;
+ bool did_check_result = false;
+ net::CompletionCallback completion_callback =
+ base::Bind(&CallClosureAfterCheckingResult,
+ closure.closure(), base::Unretained(&did_check_result));
+ bool queued = boss.DoSomething(completion_callback);
+ EXPECT_TRUE(queued);
+
+ EXPECT_FALSE(did_check_result);
+ closure.WaitForResult();
+ EXPECT_TRUE(did_check_result);
+}
+
// TODO: test deleting ExampleEmployer while work outstanding
diff --git a/chromium/net/base/trace_net_log_observer.cc b/chromium/net/base/trace_net_log_observer.cc
new file mode 100644
index 00000000000..5d98c41d37b
--- /dev/null
+++ b/chromium/net/base/trace_net_log_observer.cc
@@ -0,0 +1,112 @@
+// Copyright 2014 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/trace_net_log_observer.h"
+
+#include <stdio.h>
+
+#include <string>
+
+#include "base/debug/trace_event.h"
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "net/base/net_log.h"
+
+namespace net {
+
+namespace {
+
+// TraceLog category for NetLog events.
+const char kNetLogTracingCategory[] = TRACE_DISABLED_BY_DEFAULT("netlog");
+
+class TracedValue : public base::debug::ConvertableToTraceFormat {
+ public:
+ explicit TracedValue(scoped_ptr<base::Value> value) : value_(value.Pass()) {}
+
+ private:
+ ~TracedValue() override {}
+
+ void AppendAsTraceFormat(std::string* out) const override {
+ if (value_) {
+ std::string tmp;
+ base::JSONWriter::Write(value_.get(), &tmp);
+ *out += tmp;
+ } else {
+ *out += "\"\"";
+ }
+ }
+
+ private:
+ scoped_ptr<base::Value> value_;
+};
+
+} // namespace
+
+TraceNetLogObserver::TraceNetLogObserver() : net_log_to_watch_(NULL) {
+}
+
+TraceNetLogObserver::~TraceNetLogObserver() {
+ DCHECK(!net_log_to_watch_);
+ DCHECK(!net_log());
+}
+
+void TraceNetLogObserver::OnAddEntry(const NetLog::Entry& entry) {
+ scoped_ptr<base::Value> params(entry.ParametersToValue());
+ switch (entry.phase()) {
+ case NetLog::PHASE_BEGIN:
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
+ kNetLogTracingCategory,
+ NetLog::EventTypeToString(entry.type()), entry.source().id,
+ "source_type", NetLog::SourceTypeToString(entry.source().type),
+ "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
+ new TracedValue(params.Pass())));
+ break;
+ case NetLog::PHASE_END:
+ TRACE_EVENT_NESTABLE_ASYNC_END2(
+ kNetLogTracingCategory,
+ NetLog::EventTypeToString(entry.type()), entry.source().id,
+ "source_type", NetLog::SourceTypeToString(entry.source().type),
+ "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
+ new TracedValue(params.Pass())));
+ break;
+ case NetLog::PHASE_NONE:
+ TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(
+ kNetLogTracingCategory,
+ NetLog::EventTypeToString(entry.type()), entry.source().id,
+ "source_type", NetLog::SourceTypeToString(entry.source().type),
+ "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
+ new TracedValue(params.Pass())));
+ break;
+ }
+}
+
+void TraceNetLogObserver::WatchForTraceStart(NetLog* netlog) {
+ DCHECK(!net_log_to_watch_);
+ DCHECK(!net_log());
+ net_log_to_watch_ = netlog;
+ base::debug::TraceLog::GetInstance()->AddEnabledStateObserver(this);
+}
+
+void TraceNetLogObserver::StopWatchForTraceStart() {
+ // Should only stop if is currently watching.
+ DCHECK(net_log_to_watch_);
+ base::debug::TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
+ if (net_log())
+ net_log()->RemoveThreadSafeObserver(this);
+ net_log_to_watch_ = NULL;
+}
+
+void TraceNetLogObserver::OnTraceLogEnabled() {
+ net_log_to_watch_->AddThreadSafeObserver(this,
+ NetLog::LOG_STRIP_PRIVATE_DATA);
+}
+
+void TraceNetLogObserver::OnTraceLogDisabled() {
+ if (net_log())
+ net_log()->RemoveThreadSafeObserver(this);
+}
+
+} // namespace net
diff --git a/chromium/net/base/trace_net_log_observer.h b/chromium/net/base/trace_net_log_observer.h
new file mode 100644
index 00000000000..9fc062b6f91
--- /dev/null
+++ b/chromium/net/base/trace_net_log_observer.h
@@ -0,0 +1,49 @@
+// Copyright 2014 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.
+
+#ifndef NET_BASE_TRACE_NET_LOG_OBSERVER_H_
+#define NET_BASE_TRACE_NET_LOG_OBSERVER_H_
+
+#include "base/debug/trace_event_impl.h"
+#include "base/macros.h"
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+
+namespace net {
+
+// TraceNetLogObserver watches for TraceLog enable, and sends NetLog
+// events to TraceLog if it is enabled.
+class NET_EXPORT TraceNetLogObserver
+ : public NetLog::ThreadSafeObserver,
+ public base::debug::TraceLog::EnabledStateObserver {
+ public:
+ TraceNetLogObserver();
+ ~TraceNetLogObserver() override;
+
+ // net::NetLog::ThreadSafeObserver implementation:
+ void OnAddEntry(const NetLog::Entry& entry) override;
+
+ // Start to watch for TraceLog enable and disable events.
+ // This can't be called if already watching for events.
+ // Watches NetLog only when tracing is enabled.
+ void WatchForTraceStart(NetLog* net_log);
+
+ // Stop watching for TraceLog enable and disable events.
+ // If WatchForTraceStart is called, this must be called before
+ // TraceNetLogObserver is destroyed.
+ void StopWatchForTraceStart();
+
+ // base::debug::TraceLog::EnabledStateChangedObserver implementation:
+ void OnTraceLogEnabled() override;
+ void OnTraceLogDisabled() override;
+
+ private:
+ NetLog* net_log_to_watch_;
+
+ DISALLOW_COPY_AND_ASSIGN(TraceNetLogObserver);
+};
+
+} // namespace net
+
+#endif // NET_BASE_TRACE_NET_LOG_OBSERVER_H_
diff --git a/chromium/net/base/trace_net_log_observer_unittest.cc b/chromium/net/base/trace_net_log_observer_unittest.cc
new file mode 100644
index 00000000000..5256bac9c8a
--- /dev/null
+++ b/chromium/net/base/trace_net_log_observer_unittest.cc
@@ -0,0 +1,378 @@
+// Copyright 2014 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/trace_net_log_observer.h"
+
+#include <string>
+#include <vector>
+
+#include "base/debug/trace_event.h"
+#include "base/debug/trace_event_impl.h"
+#include "base/json/json_reader.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/values.h"
+#include "net/base/capturing_net_log.h"
+#include "net/base/net_log.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::debug::TraceLog;
+
+namespace net {
+
+namespace {
+
+// TraceLog category for NetLog events.
+const char kNetLogTracingCategory[] = TRACE_DISABLED_BY_DEFAULT("netlog");
+
+struct TraceEntryInfo {
+ std::string category;
+ std::string id;
+ std::string phase;
+ std::string name;
+ std::string source_type;
+};
+
+TraceEntryInfo GetTraceEntryInfoFromValue(const base::DictionaryValue& value) {
+ TraceEntryInfo info;
+ EXPECT_TRUE(value.GetString("cat", &info.category));
+ EXPECT_TRUE(value.GetString("id", &info.id));
+ EXPECT_TRUE(value.GetString("ph", &info.phase));
+ EXPECT_TRUE(value.GetString("name", &info.name));
+ EXPECT_TRUE(value.GetString("args.source_type", &info.source_type));
+
+ return info;
+}
+
+class TraceNetLogObserverTest : public testing::Test {
+ public:
+ TraceNetLogObserverTest() {
+ TraceLog* tracelog = TraceLog::GetInstance();
+ DCHECK(tracelog);
+ DCHECK(!tracelog->IsEnabled());
+ trace_buffer_.SetOutputCallback(json_output_.GetCallback());
+ trace_net_log_observer_.reset(new TraceNetLogObserver());
+ trace_events_.reset(new base::ListValue());
+ }
+
+ ~TraceNetLogObserverTest() override {
+ DCHECK(!TraceLog::GetInstance()->IsEnabled());
+ }
+
+ void OnTraceDataCollected(
+ base::RunLoop* run_loop,
+ const scoped_refptr<base::RefCountedString>& events_str,
+ bool has_more_events) {
+ DCHECK(trace_events_->empty());
+ trace_buffer_.Start();
+ trace_buffer_.AddFragment(events_str->data());
+ trace_buffer_.Finish();
+
+ scoped_ptr<base::Value> trace_value;
+ trace_value.reset(base::JSONReader::Read(
+ json_output_.json_output,
+ base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN));
+
+ ASSERT_TRUE(trace_value) << json_output_.json_output;
+ base::ListValue* trace_events = NULL;
+ ASSERT_TRUE(trace_value->GetAsList(&trace_events));
+
+ trace_events_ = FilterNetLogTraceEvents(*trace_events);
+
+ if (!has_more_events)
+ run_loop->Quit();
+ }
+
+ static void EnableTraceLog() {
+ TraceLog::GetInstance()->SetEnabled(
+ base::debug::CategoryFilter(kNetLogTracingCategory),
+ TraceLog::RECORDING_MODE,
+ base::debug::TraceOptions());
+ }
+
+ void EndTraceAndFlush() {
+ base::RunLoop run_loop;
+ TraceLog::GetInstance()->SetDisabled();
+ TraceLog::GetInstance()->Flush(
+ base::Bind(&TraceNetLogObserverTest::OnTraceDataCollected,
+ base::Unretained(this),
+ base::Unretained(&run_loop)));
+ run_loop.Run();
+ }
+
+ void set_trace_net_log_observer(TraceNetLogObserver* trace_net_log_observer) {
+ trace_net_log_observer_.reset(trace_net_log_observer);
+ }
+
+ static scoped_ptr<base::ListValue> FilterNetLogTraceEvents(
+ const base::ListValue& trace_events) {
+ scoped_ptr<base::ListValue> filtered_trace_events(new base::ListValue());
+ for (size_t i = 0; i < trace_events.GetSize(); i++) {
+ const base::DictionaryValue* dict = NULL;
+ if (!trace_events.GetDictionary(i, &dict)) {
+ ADD_FAILURE() << "Unexpected non-dictionary event in trace_events";
+ continue;
+ }
+ std::string category;
+ if (!dict->GetString("cat", &category)) {
+ ADD_FAILURE()
+ << "Unexpected item without a category field in trace_events";
+ continue;
+ }
+ if (category != kNetLogTracingCategory)
+ continue;
+ filtered_trace_events->Append(dict->DeepCopy());
+ }
+ return filtered_trace_events.Pass();
+ }
+
+ base::ListValue* trace_events() const {
+ return trace_events_.get();
+ }
+
+ CapturingNetLog* net_log() {
+ return &net_log_;
+ }
+
+ TraceNetLogObserver* trace_net_log_observer() const {
+ return trace_net_log_observer_.get();
+ }
+
+ private:
+ scoped_ptr<base::ListValue> trace_events_;
+ base::debug::TraceResultBuffer trace_buffer_;
+ base::debug::TraceResultBuffer::SimpleOutput json_output_;
+ CapturingNetLog net_log_;
+ scoped_ptr<TraceNetLogObserver> trace_net_log_observer_;
+};
+
+TEST_F(TraceNetLogObserverTest, TracingNotEnabled) {
+ trace_net_log_observer()->WatchForTraceStart(net_log());
+ net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+
+ EndTraceAndFlush();
+ trace_net_log_observer()->StopWatchForTraceStart();
+
+ EXPECT_EQ(0u, trace_events()->GetSize());
+}
+
+TEST_F(TraceNetLogObserverTest, TraceEventCaptured) {
+ CapturingNetLog::CapturedEntryList entries;
+ net_log()->GetEntries(&entries);
+ EXPECT_TRUE(entries.empty());
+
+ trace_net_log_observer()->WatchForTraceStart(net_log());
+ EnableTraceLog();
+ BoundNetLog bound_net_log =
+ BoundNetLog::Make(net_log(), net::NetLog::SOURCE_NONE);
+ net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ bound_net_log.BeginEvent(NetLog::TYPE_URL_REQUEST_START_JOB);
+ bound_net_log.EndEvent(NetLog::TYPE_REQUEST_ALIVE);
+
+ net_log()->GetEntries(&entries);
+ EXPECT_EQ(3u, entries.size());
+ EndTraceAndFlush();
+ trace_net_log_observer()->StopWatchForTraceStart();
+ EXPECT_EQ(3u, trace_events()->GetSize());
+ const base::DictionaryValue* item1 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(0, &item1));
+ const base::DictionaryValue* item2 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(1, &item2));
+ const base::DictionaryValue* item3 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(2, &item3));
+
+ TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
+ TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
+ TraceEntryInfo actual_item3 = GetTraceEntryInfoFromValue(*item3);
+ EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
+ actual_item1.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_CANCELLED),
+ actual_item1.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
+ actual_item1.source_type);
+
+ EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[1].source.id), actual_item2.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN),
+ actual_item2.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB),
+ actual_item2.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type),
+ actual_item2.source_type);
+
+ EXPECT_EQ(kNetLogTracingCategory, actual_item3.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[2].source.id), actual_item3.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_END),
+ actual_item3.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE),
+ actual_item3.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[2].source.type),
+ actual_item3.source_type);
+}
+
+TEST_F(TraceNetLogObserverTest, EnableAndDisableTracing) {
+ trace_net_log_observer()->WatchForTraceStart(net_log());
+ EnableTraceLog();
+ net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ TraceLog::GetInstance()->SetDisabled();
+ net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+ EnableTraceLog();
+ net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
+
+ EndTraceAndFlush();
+ trace_net_log_observer()->StopWatchForTraceStart();
+
+ CapturingNetLog::CapturedEntryList entries;
+ net_log()->GetEntries(&entries);
+ EXPECT_EQ(3u, entries.size());
+ EXPECT_EQ(2u, trace_events()->GetSize());
+ const base::DictionaryValue* item1 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(0, &item1));
+ const base::DictionaryValue* item2 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(1, &item2));
+
+ TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
+ TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
+ EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
+ actual_item1.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_CANCELLED),
+ actual_item1.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
+ actual_item1.source_type);
+
+ EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[2].source.id), actual_item2.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
+ actual_item2.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_URL_REQUEST_START_JOB),
+ actual_item2.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[2].source.type),
+ actual_item2.source_type);
+}
+
+TEST_F(TraceNetLogObserverTest, DestroyObserverWhileTracing) {
+ trace_net_log_observer()->WatchForTraceStart(net_log());
+ EnableTraceLog();
+ net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ trace_net_log_observer()->StopWatchForTraceStart();
+ set_trace_net_log_observer(NULL);
+ net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+
+ EndTraceAndFlush();
+
+ CapturingNetLog::CapturedEntryList entries;
+ net_log()->GetEntries(&entries);
+ EXPECT_EQ(2u, entries.size());
+ EXPECT_EQ(1u, trace_events()->GetSize());
+
+ const base::DictionaryValue* item1 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(0, &item1));
+
+ TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
+ EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
+ actual_item1.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_CANCELLED),
+ actual_item1.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
+ actual_item1.source_type);
+}
+
+TEST_F(TraceNetLogObserverTest, DestroyObserverWhileNotTracing) {
+ trace_net_log_observer()->WatchForTraceStart(net_log());
+ net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ trace_net_log_observer()->StopWatchForTraceStart();
+ set_trace_net_log_observer(NULL);
+ net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+ net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
+
+ EndTraceAndFlush();
+
+ CapturingNetLog::CapturedEntryList entries;
+ net_log()->GetEntries(&entries);
+ EXPECT_EQ(3u, entries.size());
+ EXPECT_EQ(0u, trace_events()->GetSize());
+}
+
+TEST_F(TraceNetLogObserverTest, CreateObserverAfterTracingStarts) {
+ set_trace_net_log_observer(NULL);
+ EnableTraceLog();
+ set_trace_net_log_observer(new TraceNetLogObserver());
+ trace_net_log_observer()->WatchForTraceStart(net_log());
+ net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED);
+ trace_net_log_observer()->StopWatchForTraceStart();
+ net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+ net_log()->AddGlobalEntry(NetLog::TYPE_URL_REQUEST_START_JOB);
+
+ EndTraceAndFlush();
+
+ CapturingNetLog::CapturedEntryList entries;
+ net_log()->GetEntries(&entries);
+ EXPECT_EQ(3u, entries.size());
+ EXPECT_EQ(0u, trace_events()->GetSize());
+}
+
+TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) {
+ trace_net_log_observer()->WatchForTraceStart(net_log());
+ EnableTraceLog();
+ NetLog::ParametersCallback net_log_callback;
+ std::string param = "bar";
+ net_log_callback = NetLog::StringCallback("foo", &param);
+
+ net_log()->AddGlobalEntry(NetLog::TYPE_CANCELLED, net_log_callback);
+ net_log()->AddGlobalEntry(NetLog::TYPE_REQUEST_ALIVE);
+
+ EndTraceAndFlush();
+ trace_net_log_observer()->StopWatchForTraceStart();
+
+ CapturingNetLog::CapturedEntryList entries;
+ net_log()->GetEntries(&entries);
+ EXPECT_EQ(2u, entries.size());
+ EXPECT_EQ(2u, trace_events()->GetSize());
+ const base::DictionaryValue* item1 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(0, &item1));
+ const base::DictionaryValue* item2 = NULL;
+ ASSERT_TRUE(trace_events()->GetDictionary(1, &item2));
+
+ TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
+ TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
+ EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
+ actual_item1.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_CANCELLED),
+ actual_item1.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
+ actual_item1.source_type);
+
+ EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
+ EXPECT_EQ(base::StringPrintf("0x%d", entries[1].source.id), actual_item2.id);
+ EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
+ actual_item2.phase);
+ EXPECT_EQ(NetLog::EventTypeToString(NetLog::TYPE_REQUEST_ALIVE),
+ actual_item2.name);
+ EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type),
+ actual_item2.source_type);
+
+ std::string item1_params;
+ std::string item2_params;
+ EXPECT_TRUE(item1->GetString("args.params.foo", &item1_params));
+ EXPECT_EQ("bar", item1_params);
+
+ EXPECT_TRUE(item2->GetString("args.params", &item2_params));
+ EXPECT_TRUE(item2_params.empty());
+}
+
+} // namespace
+
+} // namespace net
diff --git a/chromium/net/base/upload_bytes_element_reader.h b/chromium/net/base/upload_bytes_element_reader.h
index 9c7daf3a657..3246d129ed4 100644
--- a/chromium/net/base/upload_bytes_element_reader.h
+++ b/chromium/net/base/upload_bytes_element_reader.h
@@ -20,20 +20,20 @@ namespace net {
class NET_EXPORT UploadBytesElementReader : public UploadElementReader {
public:
UploadBytesElementReader(const char* bytes, uint64 length);
- virtual ~UploadBytesElementReader();
+ ~UploadBytesElementReader() override;
const char* bytes() const { return bytes_; }
uint64 length() const { return length_; }
// UploadElementReader overrides:
- virtual const UploadBytesElementReader* AsBytesReader() const OVERRIDE;
- virtual int Init(const CompletionCallback& callback) OVERRIDE;
- virtual uint64 GetContentLength() const OVERRIDE;
- virtual uint64 BytesRemaining() const OVERRIDE;
- virtual bool IsInMemory() const OVERRIDE;
- virtual int Read(IOBuffer* buf,
- int buf_length,
- const CompletionCallback& callback) OVERRIDE;
+ const UploadBytesElementReader* AsBytesReader() const override;
+ int Init(const CompletionCallback& callback) override;
+ uint64 GetContentLength() const override;
+ uint64 BytesRemaining() const override;
+ bool IsInMemory() const override;
+ int Read(IOBuffer* buf,
+ int buf_length,
+ const CompletionCallback& callback) override;
private:
const char* const bytes_;
@@ -49,7 +49,7 @@ class NET_EXPORT UploadOwnedBytesElementReader
public:
// |data| is cleared by this ctor.
explicit UploadOwnedBytesElementReader(std::vector<char>* data);
- virtual ~UploadOwnedBytesElementReader();
+ ~UploadOwnedBytesElementReader() override;
// Creates UploadOwnedBytesElementReader with a string.
static UploadOwnedBytesElementReader* CreateWithString(
diff --git a/chromium/net/base/upload_bytes_element_reader_unittest.cc b/chromium/net/base/upload_bytes_element_reader_unittest.cc
index 1aad55ee5ce..1d2f52ffb2c 100644
--- a/chromium/net/base/upload_bytes_element_reader_unittest.cc
+++ b/chromium/net/base/upload_bytes_element_reader_unittest.cc
@@ -15,7 +15,7 @@ namespace net {
class UploadBytesElementReaderTest : public PlatformTest {
protected:
- virtual void SetUp() OVERRIDE {
+ void SetUp() override {
const char kData[] = "123abc";
bytes_.assign(kData, kData + arraysize(kData));
reader_.reset(new UploadBytesElementReader(&bytes_[0], bytes_.size()));
diff --git a/chromium/net/base/upload_data_stream.cc b/chromium/net/base/upload_data_stream.cc
index 785d5e936c7..936c9128833 100644
--- a/chromium/net/base/upload_data_stream.cc
+++ b/chromium/net/base/upload_data_stream.cc
@@ -4,261 +4,125 @@
#include "net/base/upload_data_stream.h"
+#include "base/callback_helpers.h"
#include "base/logging.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
-#include "net/base/upload_bytes_element_reader.h"
-#include "net/base/upload_element_reader.h"
namespace net {
-UploadDataStream::UploadDataStream(
- ScopedVector<UploadElementReader> element_readers,
- int64 identifier)
- : element_readers_(element_readers.Pass()),
- element_index_(0),
- total_size_(0),
+UploadDataStream::UploadDataStream(bool is_chunked, int64 identifier)
+ : total_size_(0),
current_position_(0),
identifier_(identifier),
- is_chunked_(false),
- last_chunk_appended_(false),
- read_failed_(false),
+ is_chunked_(is_chunked),
initialized_successfully_(false),
- weak_ptr_factory_(this) {
-}
-
-UploadDataStream::UploadDataStream(Chunked /*chunked*/, int64 identifier)
- : element_index_(0),
- total_size_(0),
- current_position_(0),
- identifier_(identifier),
- is_chunked_(true),
- last_chunk_appended_(false),
- read_failed_(false),
- initialized_successfully_(false),
- weak_ptr_factory_(this) {
+ is_eof_(false) {
}
UploadDataStream::~UploadDataStream() {
}
-UploadDataStream* UploadDataStream::CreateWithReader(
- scoped_ptr<UploadElementReader> reader,
- int64 identifier) {
- ScopedVector<UploadElementReader> readers;
- readers.push_back(reader.release());
- return new UploadDataStream(readers.Pass(), identifier);
-}
-
int UploadDataStream::Init(const CompletionCallback& callback) {
Reset();
- return InitInternal(0, callback);
+ DCHECK(!initialized_successfully_);
+ DCHECK(callback_.is_null());
+ DCHECK(!callback.is_null() || IsInMemory());
+ int result = InitInternal();
+ if (result == ERR_IO_PENDING) {
+ DCHECK(!IsInMemory());
+ callback_ = callback;
+ } else {
+ OnInitCompleted(result);
+ }
+ return result;
}
int UploadDataStream::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
+ DCHECK(!callback.is_null() || IsInMemory());
DCHECK(initialized_successfully_);
DCHECK_GT(buf_len, 0);
- return ReadInternal(new DrainableIOBuffer(buf, buf_len), callback);
+ if (is_eof_)
+ return 0;
+ int result = ReadInternal(buf, buf_len);
+ if (result == ERR_IO_PENDING) {
+ DCHECK(!IsInMemory());
+ callback_ = callback;
+ } else {
+ OnReadCompleted(result);
+ }
+ return result;
}
bool UploadDataStream::IsEOF() const {
DCHECK(initialized_successfully_);
- if (!is_chunked_)
- return current_position_ == total_size_;
-
- // If the upload data is chunked, check if the last chunk is appended and all
- // elements are consumed.
- return element_index_ == element_readers_.size() && last_chunk_appended_;
-}
-
-bool UploadDataStream::IsInMemory() const {
- // Chunks are in memory, but UploadData does not have all the chunks at
- // once. Chunks are provided progressively with AppendChunk() as chunks
- // are ready. Check is_chunked_ here, rather than relying on the loop
- // below, as there is a case that is_chunked_ is set to true, but the
- // first chunk is not yet delivered.
- if (is_chunked_)
- return false;
-
- for (size_t i = 0; i < element_readers_.size(); ++i) {
- if (!element_readers_[i]->IsInMemory())
- return false;
- }
- return true;
-}
-
-void UploadDataStream::AppendChunk(const char* bytes,
- int bytes_len,
- bool is_last_chunk) {
- DCHECK(is_chunked_);
- DCHECK(!last_chunk_appended_);
- last_chunk_appended_ = is_last_chunk;
-
- // Initialize a reader for the newly appended chunk. We leave |total_size_| at
- // zero, since for chunked uploads, we may not know the total size.
- std::vector<char> data(bytes, bytes + bytes_len);
- UploadElementReader* reader = new UploadOwnedBytesElementReader(&data);
- const int rv = reader->Init(net::CompletionCallback());
- DCHECK_EQ(OK, rv);
- element_readers_.push_back(reader);
-
- // Resume pending read.
- if (!pending_chunked_read_callback_.is_null()) {
- base::Closure callback = pending_chunked_read_callback_;
- pending_chunked_read_callback_.Reset();
- callback.Run();
- }
+ DCHECK(is_chunked_ || is_eof_ == (current_position_ == total_size_));
+ return is_eof_;
}
void UploadDataStream::Reset() {
- weak_ptr_factory_.InvalidateWeakPtrs();
- pending_chunked_read_callback_.Reset();
- initialized_successfully_ = false;
- read_failed_ = false;
current_position_ = 0;
+ initialized_successfully_ = false;
+ is_eof_ = false;
total_size_ = 0;
- element_index_ = 0;
+ callback_.Reset();
+ ResetInternal();
}
-int UploadDataStream::InitInternal(int start_index,
- const CompletionCallback& callback) {
+void UploadDataStream::SetSize(uint64 size) {
DCHECK(!initialized_successfully_);
+ DCHECK(!is_chunked_);
+ total_size_ = size;
+}
- // Call Init() for all elements.
- for (size_t i = start_index; i < element_readers_.size(); ++i) {
- UploadElementReader* reader = element_readers_[i];
- // When new_result is ERR_IO_PENDING, InitInternal() will be called
- // with start_index == i + 1 when reader->Init() finishes.
- const int result = reader->Init(
- base::Bind(&UploadDataStream::ResumePendingInit,
- weak_ptr_factory_.GetWeakPtr(),
- i + 1,
- callback));
- if (result != OK) {
- DCHECK(result != ERR_IO_PENDING || !callback.is_null());
- return result;
- }
- }
+void UploadDataStream::SetIsFinalChunk() {
+ DCHECK(initialized_successfully_);
+ DCHECK(is_chunked_);
+ DCHECK(!is_eof_);
+ is_eof_ = true;
+}
- // Finalize initialization.
- if (!is_chunked_) {
- uint64 total_size = 0;
- for (size_t i = 0; i < element_readers_.size(); ++i) {
- UploadElementReader* reader = element_readers_[i];
- total_size += reader->GetContentLength();
- }
- total_size_ = total_size;
- }
- initialized_successfully_ = true;
- return OK;
+bool UploadDataStream::IsInMemory() const {
+ return false;
+}
+
+const ScopedVector<UploadElementReader>*
+UploadDataStream::GetElementReaders() const {
+ return NULL;
}
-void UploadDataStream::ResumePendingInit(int start_index,
- const CompletionCallback& callback,
- int previous_result) {
+void UploadDataStream::OnInitCompleted(int result) {
+ DCHECK_NE(ERR_IO_PENDING, result);
DCHECK(!initialized_successfully_);
- DCHECK(!callback.is_null());
- DCHECK_NE(ERR_IO_PENDING, previous_result);
+ DCHECK_EQ(0u, current_position_);
+ DCHECK(!is_eof_);
- // Check the last result.
- if (previous_result != OK) {
- callback.Run(previous_result);
- return;
+ if (result == OK) {
+ initialized_successfully_ = true;
+ if (!is_chunked_ && total_size_ == 0)
+ is_eof_ = true;
}
-
- const int result = InitInternal(start_index, callback);
- if (result != ERR_IO_PENDING)
- callback.Run(result);
+ if (!callback_.is_null())
+ base::ResetAndReturn(&callback_).Run(result);
}
-int UploadDataStream::ReadInternal(scoped_refptr<DrainableIOBuffer> buf,
- const CompletionCallback& callback) {
+void UploadDataStream::OnReadCompleted(int result) {
+ DCHECK_GE(result, 0);
DCHECK(initialized_successfully_);
- while (!read_failed_ && element_index_ < element_readers_.size()) {
- UploadElementReader* reader = element_readers_[element_index_];
-
- if (reader->BytesRemaining() == 0) {
- ++element_index_;
- continue;
- }
-
- if (buf->BytesRemaining() == 0)
- break;
-
- int result = reader->Read(
- buf.get(),
- buf->BytesRemaining(),
- base::Bind(base::IgnoreResult(&UploadDataStream::ResumePendingRead),
- weak_ptr_factory_.GetWeakPtr(),
- buf,
- callback));
- if (result == ERR_IO_PENDING) {
- DCHECK(!callback.is_null());
- return ERR_IO_PENDING;
- }
- ProcessReadResult(buf, result);
- }
-
- if (read_failed_) {
- // Chunked transfers may only contain byte readers, so cannot have read
- // failures.
- DCHECK(!is_chunked_);
-
- // If an error occured during read operation, then pad with zero.
- // Otherwise the server will hang waiting for the rest of the data.
- const int num_bytes_to_fill =
- std::min(static_cast<uint64>(buf->BytesRemaining()),
- size() - position() - buf->BytesConsumed());
- DCHECK_LE(0, num_bytes_to_fill);
- memset(buf->data(), 0, num_bytes_to_fill);
- buf->DidConsume(num_bytes_to_fill);
- }
-
- const int bytes_copied = buf->BytesConsumed();
- current_position_ += bytes_copied;
- DCHECK(is_chunked_ || total_size_ >= current_position_);
-
- if (is_chunked_ && !IsEOF() && bytes_copied == 0) {
- DCHECK(!callback.is_null());
- DCHECK(pending_chunked_read_callback_.is_null());
- pending_chunked_read_callback_ =
- base::Bind(&UploadDataStream::ResumePendingRead,
- weak_ptr_factory_.GetWeakPtr(),
- buf,
- callback,
- OK);
- return ERR_IO_PENDING;
+ current_position_ += result;
+ if (!is_chunked_) {
+ DCHECK_LE(current_position_, total_size_);
+ if (current_position_ == total_size_)
+ is_eof_ = true;
}
- // Returning 0 is allowed only when IsEOF() == true.
- DCHECK(bytes_copied != 0 || IsEOF());
- return bytes_copied;
-}
-
-void UploadDataStream::ResumePendingRead(scoped_refptr<DrainableIOBuffer> buf,
- const CompletionCallback& callback,
- int previous_result) {
- DCHECK(!callback.is_null());
-
- ProcessReadResult(buf, previous_result);
-
- const int result = ReadInternal(buf, callback);
- if (result != ERR_IO_PENDING)
- callback.Run(result);
-}
-
-void UploadDataStream::ProcessReadResult(scoped_refptr<DrainableIOBuffer> buf,
- int result) {
- DCHECK_NE(ERR_IO_PENDING, result);
- DCHECK(!read_failed_);
+ DCHECK(result > 0 || is_eof_);
- if (result >= 0)
- buf->DidConsume(result);
- else
- read_failed_ = true;
+ if (!callback_.is_null())
+ base::ResetAndReturn(&callback_).Run(result);
}
} // namespace net
diff --git a/chromium/net/base/upload_data_stream.h b/chromium/net/base/upload_data_stream.h
index ac14e38086f..d7df8c9ae44 100644
--- a/chromium/net/base/upload_data_stream.h
+++ b/chromium/net/base/upload_data_stream.h
@@ -5,10 +5,9 @@
#ifndef NET_BASE_UPLOAD_DATA_STREAM_H_
#define NET_BASE_UPLOAD_DATA_STREAM_H_
-#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
+#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/memory/scoped_vector.h"
-#include "base/memory/weak_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -18,31 +17,22 @@ class DrainableIOBuffer;
class IOBuffer;
class UploadElementReader;
-// A class to read all elements from an UploadData object.
+// A class for retrieving all data to be sent as a request body. Supports both
+// chunked and non-chunked uploads.
class NET_EXPORT UploadDataStream {
public:
- // An enum used to construct chunked data stream.
- enum Chunked { CHUNKED };
+ // |identifier| identifies a particular upload instance, which is used by the
+ // cache to formulate a cache key. This value should be unique across browser
+ // sessions. A value of 0 is used to indicate an unspecified identifier.
+ UploadDataStream(bool is_chunked, int64 identifier);
- // Constructs a non-chunked data stream.
- UploadDataStream(ScopedVector<UploadElementReader> element_readers,
- int64 identifier);
-
- // Constructs a chunked data stream.
- UploadDataStream(Chunked chunked, int64 identifier);
-
- ~UploadDataStream();
-
- // Creates UploadDataStream with a reader.
- static UploadDataStream* CreateWithReader(
- scoped_ptr<UploadElementReader> reader,
- int64 identifier);
+ virtual ~UploadDataStream();
// Initializes the stream. This function must be called before calling any
// other method. It is not valid to call any method (other than the
- // destructor) if Init() returns a failure. This method can be called multiple
- // times. Calling this method after a Init() success results in resetting the
- // state.
+ // destructor) if Init() fails. This method can be called multiple times.
+ // Calling this method after an Init() success results in resetting the
+ // state (i.e. the stream is rewound).
//
// Does the initialization synchronously and returns the result if possible,
// otherwise returns ERR_IO_PENDING and runs the callback with the result.
@@ -62,93 +52,88 @@ class NET_EXPORT UploadDataStream {
// If there's less data to read than we initially observed (i.e. the actual
// upload data is smaller than size()), zeros are padded to ensure that
// size() bytes can be read, which can happen for TYPE_FILE payloads.
+ //
+ // Reads are currently not allowed to fail - they must either return
+ // a value >= 0 or ERR_IO_PENDING, and call OnReadCompleted with a
+ // value >= 0.
+ // TODO(mmenke): Investigate letting reads fail.
int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
- // Identifies a particular upload instance, which is used by the cache to
- // formulate a cache key. This value should be unique across browser
- // sessions. A value of 0 is used to indicate an unspecified identifier.
- int64 identifier() const { return identifier_; }
-
// Returns the total size of the data stream and the current position.
- // size() is not to be used to determine whether the stream has ended
- // because it is possible for the stream to end before its size is reached,
- // for example, if the file is truncated. When the data is chunked, size()
- // always returns zero.
+ // When the data is chunked, always returns zero. Must always return the same
+ // value after each call to Initialize().
uint64 size() const { return total_size_; }
uint64 position() const { return current_position_; }
- bool is_chunked() const { return is_chunked_; }
- bool last_chunk_appended() const { return last_chunk_appended_; }
+ // See constructor for description.
+ int64 identifier() const { return identifier_; }
- const ScopedVector<UploadElementReader>& element_readers() const {
- return element_readers_;
- }
+ bool is_chunked() const { return is_chunked_; }
// Returns true if all data has been consumed from this upload data
- // stream.
+ // stream. For chunked uploads, returns false until the first read attempt.
+ // This makes some state machines a little simpler.
bool IsEOF() const;
- // Returns true if the upload data in the stream is entirely in memory.
- bool IsInMemory() const;
+ // Cancels all pending callbacks, and resets state. Any IOBuffer currently
+ // being read to is not safe for future use, as it may be in use on another
+ // thread.
+ void Reset();
+
+ // Returns true if the upload data in the stream is entirely in memory, and
+ // all read requests will succeed synchronously. Expected to return false for
+ // chunked requests.
+ virtual bool IsInMemory() const;
- // Adds the given chunk of bytes to be sent with chunked transfer encoding.
- void AppendChunk(const char* bytes, int bytes_len, bool is_last_chunk);
+ // Returns a list of element readers owned by |this|, if it has any.
+ virtual const ScopedVector<UploadElementReader>*
+ GetElementReaders() const;
- // Resets this instance to the uninitialized state.
- void Reset();
+ protected:
+ // Must be called by subclasses when InitInternal and ReadInternal complete
+ // asynchronously.
+ void OnInitCompleted(int result);
+ void OnReadCompleted(int result);
+
+ // Must be called before InitInternal completes, for non-chunked uploads.
+ // Must not be called for chunked uploads.
+ void SetSize(uint64 size);
+
+ // Must be called for chunked uploads before the final ReadInternal call
+ // completes. Must not be called for non-chunked uploads.
+ void SetIsFinalChunk();
private:
- // Runs Init() for all element readers.
- // This method is used to implement Init().
- int InitInternal(int start_index, const CompletionCallback& callback);
-
- // Resumes initialization and runs callback with the result when necessary.
- void ResumePendingInit(int start_index,
- const CompletionCallback& callback,
- int previous_result);
-
- // Reads data from the element readers.
- // This method is used to implement Read().
- int ReadInternal(scoped_refptr<DrainableIOBuffer> buf,
- const CompletionCallback& callback);
-
- // Resumes pending read and calls callback with the result when necessary.
- void ResumePendingRead(scoped_refptr<DrainableIOBuffer> buf,
- const CompletionCallback& callback,
- int previous_result);
-
- // Processes result of UploadElementReader::Read(). If |result| indicates
- // success, updates |buf|'s offset. Otherwise, sets |read_failed_| to true.
- void ProcessReadResult(scoped_refptr<DrainableIOBuffer> buf,
- int result);
-
- ScopedVector<UploadElementReader> element_readers_;
-
- // Index of the current upload element (i.e. the element currently being
- // read). The index is used as a cursor to iterate over elements in
- // |upload_data_|.
- size_t element_index_;
-
- // Size and current read position within the upload data stream.
- // |total_size_| is set to zero when the data is chunked.
+ // See Init(). If it returns ERR_IO_PENDING, OnInitCompleted must be called
+ // once it completes. If the upload is not chunked, SetSize must be called
+ // before it completes.
+ virtual int InitInternal() = 0;
+
+ // See Read(). For chunked uploads, must call SetIsFinalChunk if this is the
+ // final chunk. For non-chunked uploads, the UploadDataStream determins which
+ // read is the last based on size. Must read 1 or more bytes on every call,
+ // though the final chunk may be 0 bytes, for chunked requests. If it returns
+ // ERR_IO_PENDING, OnInitCompleted must be called once it completes. Must not
+ // return any error, other than ERR_IO_PENDING.
+ virtual int ReadInternal(IOBuffer* buf, int buf_len) = 0;
+
+ // Resets state and cancels any pending callbacks. Guaranteed to be called
+ // before all but the first call to InitInternal.
+ virtual void ResetInternal() = 0;
+
uint64 total_size_;
uint64 current_position_;
const int64 identifier_;
const bool is_chunked_;
- bool last_chunk_appended_;
-
- // True if an error occcured during read operation.
- bool read_failed_;
// True if the initialization was successful.
bool initialized_successfully_;
- // Callback to resume reading chunked data.
- base::Closure pending_chunked_read_callback_;
+ bool is_eof_;
- base::WeakPtrFactory<UploadDataStream> weak_ptr_factory_;
+ CompletionCallback callback_;
DISALLOW_COPY_AND_ASSIGN(UploadDataStream);
};
diff --git a/chromium/net/base/upload_element.cc b/chromium/net/base/upload_element.cc
deleted file mode 100644
index 6b6438aec26..00000000000
--- a/chromium/net/base/upload_element.cc
+++ /dev/null
@@ -1,25 +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/upload_element.h"
-
-#include <algorithm>
-
-#include "net/base/file_stream.h"
-#include "net/base/net_errors.h"
-
-namespace net {
-
-UploadElement::UploadElement()
- : type_(TYPE_BYTES),
- bytes_start_(NULL),
- bytes_length_(0),
- file_range_offset_(0),
- file_range_length_(kuint64max) {
-}
-
-UploadElement::~UploadElement() {
-}
-
-} // namespace net
diff --git a/chromium/net/base/upload_element.h b/chromium/net/base/upload_element.h
deleted file mode 100644
index 34f601464d9..00000000000
--- a/chromium/net/base/upload_element.h
+++ /dev/null
@@ -1,110 +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.
-
-#ifndef NET_BASE_UPLOAD_ELEMENT_H_
-#define NET_BASE_UPLOAD_ELEMENT_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/files/file_path.h"
-#include "base/time/time.h"
-#include "net/base/net_export.h"
-
-namespace net {
-
-// A class representing an element contained by UploadData.
-class NET_EXPORT UploadElement {
- public:
- enum Type {
- TYPE_BYTES,
- TYPE_FILE,
- };
-
- UploadElement();
- ~UploadElement();
-
- Type type() const { return type_; }
-
- const char* bytes() const { return bytes_start_ ? bytes_start_ : &buf_[0]; }
- uint64 bytes_length() const { return buf_.size() + bytes_length_; }
- const base::FilePath& file_path() const { return file_path_; }
- uint64 file_range_offset() const { return file_range_offset_; }
- uint64 file_range_length() const { return file_range_length_; }
- // If NULL time is returned, we do not do the check.
- const base::Time& expected_file_modification_time() const {
- return expected_file_modification_time_;
- }
-
- void SetToBytes(const char* bytes, int bytes_len) {
- type_ = TYPE_BYTES;
- buf_.assign(bytes, bytes + bytes_len);
- }
-
- // This does not copy the given data and the caller should make sure
- // the data is secured somewhere else (e.g. by attaching the data
- // using SetUserData).
- void SetToSharedBytes(const char* bytes, int bytes_len) {
- type_ = TYPE_BYTES;
- bytes_start_ = bytes;
- bytes_length_ = bytes_len;
- }
-
- void SetToFilePath(const base::FilePath& path) {
- SetToFilePathRange(path, 0, kuint64max, base::Time());
- }
-
- // If expected_modification_time is NULL, we do not check for the file
- // change. Also note that the granularity for comparison is time_t, not
- // the full precision.
- void SetToFilePathRange(const base::FilePath& path,
- uint64 offset, uint64 length,
- const base::Time& expected_modification_time) {
- type_ = TYPE_FILE;
- file_path_ = path;
- file_range_offset_ = offset;
- file_range_length_ = length;
- expected_file_modification_time_ = expected_modification_time;
- }
-
- private:
- Type type_;
- std::vector<char> buf_;
- const char* bytes_start_;
- uint64 bytes_length_;
- base::FilePath file_path_;
- uint64 file_range_offset_;
- uint64 file_range_length_;
- base::Time expected_file_modification_time_;
-
- DISALLOW_COPY_AND_ASSIGN(UploadElement);
-};
-
-#if defined(UNIT_TEST)
-inline bool operator==(const UploadElement& a,
- const UploadElement& b) {
- if (a.type() != b.type())
- return false;
- if (a.type() == UploadElement::TYPE_BYTES)
- return a.bytes_length() == b.bytes_length() &&
- memcmp(a.bytes(), b.bytes(), b.bytes_length()) == 0;
- if (a.type() == UploadElement::TYPE_FILE) {
- return a.file_path() == b.file_path() &&
- a.file_range_offset() == b.file_range_offset() &&
- a.file_range_length() == b.file_range_length() &&
- a.expected_file_modification_time() ==
- b.expected_file_modification_time();
- }
- return false;
-}
-
-inline bool operator!=(const UploadElement& a,
- const UploadElement& b) {
- return !(a == b);
-}
-#endif // defined(UNIT_TEST)
-
-} // namespace net
-
-#endif // NET_BASE_UPLOAD_ELEMENT_H_
diff --git a/chromium/net/base/upload_element_reader.h b/chromium/net/base/upload_element_reader.h
index d71f57cdb64..a46b9709fa8 100644
--- a/chromium/net/base/upload_element_reader.h
+++ b/chromium/net/base/upload_element_reader.h
@@ -35,8 +35,8 @@ class NET_EXPORT UploadElementReader {
// state.
virtual int Init(const CompletionCallback& callback) = 0;
- // Returns the byte-length of the element. For files that do not exist, 0
- // is returned. This is done for consistency with Mozilla.
+ // Returns the byte-length of the element. For files that do not exist, 0
+ // is returned. This is done for consistency with Mozilla.
virtual uint64 GetContentLength() const = 0;
// Returns the number of bytes remaining to read.
diff --git a/chromium/net/base/upload_file_element_reader.cc b/chromium/net/base/upload_file_element_reader.cc
index f8775ee567b..46824668cce 100644
--- a/chromium/net/base/upload_file_element_reader.cc
+++ b/chromium/net/base/upload_file_element_reader.cc
@@ -5,8 +5,9 @@
#include "net/base/upload_file_element_reader.h"
#include "base/bind.h"
-#include "base/file_util.h"
+#include "base/files/file_util.h"
#include "base/location.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/task_runner_util.h"
#include "net/base/file_stream.h"
#include "net/base/io_buffer.h"
@@ -103,6 +104,11 @@ void UploadFileElementReader::Reset() {
void UploadFileElementReader::OnOpenCompleted(
const CompletionCallback& callback,
int result) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 UploadFileElementReader::OnOpenCompleted"));
+
DCHECK(!callback.is_null());
if (result < 0) {
@@ -114,7 +120,7 @@ void UploadFileElementReader::OnOpenCompleted(
if (range_offset_) {
int result = file_stream_->Seek(
- FROM_BEGIN, range_offset_,
+ base::File::FROM_BEGIN, range_offset_,
base::Bind(&UploadFileElementReader::OnSeekCompleted,
weak_ptr_factory_.GetWeakPtr(),
callback));
@@ -140,11 +146,9 @@ void UploadFileElementReader::OnSeekCompleted(
base::File::Info* file_info = new base::File::Info;
bool posted = base::PostTaskAndReplyWithResult(
- task_runner_,
+ task_runner_.get(),
FROM_HERE,
- base::Bind(&base::GetFileInfo,
- path_,
- file_info),
+ base::Bind(&base::GetFileInfo, path_, file_info),
base::Bind(&UploadFileElementReader::OnGetFileInfoCompleted,
weak_ptr_factory_.GetWeakPtr(),
callback,
diff --git a/chromium/net/base/upload_file_element_reader.h b/chromium/net/base/upload_file_element_reader.h
index 12427174377..fc3f3349a8b 100644
--- a/chromium/net/base/upload_file_element_reader.h
+++ b/chromium/net/base/upload_file_element_reader.h
@@ -32,7 +32,7 @@ class NET_EXPORT UploadFileElementReader : public UploadElementReader {
uint64 range_offset,
uint64 range_length,
const base::Time& expected_modification_time);
- virtual ~UploadFileElementReader();
+ ~UploadFileElementReader() override;
const base::FilePath& path() const { return path_; }
uint64 range_offset() const { return range_offset_; }
@@ -42,22 +42,18 @@ class NET_EXPORT UploadFileElementReader : public UploadElementReader {
}
// UploadElementReader overrides:
- virtual const UploadFileElementReader* AsFileReader() const OVERRIDE;
- virtual int Init(const CompletionCallback& callback) OVERRIDE;
- virtual uint64 GetContentLength() const OVERRIDE;
- virtual uint64 BytesRemaining() const OVERRIDE;
- virtual int Read(IOBuffer* buf,
- int buf_length,
- const CompletionCallback& callback) OVERRIDE;
+ const UploadFileElementReader* AsFileReader() const override;
+ int Init(const CompletionCallback& callback) override;
+ uint64 GetContentLength() const override;
+ uint64 BytesRemaining() const override;
+ int Read(IOBuffer* buf,
+ int buf_length,
+ const CompletionCallback& callback) override;
private:
- FRIEND_TEST_ALL_PREFIXES(UploadDataStreamTest, FileSmallerThanLength);
+ FRIEND_TEST_ALL_PREFIXES(ElementsUploadDataStreamTest, FileSmallerThanLength);
FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
UploadFileSmallerThanLength);
- FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionSpdy2Test,
- UploadFileSmallerThanLength);
- FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionSpdy3Test,
- UploadFileSmallerThanLength);
// Resets this instance to the uninitialized state.
void Reset();
diff --git a/chromium/net/base/upload_file_element_reader_unittest.cc b/chromium/net/base/upload_file_element_reader_unittest.cc
index 395b8673724..b0374acd966 100644
--- a/chromium/net/base/upload_file_element_reader_unittest.cc
+++ b/chromium/net/base/upload_file_element_reader_unittest.cc
@@ -4,7 +4,7 @@
#include "net/base/upload_file_element_reader.h"
-#include "base/file_util.h"
+#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/run_loop.h"
@@ -18,7 +18,7 @@ namespace net {
class UploadFileElementReaderTest : public PlatformTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
PlatformTest::SetUp();
// Some tests (*.ReadPartially) rely on bytes_.size() being even.
const char kData[] = "123456789abcdefghi";
@@ -46,7 +46,7 @@ class UploadFileElementReaderTest : public PlatformTest {
EXPECT_FALSE(reader_->IsInMemory());
}
- virtual ~UploadFileElementReaderTest() {
+ ~UploadFileElementReaderTest() override {
reader_.reset();
base::RunLoop().RunUntilIdle();
}