summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsammc <sammc@chromium.org>2015-06-28 19:58:47 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-29 02:59:20 +0000
commitf2d1ea00bc13c6e742c9c3bffa78d4c009c63e7e (patch)
tree19e908025d9cc6dbbb1068496f14e806b2b105ee
parent1e0de6aa93e9534a4c88abd457e4169f6fe4c863 (diff)
downloadchromium_src-f2d1ea00bc13c6e742c9c3bffa78d4c009c63e7e.zip
chromium_src-f2d1ea00bc13c6e742c9c3bffa78d4c009c63e7e.tar.gz
chromium_src-f2d1ea00bc13c6e742c9c3bffa78d4c009c63e7e.tar.bz2
Split ProxyResolverV8Tracing into an implementation and a wrapper.
The implementation-specific interfaces use a Bindings interface for reporting alerts and errors and making DNS requests. This allows a user to provide an implementation instead of forwarding to a fixed NetLog and HostResolver. The wrappers implement the ProxyResolver and ProxyResolverFactory interfaces, mostly matching the previous behavior. The one exception is that LoadState change reporting has been removed; the one user (MojoProxyResolverImpl) will soon use the implementation interface directly instead. BUG=467832 Review URL: https://codereview.chromium.org/1145153004 Cr-Commit-Position: refs/heads/master@{#336525}
-rw-r--r--net/BUILD.gn6
-rw-r--r--net/interfaces/proxy_resolver_service.mojom4
-rw-r--r--net/net.gyp6
-rw-r--r--net/net.gypi2
-rw-r--r--net/proxy/load_state_change_coalescer.cc36
-rw-r--r--net/proxy/load_state_change_coalescer.h52
-rw-r--r--net/proxy/load_state_change_coalescer_unittest.cc83
-rw-r--r--net/proxy/mojo_proxy_resolver_factory_impl.cc54
-rw-r--r--net/proxy/mojo_proxy_resolver_factory_impl.h3
-rw-r--r--net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc4
-rw-r--r--net/proxy/mojo_proxy_resolver_impl.cc41
-rw-r--r--net/proxy/mojo_proxy_resolver_impl.h10
-rw-r--r--net/proxy/mojo_proxy_resolver_impl_unittest.cc28
-rw-r--r--net/proxy/proxy_resolver.h3
-rw-r--r--net/proxy/proxy_resolver_factory_mojo.cc8
-rw-r--r--net/proxy/proxy_resolver_factory_mojo_unittest.cc30
-rw-r--r--net/proxy/proxy_resolver_v8_tracing.cc278
-rw-r--r--net/proxy/proxy_resolver_v8_tracing.h108
-rw-r--r--net/proxy/proxy_resolver_v8_tracing_unittest.cc693
-rw-r--r--net/proxy/proxy_resolver_v8_tracing_wrapper.cc193
-rw-r--r--net/proxy/proxy_resolver_v8_tracing_wrapper.h65
-rw-r--r--net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc1145
-rw-r--r--net/proxy/proxy_service_v8.cc6
23 files changed, 1883 insertions, 975 deletions
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 2fdc390..8edf028 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -768,6 +768,8 @@ if (use_v8_in_net) {
"proxy/proxy_resolver_v8.h",
"proxy/proxy_resolver_v8_tracing.cc",
"proxy/proxy_resolver_v8_tracing.h",
+ "proxy/proxy_resolver_v8_tracing_wrapper.cc",
+ "proxy/proxy_resolver_v8_tracing_wrapper.h",
"proxy/proxy_service_v8.cc",
"proxy/proxy_service_v8.h",
]
@@ -839,8 +841,6 @@ if (use_v8_in_net && !is_android) {
sources = [
"dns/host_resolver_mojo.cc",
"dns/host_resolver_mojo.h",
- "proxy/load_state_change_coalescer.cc",
- "proxy/load_state_change_coalescer.h",
"proxy/mojo_proxy_resolver_factory_impl.cc",
"proxy/mojo_proxy_resolver_factory_impl.h",
"proxy/mojo_proxy_resolver_impl.cc",
@@ -1481,6 +1481,7 @@ if (!is_android && !is_mac) {
} else {
sources -= [
"proxy/proxy_resolver_v8_tracing_unittest.cc",
+ "proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc",
"proxy/proxy_resolver_v8_unittest.cc",
]
}
@@ -1496,7 +1497,6 @@ if (!is_android && !is_mac) {
sources -= [
"dns/host_resolver_mojo_unittest.cc",
"dns/mojo_host_resolver_impl_unittest.cc",
- "proxy/load_state_change_coalescer_unittest.cc",
"proxy/mojo_proxy_resolver_factory_impl_unittest.cc",
"proxy/mojo_proxy_resolver_impl_unittest.cc",
"proxy/proxy_resolver_error_observer_mojo_unittest.cc",
diff --git a/net/interfaces/proxy_resolver_service.mojom b/net/interfaces/proxy_resolver_service.mojom
index 68f798e..133fe8b 100644
--- a/net/interfaces/proxy_resolver_service.mojom
+++ b/net/interfaces/proxy_resolver_service.mojom
@@ -31,15 +31,13 @@ struct ProxyServer {
interface ProxyResolver {
// Use a ProxyResolverRequestClient instead of returning a result so we can
- // receive load state updates and cancel in-flight requests by destroying the
- // client.
+ // cancel in-flight requests by destroying the client.
// TODO(amistry): Add BoundNetLog.
GetProxyForUrl(string url, ProxyResolverRequestClient client);
};
interface ProxyResolverRequestClient {
ReportResult(int32 error, array<ProxyServer>? proxy_servers);
- LoadStateChanged(int32 load_state);
};
interface ProxyResolverErrorObserver {
diff --git a/net/net.gyp b/net/net.gyp
index 4482264..c450f47 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -301,6 +301,7 @@
}, { # else: !use_v8_in_net
'sources!': [
'proxy/proxy_resolver_v8_tracing_unittest.cc',
+ 'proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc',
'proxy/proxy_resolver_v8_unittest.cc',
],
},
@@ -317,7 +318,6 @@
'sources!': [
'dns/host_resolver_mojo_unittest.cc',
'dns/mojo_host_resolver_impl_unittest.cc',
- 'proxy/load_state_change_coalescer_unittest.cc',
'proxy/mojo_proxy_resolver_factory_impl_unittest.cc',
'proxy/mojo_proxy_resolver_impl_unittest.cc',
'proxy/proxy_resolver_error_observer_mojo_unittest.cc',
@@ -869,6 +869,8 @@
'proxy/proxy_resolver_v8.h',
'proxy/proxy_resolver_v8_tracing.cc',
'proxy/proxy_resolver_v8_tracing.h',
+ 'proxy/proxy_resolver_v8_tracing_wrapper.cc',
+ 'proxy/proxy_resolver_v8_tracing_wrapper.h',
'proxy/proxy_service_v8.cc',
'proxy/proxy_service_v8.h',
],
@@ -930,8 +932,6 @@
'sources': [
'dns/host_resolver_mojo.cc',
'dns/host_resolver_mojo.h',
- 'proxy/load_state_change_coalescer.cc',
- 'proxy/load_state_change_coalescer.h',
'proxy/mojo_proxy_resolver_factory_impl.cc',
'proxy/mojo_proxy_resolver_factory_impl.h',
'proxy/mojo_proxy_resolver_impl.cc',
diff --git a/net/net.gypi b/net/net.gypi
index 5a86dee..6283632 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -1480,7 +1480,6 @@
'proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc',
'proxy/dhcp_proxy_script_fetcher_factory_unittest.cc',
'proxy/dhcp_proxy_script_fetcher_win_unittest.cc',
- 'proxy/load_state_change_coalescer_unittest.cc',
'proxy/mojo_proxy_resolver_factory_impl_unittest.cc',
'proxy/mojo_proxy_resolver_impl_unittest.cc',
'proxy/multi_threaded_proxy_resolver_unittest.cc',
@@ -1495,6 +1494,7 @@
'proxy/proxy_resolver_error_observer_mojo_unittest.cc',
'proxy/proxy_resolver_factory_mojo_unittest.cc',
'proxy/proxy_resolver_v8_tracing_unittest.cc',
+ 'proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc',
'proxy/proxy_resolver_v8_unittest.cc',
'proxy/proxy_script_decider_unittest.cc',
'proxy/proxy_script_fetcher_impl_unittest.cc',
diff --git a/net/proxy/load_state_change_coalescer.cc b/net/proxy/load_state_change_coalescer.cc
deleted file mode 100644
index ae15e53..0000000
--- a/net/proxy/load_state_change_coalescer.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 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/proxy/load_state_change_coalescer.h"
-
-namespace net {
-
-LoadStateChangeCoalescer::LoadStateChangeCoalescer(
- const base::Callback<void(LoadState)>& callback,
- const base::TimeDelta& timeout,
- LoadState initial_load_state)
- : callback_(callback),
- timeout_(timeout),
- committed_load_state_(initial_load_state),
- pending_load_state_(initial_load_state) {
-}
-
-void LoadStateChangeCoalescer::LoadStateChanged(LoadState load_state) {
- if (load_state == committed_load_state_) {
- timer_.Stop();
- return;
- }
- pending_load_state_ = load_state;
- timer_.Start(FROM_HERE, timeout_, this,
- &LoadStateChangeCoalescer::SendLoadStateChanged);
-}
-
-LoadStateChangeCoalescer::~LoadStateChangeCoalescer() = default;
-
-void LoadStateChangeCoalescer::SendLoadStateChanged() {
- committed_load_state_ = pending_load_state_;
- callback_.Run(pending_load_state_);
-}
-
-} // namespace net
diff --git a/net/proxy/load_state_change_coalescer.h b/net/proxy/load_state_change_coalescer.h
deleted file mode 100644
index 6425385..0000000
--- a/net/proxy/load_state_change_coalescer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2015 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_PROXY_LOAD_STATE_CHANGE_COALESCER_H_
-#define NET_PROXY_LOAD_STATE_CHANGE_COALESCER_H_
-
-#include "base/cancelable_callback.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "net/base/load_states.h"
-
-namespace net {
-
-// A class that coalesces LoadState changes. When a new LoadState is reported,
-// it becomes the pending LoadState and is queued for |timeout|. If the timeout
-// elapses without another new LoadState, the pending LoadState becomes the
-// committed LoadState and the callback is called with that LoadState. If a new
-// LoadState is reported before the timeout has elapsed, the pending LoadState
-// is discarded and the new LoadState becomes the new pending LoadState, unless
-// it's the same as the committed LoadState, in which case no pending LoadState
-// is queued.
-class LoadStateChangeCoalescer {
- public:
- LoadStateChangeCoalescer(const base::Callback<void(LoadState)>& callback,
- const base::TimeDelta& timeout,
- LoadState initial_load_state);
- ~LoadStateChangeCoalescer();
-
- // Adds a LoadState change to the pipeline. If it isn't coalesced, |callback_|
- // will be called with |load_state| after |timeout_|.
- void LoadStateChanged(LoadState load_state);
-
- private:
- void SendLoadStateChanged();
-
- // The callback to call to report a LoadState change.
- const base::Callback<void(LoadState)> callback_;
-
- // The amount of time for which a LoadState change can be coalesced.
- const base::TimeDelta timeout_;
-
- base::OneShotTimer<LoadStateChangeCoalescer> timer_;
- LoadState committed_load_state_;
- LoadState pending_load_state_;
-
- DISALLOW_COPY_AND_ASSIGN(LoadStateChangeCoalescer);
-};
-
-} // namespace net
-
-#endif // NET_PROXY_LOAD_STATE_CHANGE_COALESCER_H_
diff --git a/net/proxy/load_state_change_coalescer_unittest.cc b/net/proxy/load_state_change_coalescer_unittest.cc
deleted file mode 100644
index e6f8303..0000000
--- a/net/proxy/load_state_change_coalescer_unittest.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2015 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/proxy/load_state_change_coalescer.h"
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-class LoadStateChangeCoalescerTest : public testing::Test {
- protected:
- void SetUp() override {
- coalescer_.reset(new LoadStateChangeCoalescer(
- base::Bind(&LoadStateChangeCoalescerTest::LoadStateChanged,
- base::Unretained(this)),
- base::TimeDelta(), LOAD_STATE_IDLE));
- }
-
- void TearDown() override { coalescer_.reset(); }
-
- void LoadStateChanged(LoadState load_state) {
- load_state_changes_.push_back(load_state);
- }
-
- void WaitUntilIdle() { base::RunLoop().RunUntilIdle(); }
-
- scoped_ptr<LoadStateChangeCoalescer> coalescer_;
- std::vector<LoadState> load_state_changes_;
-};
-
-TEST_F(LoadStateChangeCoalescerTest, SingleChange) {
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_PROXY_FOR_URL);
- WaitUntilIdle();
- ASSERT_EQ(1u, load_state_changes_.size());
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, load_state_changes_[0]);
-}
-
-TEST_F(LoadStateChangeCoalescerTest, TwoChangesCoalesce) {
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_PROXY_FOR_URL);
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- WaitUntilIdle();
- ASSERT_EQ(1u, load_state_changes_.size());
- EXPECT_EQ(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT, load_state_changes_[0]);
-}
-
-TEST_F(LoadStateChangeCoalescerTest, ThreeChangesCoalesce) {
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_PROXY_FOR_URL);
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- coalescer_->LoadStateChanged(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT);
- WaitUntilIdle();
- ASSERT_EQ(1u, load_state_changes_.size());
- EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT, load_state_changes_[0]);
-}
-
-TEST_F(LoadStateChangeCoalescerTest, CoalesceToOriginalLoadState) {
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_PROXY_FOR_URL);
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- coalescer_->LoadStateChanged(LOAD_STATE_IDLE);
- WaitUntilIdle();
- EXPECT_TRUE(load_state_changes_.empty());
-}
-
-TEST_F(LoadStateChangeCoalescerTest, AlternateLoadStatesWithWait) {
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_PROXY_FOR_URL);
- WaitUntilIdle();
- ASSERT_EQ(1u, load_state_changes_.size());
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, load_state_changes_[0]);
-
- coalescer_->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- coalescer_->LoadStateChanged(LOAD_STATE_IDLE);
- WaitUntilIdle();
- ASSERT_EQ(2u, load_state_changes_.size());
- EXPECT_EQ(LOAD_STATE_IDLE, load_state_changes_[1]);
-}
-
-} // namespace net
diff --git a/net/proxy/mojo_proxy_resolver_factory_impl.cc b/net/proxy/mojo_proxy_resolver_factory_impl.cc
index 4a95aa7..834151e 100644
--- a/net/proxy/mojo_proxy_resolver_factory_impl.cc
+++ b/net/proxy/mojo_proxy_resolver_factory_impl.cc
@@ -13,7 +13,7 @@
#include "net/proxy/proxy_resolver_error_observer_mojo.h"
#include "net/proxy/proxy_resolver_factory.h"
#include "net/proxy/proxy_resolver_v8.h"
-#include "net/proxy/proxy_resolver_v8_tracing.h"
+#include "net/proxy/proxy_resolver_v8_tracing_wrapper.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
namespace net {
@@ -26,38 +26,12 @@ scoped_ptr<ProxyResolverErrorObserver> ReturnErrorObserver(
scoped_ptr<ProxyResolverFactory> CreateDefaultProxyResolver(
HostResolver* host_resolver,
- scoped_ptr<ProxyResolverErrorObserver> error_observer,
- const ProxyResolver::LoadStateChangedCallback& callback) {
- return make_scoped_ptr(new ProxyResolverFactoryV8Tracing(
- host_resolver, nullptr, callback,
+ scoped_ptr<ProxyResolverErrorObserver> error_observer) {
+ return make_scoped_ptr(new ProxyResolverFactoryV8TracingWrapper(
+ host_resolver, nullptr,
base::Bind(&ReturnErrorObserver, base::Passed(&error_observer))));
}
-class LoadStateChangeForwarder
- : public base::RefCounted<LoadStateChangeForwarder> {
- public:
- LoadStateChangeForwarder() = default;
-
- void OnLoadStateChanged(ProxyResolver::RequestHandle request_handle,
- LoadState load_state) const {
- if (!callback_.is_null())
- callback_.Run(request_handle, load_state);
- }
-
- void set_load_state_changed_callback(
- const ProxyResolver::LoadStateChangedCallback& callback) {
- callback_ = callback;
- }
-
- private:
- friend class base::RefCounted<LoadStateChangeForwarder>;
- ~LoadStateChangeForwarder() = default;
-
- ProxyResolver::LoadStateChangedCallback callback_;
-
- DISALLOW_COPY_AND_ASSIGN(LoadStateChangeForwarder);
-};
-
// A class to manage the lifetime of a MojoProxyResolverImpl and a
// HostResolverMojo. An instance will remain while the message pipes for both
// mojo connections remain open.
@@ -66,8 +40,6 @@ class MojoProxyResolverHolder : public mojo::ErrorHandler {
MojoProxyResolverHolder(
scoped_ptr<HostResolverMojo> host_resolver,
scoped_ptr<ProxyResolver> proxy_resolver_impl,
- const scoped_refptr<LoadStateChangeForwarder>&
- load_state_change_forwarder,
mojo::InterfaceRequest<interfaces::ProxyResolver> request);
private:
@@ -84,13 +56,9 @@ class MojoProxyResolverHolder : public mojo::ErrorHandler {
MojoProxyResolverHolder::MojoProxyResolverHolder(
scoped_ptr<HostResolverMojo> host_resolver,
scoped_ptr<ProxyResolver> proxy_resolver_impl,
- const scoped_refptr<LoadStateChangeForwarder>& load_state_change_forwarder,
mojo::InterfaceRequest<interfaces::ProxyResolver> request)
: host_resolver_(host_resolver.Pass()),
- mojo_proxy_resolver_(
- proxy_resolver_impl.Pass(),
- base::Bind(&LoadStateChangeForwarder::set_load_state_changed_callback,
- load_state_change_forwarder)),
+ mojo_proxy_resolver_(proxy_resolver_impl.Pass()),
binding_(&mojo_proxy_resolver_, request.Pass()) {
binding_.set_error_handler(this);
host_resolver_->set_disconnect_callback(base::Bind(
@@ -122,7 +90,6 @@ class MojoProxyResolverFactoryImpl::Job : public mojo::ErrorHandler {
MojoProxyResolverFactoryImpl* const parent_;
scoped_ptr<HostResolverMojo> host_resolver_;
- scoped_refptr<LoadStateChangeForwarder> load_state_change_forwarder_;
scoped_ptr<ProxyResolver> proxy_resolver_impl_;
mojo::InterfaceRequest<interfaces::ProxyResolver> proxy_request_;
scoped_ptr<net::ProxyResolverFactory> factory_;
@@ -145,13 +112,10 @@ MojoProxyResolverFactoryImpl::Job::Job(
host_resolver.Pass(),
base::Bind(&MojoProxyResolverFactoryImpl::Job::OnConnectionError,
base::Unretained(this)))),
- load_state_change_forwarder_(new LoadStateChangeForwarder),
proxy_request_(request.Pass()),
factory_(proxy_resolver_factory.Run(
host_resolver_.get(),
- ProxyResolverErrorObserverMojo::Create(error_observer.Pass()),
- base::Bind(&LoadStateChangeForwarder::OnLoadStateChanged,
- load_state_change_forwarder_))),
+ ProxyResolverErrorObserverMojo::Create(error_observer.Pass()))),
client_ptr_(client.Pass()) {
client_ptr_.set_error_handler(this);
factory_->CreateProxyResolver(
@@ -172,9 +136,9 @@ void MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated(int error) {
if (error == OK) {
// The MojoProxyResolverHolder will delete itself if either
// |host_resolver_| or |proxy_request_| encounters a connection error.
- new MojoProxyResolverHolder(
- host_resolver_.Pass(), proxy_resolver_impl_.Pass(),
- load_state_change_forwarder_, proxy_request_.Pass());
+ new MojoProxyResolverHolder(host_resolver_.Pass(),
+ proxy_resolver_impl_.Pass(),
+ proxy_request_.Pass());
}
client_ptr_->ReportResult(error);
parent_->RemoveJob(this);
diff --git a/net/proxy/mojo_proxy_resolver_factory_impl.h b/net/proxy/mojo_proxy_resolver_factory_impl.h
index bf652b7..f447759 100644
--- a/net/proxy/mojo_proxy_resolver_factory_impl.h
+++ b/net/proxy/mojo_proxy_resolver_factory_impl.h
@@ -21,8 +21,7 @@ class MojoProxyResolverFactoryImpl : public interfaces::ProxyResolverFactory {
public:
using Factory = base::Callback<scoped_ptr<net::ProxyResolverFactory>(
HostResolver*,
- scoped_ptr<ProxyResolverErrorObserver>,
- const ProxyResolver::LoadStateChangedCallback&)>;
+ scoped_ptr<ProxyResolverErrorObserver>)>;
explicit MojoProxyResolverFactoryImpl(
mojo::InterfaceRequest<interfaces::ProxyResolverFactory> request);
diff --git a/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc b/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc
index fc1c94b..a0d9180 100644
--- a/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc
+++ b/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc
@@ -76,10 +76,8 @@ class MojoProxyResolverFactoryImplTest
scoped_ptr<ProxyResolverFactory> CreateFakeProxyResolverFactory(
HostResolver* host_resolver,
- scoped_ptr<ProxyResolverErrorObserver> error_observer,
- const ProxyResolver::LoadStateChangedCallback& callback) {
+ scoped_ptr<ProxyResolverErrorObserver> error_observer) {
EXPECT_TRUE(host_resolver);
- EXPECT_FALSE(callback.is_null());
DCHECK(mock_factory_owner_);
return mock_factory_owner_.Pass();
}
diff --git a/net/proxy/mojo_proxy_resolver_impl.cc b/net/proxy/mojo_proxy_resolver_impl.cc
index c300b6e..b270438 100644
--- a/net/proxy/mojo_proxy_resolver_impl.cc
+++ b/net/proxy/mojo_proxy_resolver_impl.cc
@@ -8,15 +8,11 @@
#include "mojo/common/url_type_converters.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
-#include "net/proxy/load_state_change_coalescer.h"
#include "net/proxy/mojo_proxy_type_converters.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_resolver_script_data.h"
namespace net {
-namespace {
-const int kLoadStateChangeCoalesceTimeoutMilliseconds = 10;
-}
class MojoProxyResolverImpl::Job : public mojo::ErrorHandler {
public:
@@ -27,9 +23,6 @@ class MojoProxyResolverImpl::Job : public mojo::ErrorHandler {
void Start();
- // Invoked when the LoadState for this job changes.
- void LoadStateChanged(LoadState load_state);
-
net::ProxyResolver::RequestHandle request_handle() { return request_handle_; }
private:
@@ -40,8 +33,6 @@ class MojoProxyResolverImpl::Job : public mojo::ErrorHandler {
void GetProxyDone(int error);
- void SendLoadStateChanged(LoadState load_state);
-
MojoProxyResolverImpl* resolver_;
interfaces::ProxyResolverRequestClientPtr client_;
@@ -49,33 +40,19 @@ class MojoProxyResolverImpl::Job : public mojo::ErrorHandler {
GURL url_;
net::ProxyResolver::RequestHandle request_handle_;
bool done_;
- LoadStateChangeCoalescer load_state_change_coalescer_;
DISALLOW_COPY_AND_ASSIGN(Job);
};
MojoProxyResolverImpl::MojoProxyResolverImpl(
- scoped_ptr<net::ProxyResolver> resolver,
- const base::Callback<
- void(const net::ProxyResolver::LoadStateChangedCallback&)>&
- load_state_change_callback_setter)
+ scoped_ptr<net::ProxyResolver> resolver)
: resolver_(resolver.Pass()) {
- load_state_change_callback_setter.Run(base::Bind(
- &MojoProxyResolverImpl::LoadStateChanged, base::Unretained(this)));
}
MojoProxyResolverImpl::~MojoProxyResolverImpl() {
STLDeleteElements(&resolve_jobs_);
}
-void MojoProxyResolverImpl::LoadStateChanged(
- net::ProxyResolver::RequestHandle handle,
- LoadState load_state) {
- auto it = request_handle_to_job_.find(handle);
- DCHECK(it != request_handle_to_job_.end());
- it->second->LoadStateChanged(load_state);
-}
-
void MojoProxyResolverImpl::GetProxyForUrl(
const mojo::String& url,
interfaces::ProxyResolverRequestClientPtr client) {
@@ -103,13 +80,7 @@ MojoProxyResolverImpl::Job::Job(
client_(client.Pass()),
url_(url),
request_handle_(nullptr),
- done_(false),
- load_state_change_coalescer_(
- base::Bind(&MojoProxyResolverImpl::Job::SendLoadStateChanged,
- base::Unretained(this)),
- base::TimeDelta::FromMilliseconds(
- kLoadStateChangeCoalesceTimeoutMilliseconds),
- LOAD_STATE_RESOLVING_PROXY_FOR_URL) {
+ done_(false) {
}
MojoProxyResolverImpl::Job::~Job() {
@@ -130,10 +101,6 @@ void MojoProxyResolverImpl::Job::Start() {
std::make_pair(request_handle_, this));
}
-void MojoProxyResolverImpl::Job::LoadStateChanged(LoadState load_state) {
- load_state_change_coalescer_.LoadStateChanged(load_state);
-}
-
void MojoProxyResolverImpl::Job::GetProxyDone(int error) {
done_ = true;
DVLOG(1) << "GetProxyForUrl(" << url_ << ") finished with error " << error
@@ -154,8 +121,4 @@ void MojoProxyResolverImpl::Job::OnConnectionError() {
resolver_->DeleteJob(this);
}
-void MojoProxyResolverImpl::Job::SendLoadStateChanged(LoadState load_state) {
- client_->LoadStateChanged(load_state);
-}
-
} // namespace net
diff --git a/net/proxy/mojo_proxy_resolver_impl.h b/net/proxy/mojo_proxy_resolver_impl.h
index a99c6a4..2d801c8 100644
--- a/net/proxy/mojo_proxy_resolver_impl.h
+++ b/net/proxy/mojo_proxy_resolver_impl.h
@@ -18,11 +18,7 @@ namespace net {
class MojoProxyResolverImpl : public interfaces::ProxyResolver {
public:
- MojoProxyResolverImpl(
- scoped_ptr<net::ProxyResolver> resolver,
- const base::Callback<
- void(const net::ProxyResolver::LoadStateChangedCallback&)>&
- load_state_change_callback_setter);
+ explicit MojoProxyResolverImpl(scoped_ptr<net::ProxyResolver> resolver);
~MojoProxyResolverImpl() override;
@@ -36,10 +32,6 @@ class MojoProxyResolverImpl : public interfaces::ProxyResolver {
void DeleteJob(Job* job);
- // Invoked when the LoadState of a request changes.
- void LoadStateChanged(net::ProxyResolver::RequestHandle handle,
- LoadState load_state);
-
scoped_ptr<net::ProxyResolver> resolver_;
std::set<Job*> resolve_jobs_;
std::map<net::ProxyResolver::RequestHandle, Job*> request_handle_to_job_;
diff --git a/net/proxy/mojo_proxy_resolver_impl_unittest.cc b/net/proxy/mojo_proxy_resolver_impl_unittest.cc
index b9fa785..bdccf6c 100644
--- a/net/proxy/mojo_proxy_resolver_impl_unittest.cc
+++ b/net/proxy/mojo_proxy_resolver_impl_unittest.cc
@@ -26,7 +26,6 @@ class TestRequestClient : public interfaces::ProxyResolverRequestClient,
public:
enum Event {
RESULT_RECEIVED,
- LOAD_STATE_CHANGED,
CONNECTION_ERROR,
};
@@ -37,21 +36,18 @@ class TestRequestClient : public interfaces::ProxyResolverRequestClient,
Error error() { return error_; }
const mojo::Array<interfaces::ProxyServerPtr>& results() { return results_; }
- LoadState load_state() { return load_state_; }
EventWaiter<Event>& event_waiter() { return event_waiter_; }
private:
// interfaces::ProxyResolverRequestClient override.
void ReportResult(int32_t error,
mojo::Array<interfaces::ProxyServerPtr> results) override;
- void LoadStateChanged(int32_t load_state) override;
// mojo::ErrorHandler override.
void OnConnectionError() override;
bool done_ = false;
Error error_ = ERR_FAILED;
- LoadState load_state_ = LOAD_STATE_IDLE;
mojo::Array<interfaces::ProxyServerPtr> results_;
mojo::Binding<interfaces::ProxyResolverRequestClient> binding_;
@@ -83,11 +79,6 @@ void TestRequestClient::ReportResult(
done_ = true;
}
-void TestRequestClient::LoadStateChanged(int32_t load_state) {
- event_waiter_.NotifyEvent(LOAD_STATE_CHANGED);
- load_state_ = static_cast<LoadState>(load_state);
-}
-
void TestRequestClient::OnConnectionError() {
event_waiter_.NotifyEvent(CONNECTION_ERROR);
}
@@ -164,25 +155,14 @@ class MojoProxyResolverImplTest : public testing::Test {
scoped_ptr<CallbackMockProxyResolver> mock_resolver(
new CallbackMockProxyResolver);
mock_proxy_resolver_ = mock_resolver.get();
- resolver_impl_.reset(new MojoProxyResolverImpl(
- mock_resolver.Pass(),
- base::Bind(&MojoProxyResolverImplTest::set_load_state_changed_callback,
- base::Unretained(this))));
+ resolver_impl_.reset(new MojoProxyResolverImpl(mock_resolver.Pass()));
resolver_ = resolver_impl_.get();
}
- void set_load_state_changed_callback(
- const ProxyResolver::LoadStateChangedCallback& callback) {
- EXPECT_TRUE(load_state_changed_callback_.is_null());
- EXPECT_FALSE(callback.is_null());
- load_state_changed_callback_ = callback;
- }
-
CallbackMockProxyResolver* mock_proxy_resolver_;
scoped_ptr<MojoProxyResolverImpl> resolver_impl_;
interfaces::ProxyResolver* resolver_;
- ProxyResolver::LoadStateChangedCallback load_state_changed_callback_;
};
TEST_F(MojoProxyResolverImplTest, GetProxyForUrl) {
@@ -195,12 +175,6 @@ TEST_F(MojoProxyResolverImplTest, GetProxyForUrl) {
mock_proxy_resolver_->pending_requests()[0];
EXPECT_EQ(GURL("http://example.com"), request->url());
- ASSERT_FALSE(load_state_changed_callback_.is_null());
- load_state_changed_callback_.Run(request.get(),
- LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- client.event_waiter().WaitForEvent(TestRequestClient::LOAD_STATE_CHANGED);
- EXPECT_EQ(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT, client.load_state());
-
request->results()->UsePacString(
"PROXY proxy.example.com:1; "
"SOCKS4 socks4.example.com:2; "
diff --git a/net/proxy/proxy_resolver.h b/net/proxy/proxy_resolver.h
index 11df64f..b303e2b 100644
--- a/net/proxy/proxy_resolver.h
+++ b/net/proxy/proxy_resolver.h
@@ -29,9 +29,6 @@ class NET_EXPORT_PRIVATE ProxyResolver {
// Opaque pointer type, to return a handle to cancel outstanding requests.
typedef void* RequestHandle;
- using LoadStateChangedCallback =
- base::Callback<void(RequestHandle, LoadState)>;
-
ProxyResolver() {}
virtual ~ProxyResolver() {}
diff --git a/net/proxy/proxy_resolver_factory_mojo.cc b/net/proxy/proxy_resolver_factory_mojo.cc
index efb1514..0e5b46b 100644
--- a/net/proxy/proxy_resolver_factory_mojo.cc
+++ b/net/proxy/proxy_resolver_factory_mojo.cc
@@ -132,7 +132,7 @@ class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient,
void Cancel();
// Returns the LoadState of this job.
- LoadState load_state() { return load_state_; }
+ LoadState load_state() { return LOAD_STATE_RESOLVING_PROXY_FOR_URL; }
private:
// Overridden from mojo::ErrorHandler:
@@ -142,13 +142,11 @@ class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient,
void ReportResult(
int32_t error,
mojo::Array<interfaces::ProxyServerPtr> proxy_servers) override;
- void LoadStateChanged(int32_t load_state) override;
ProxyResolverMojo* resolver_;
const GURL url_;
ProxyInfo* results_;
CompletionCallback callback_;
- LoadState load_state_ = LOAD_STATE_RESOLVING_PROXY_FOR_URL;
base::ThreadChecker thread_checker_;
mojo::Binding<interfaces::ProxyResolverRequestClient> binding_;
@@ -206,10 +204,6 @@ void ProxyResolverMojo::Job::ReportResult(
callback.Run(error);
}
-void ProxyResolverMojo::Job::LoadStateChanged(int32_t load_state) {
- load_state_ = static_cast<LoadState>(load_state);
-}
-
ProxyResolverMojo::ProxyResolverMojo(
interfaces::ProxyResolverPtr resolver_ptr,
scoped_ptr<interfaces::HostResolver> host_resolver,
diff --git a/net/proxy/proxy_resolver_factory_mojo_unittest.cc b/net/proxy/proxy_resolver_factory_mojo_unittest.cc
index 16d670b..20214de 100644
--- a/net/proxy/proxy_resolver_factory_mojo_unittest.cc
+++ b/net/proxy/proxy_resolver_factory_mojo_unittest.cc
@@ -101,8 +101,6 @@ struct GetProxyForUrlAction {
DISCONNECT,
// Wait for the client pipe to be disconnected.
WAIT_FOR_CLIENT_DISCONNECT,
- // Send a LoadStateChanged message and keep the client pipe open.
- SEND_LOAD_STATE_AND_BLOCK,
};
GetProxyForUrlAction() {}
@@ -150,13 +148,6 @@ struct GetProxyForUrlAction {
return result;
}
- static GetProxyForUrlAction SendLoadStateChanged(const GURL& url) {
- GetProxyForUrlAction result;
- result.expected_url = url;
- result.action = SEND_LOAD_STATE_AND_BLOCK;
- return result;
- }
-
Action action = COMPLETE;
Error error = OK;
mojo::Array<interfaces::ProxyServerPtr> proxy_servers;
@@ -250,11 +241,6 @@ void MockMojoProxyResolver::GetProxyForUrl(
case GetProxyForUrlAction::WAIT_FOR_CLIENT_DISCONNECT:
ASSERT_FALSE(client.WaitForIncomingResponse());
break;
- case GetProxyForUrlAction::SEND_LOAD_STATE_AND_BLOCK:
- client->LoadStateChanged(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- blocked_clients_.push_back(
- new interfaces::ProxyResolverRequestClientPtr(client.Pass()));
- break;
}
WakeWaiter();
}
@@ -269,7 +255,6 @@ class Request {
int error() const { return error_; }
const ProxyInfo& results() const { return results_; }
- LoadState load_state() { return resolver_->GetLoadState(handle_); }
private:
ProxyResolver* resolver_;
@@ -628,21 +613,6 @@ TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL) {
EXPECT_EQ("DIRECT", request->results().ToPacString());
}
-TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_LoadState) {
- mock_proxy_resolver_.AddGetProxyAction(
- GetProxyForUrlAction::SendLoadStateChanged(GURL(kExampleUrl)));
- CreateProxyResolver();
-
- scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
- EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request->load_state());
- while (request->load_state() == LOAD_STATE_RESOLVING_PROXY_FOR_URL)
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT, request->load_state());
- mock_proxy_resolver_.ClearBlockedClients();
- EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED, request->WaitForResult());
-}
-
TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_MultipleResults) {
static const char kPacString[] =
"PROXY foo1:80;DIRECT;SOCKS foo2:1234;"
diff --git a/net/proxy/proxy_resolver_v8_tracing.cc b/net/proxy/proxy_resolver_v8_tracing.cc
index 2f528e6..01e1ef5 100644
--- a/net/proxy/proxy_resolver_v8_tracing.cc
+++ b/net/proxy/proxy_resolver_v8_tracing.cc
@@ -16,11 +16,9 @@
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
-#include "base/values.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/dns/host_resolver.h"
-#include "net/log/net_log.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_resolver_error_observer.h"
#include "net/proxy/proxy_resolver_v8.h"
@@ -58,17 +56,6 @@ const size_t kMaxUniqueResolveDnsPerExec = 20;
// hit this. (In fact normal scripts should not even have alerts() or errors).
const size_t kMaxAlertsAndErrorsBytes = 2048;
-// Returns event parameters for a PAC error message (line number + message).
-scoped_ptr<base::Value> NetLogErrorCallback(
- int line_number,
- const base::string16* message,
- NetLogCaptureMode /* capture_mode */) {
- scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetInteger("line_number", line_number);
- dict->SetString("message", *message);
- return dict.Pass();
-}
-
// The Job class is responsible for executing GetProxyForURL() and
// creating ProxyResolverV8 instances, since both of these operations share
// similar code.
@@ -81,8 +68,8 @@ scoped_ptr<base::Value> NetLogErrorCallback(
// thread. Most methods are expected to be used exclusively on one thread
// or the other.
//
-// The lifetime of Jobs does not exceed that of the ProxyResolverV8Tracing that
-// spawned it. Destruction might happen on either the origin thread or the
+// The lifetime of Jobs does not exceed that of the ProxyResolverV8TracingImpl
+// that spawned it. Destruction might happen on either the origin thread or the
// worker thread.
class Job : public base::RefCountedThreadSafe<Job>,
public ProxyResolverV8::JSBindings {
@@ -90,30 +77,19 @@ class Job : public base::RefCountedThreadSafe<Job>,
struct Params {
Params(
const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
- HostResolver* host_resolver,
- ProxyResolverErrorObserver* error_observer,
- NetLog* net_log,
- ProxyResolver::LoadStateChangedCallback on_load_state_changed,
int* num_outstanding_callbacks)
: v8_resolver(nullptr),
worker_task_runner(worker_task_runner),
- host_resolver(host_resolver),
- error_observer(error_observer),
- net_log(net_log),
- on_load_state_changed(on_load_state_changed),
num_outstanding_callbacks(num_outstanding_callbacks) {}
ProxyResolverV8* v8_resolver;
scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner;
- HostResolver* host_resolver;
- ProxyResolverErrorObserver* error_observer;
- NetLog* net_log;
- ProxyResolver::LoadStateChangedCallback on_load_state_changed;
int* num_outstanding_callbacks;
};
// |params| is non-owned. It contains the parameters for this Job, and must
// outlive it.
- explicit Job(const Params* params);
+ Job(const Params* params,
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings);
// Called from origin thread.
void StartCreateV8Resolver(
@@ -124,7 +100,6 @@ class Job : public base::RefCountedThreadSafe<Job>,
// Called from origin thread.
void StartGetProxyForURL(const GURL& url,
ProxyInfo* results,
- const BoundNetLog& net_log,
const CompletionCallback& callback);
// Called from origin thread.
@@ -159,8 +134,6 @@ class Job : public base::RefCountedThreadSafe<Job>,
ProxyResolverV8* v8_resolver();
const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner();
HostResolver* host_resolver();
- ProxyResolverErrorObserver* error_observer();
- NetLog* net_log();
// Invokes the user's callback.
void NotifyCaller(int result);
@@ -223,11 +196,7 @@ class Job : public base::RefCountedThreadSafe<Job>,
void DispatchAlertOrError(bool is_alert, int line_number,
const base::string16& message);
- void LogEventToCurrentRequestAndGlobally(
- NetLog::EventType type,
- const NetLog::ParametersCallback& parameters_callback);
-
- // The thread which called into ProxyResolverV8Tracing, and on which the
+ // The thread which called into ProxyResolverV8TracingImpl, and on which the
// completion callback is expected to run.
scoped_refptr<base::SingleThreadTaskRunner> origin_runner_;
@@ -235,6 +204,8 @@ class Job : public base::RefCountedThreadSafe<Job>,
// Initialized on origin thread and then accessed from both threads.
const Params* const params_;
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings_;
+
// The callback to run (on the origin thread) when the Job finishes.
// Should only be accessed from origin thread.
CompletionCallback callback_;
@@ -277,7 +248,6 @@ class Job : public base::RefCountedThreadSafe<Job>,
ProxyInfo* user_results_; // Owned by caller, lives on origin thread.
GURL url_;
ProxyInfo results_;
- BoundNetLog bound_net_log_;
// ---------------------------------------------------------------------------
// State for ExecuteNonBlocking()
@@ -324,53 +294,42 @@ class Job : public base::RefCountedThreadSafe<Job>,
AddressList pending_dns_addresses_;
};
-class ProxyResolverV8Tracing : public ProxyResolver,
- public base::NonThreadSafe {
+class ProxyResolverV8TracingImpl : public ProxyResolverV8Tracing,
+ public base::NonThreadSafe {
public:
- // Constructs a ProxyResolver that will issue DNS requests through
- // |job_params->host_resolver|, forward Javascript errors through
- // |error_observer|, and log Javascript errors and alerts to
- // |job_params->net_log|. When the LoadState for a request changes,
- // |job_params->on_load_state_changed| will be invoked with the RequestHandle
- // for that request with the new LoadState.
- //
- // Note that the constructor takes ownership of |error_observer|, whereas
- // |job_params->host_resolver| and |job_params->net_log| are expected to
- // outlive |this|.
- ProxyResolverV8Tracing(scoped_ptr<ProxyResolverErrorObserver> error_observer,
- scoped_ptr<base::Thread> thread,
- scoped_ptr<ProxyResolverV8> resolver,
- scoped_ptr<Job::Params> job_params);
-
- ~ProxyResolverV8Tracing() override;
-
- // ProxyResolver implementation:
- int GetProxyForURL(const GURL& url,
- ProxyInfo* results,
- const CompletionCallback& callback,
- RequestHandle* request,
- const BoundNetLog& net_log) override;
- void CancelRequest(RequestHandle request) override;
- LoadState GetLoadState(RequestHandle request) const override;
+ ProxyResolverV8TracingImpl(scoped_ptr<base::Thread> thread,
+ scoped_ptr<ProxyResolverV8> resolver,
+ scoped_ptr<Job::Params> job_params);
+
+ ~ProxyResolverV8TracingImpl() override;
+
+ // ProxyResolverV8Tracing overrides.
+ void GetProxyForURL(const GURL& url,
+ ProxyInfo* results,
+ const CompletionCallback& callback,
+ ProxyResolver::RequestHandle* request,
+ scoped_ptr<Bindings> bindings) override;
+ void CancelRequest(ProxyResolver::RequestHandle request) override;
+ LoadState GetLoadState(ProxyResolver::RequestHandle request) const override;
private:
// The worker thread on which the ProxyResolverV8 will be run.
scoped_ptr<base::Thread> thread_;
scoped_ptr<ProxyResolverV8> v8_resolver_;
- scoped_ptr<ProxyResolverErrorObserver> error_observer_;
-
scoped_ptr<Job::Params> job_params_;
// The number of outstanding (non-cancelled) jobs.
int num_outstanding_callbacks_;
- DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8Tracing);
+ DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8TracingImpl);
};
-Job::Job(const Job::Params* params)
+Job::Job(const Job::Params* params,
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings)
: origin_runner_(base::ThreadTaskRunnerHandle::Get()),
params_(params),
+ bindings_(bindings.Pass()),
event_(true, false),
last_num_dns_(0),
pending_dns_(NULL) {
@@ -395,13 +354,11 @@ void Job::StartCreateV8Resolver(
void Job::StartGetProxyForURL(const GURL& url,
ProxyInfo* results,
- const BoundNetLog& net_log,
const CompletionCallback& callback) {
CheckIsOnOriginThread();
url_ = url;
user_results_ = results;
- bound_net_log_ = net_log;
Start(GET_PROXY_FOR_URL, false /*non-blocking*/, callback);
}
@@ -490,15 +447,7 @@ const scoped_refptr<base::SingleThreadTaskRunner>& Job::worker_task_runner() {
}
HostResolver* Job::host_resolver() {
- return params_->host_resolver;
-}
-
-ProxyResolverErrorObserver* Job::error_observer() {
- return params_->error_observer;
-}
-
-NetLog* Job::net_log() {
- return params_->net_log;
+ return bindings_->GetHostResolver();
}
void Job::NotifyCaller(int result) {
@@ -746,12 +695,9 @@ void Job::DoDnsOperation() {
HostResolver::RequestHandle dns_request = NULL;
int result = host_resolver()->Resolve(
- MakeDnsRequestInfo(pending_dns_host_, pending_dns_op_),
- DEFAULT_PRIORITY,
- &pending_dns_addresses_,
- base::Bind(&Job::OnDnsOperationComplete, this),
- &dns_request,
- bound_net_log_);
+ MakeDnsRequestInfo(pending_dns_host_, pending_dns_op_), DEFAULT_PRIORITY,
+ &pending_dns_addresses_, base::Bind(&Job::OnDnsOperationComplete, this),
+ &dns_request, bindings_->GetBoundNetLog());
pending_dns_completed_synchronously_ = result != ERR_IO_PENDING;
@@ -769,10 +715,6 @@ void Job::DoDnsOperation() {
} else {
DCHECK(dns_request);
pending_dns_ = dns_request;
- if (!params_->on_load_state_changed.is_null()) {
- params_->on_load_state_changed.Run(
- this, LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT);
- }
// OnDnsOperationComplete() will be called by host resolver on completion.
}
@@ -793,12 +735,6 @@ void Job::OnDnsOperationComplete(int result) {
pending_dns_addresses_);
pending_dns_ = NULL;
- if (!params_->on_load_state_changed.is_null() &&
- !pending_dns_completed_synchronously_ && !cancelled_.IsSet()) {
- params_->on_load_state_changed.Run(this,
- LOAD_STATE_RESOLVING_PROXY_FOR_URL);
- }
-
if (blocking_dns_) {
event_.Signal();
return;
@@ -949,8 +885,8 @@ void Job::DispatchAlertOrError(bool is_alert,
// alerts/errors. The request might get cancelled shortly after this
// check! (There is no lock being held to guarantee otherwise).
//
- // If this happens, then some information will get written to the NetLog
- // needlessly, however the NetLog will still be alive so it shouldn't cause
+ // If this happens, then some information will be logged needlessly, however
+ // the Bindings are responsible for handling this case so it shouldn't cause
// problems.
if (cancelled_.IsSet())
return;
@@ -961,10 +897,7 @@ void Job::DispatchAlertOrError(bool is_alert,
// -------------------
VLOG(1) << "PAC-alert: " << message;
- // Send to the NetLog.
- LogEventToCurrentRequestAndGlobally(
- NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::StringCallback("message", &message));
+ bindings_->Alert(message);
} else {
// -------------------
// error
@@ -974,41 +907,22 @@ void Job::DispatchAlertOrError(bool is_alert,
else
VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message;
- // Send the error to the NetLog.
- LogEventToCurrentRequestAndGlobally(
- NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
- base::Bind(&NetLogErrorCallback, line_number, &message));
-
- if (error_observer())
- error_observer()->OnPACScriptError(line_number, message);
+ bindings_->OnError(line_number, message);
}
}
-void Job::LogEventToCurrentRequestAndGlobally(
- NetLog::EventType type,
- const NetLog::ParametersCallback& parameters_callback) {
- CheckIsOnWorkerThread();
- bound_net_log_.AddEvent(type, parameters_callback);
-
- // Emit to the global NetLog event stream.
- if (net_log())
- net_log()->AddGlobalEntry(type, parameters_callback);
-}
-
-ProxyResolverV8Tracing::ProxyResolverV8Tracing(
- scoped_ptr<ProxyResolverErrorObserver> error_observer,
+ProxyResolverV8TracingImpl::ProxyResolverV8TracingImpl(
scoped_ptr<base::Thread> thread,
scoped_ptr<ProxyResolverV8> resolver,
scoped_ptr<Job::Params> job_params)
: thread_(thread.Pass()),
v8_resolver_(resolver.Pass()),
- error_observer_(error_observer.Pass()),
job_params_(job_params.Pass()),
num_outstanding_callbacks_(0) {
job_params_->num_outstanding_callbacks = &num_outstanding_callbacks_;
}
-ProxyResolverV8Tracing::~ProxyResolverV8Tracing() {
+ProxyResolverV8TracingImpl::~ProxyResolverV8TracingImpl() {
// Note, all requests should have been cancelled.
CHECK_EQ(0, num_outstanding_callbacks_);
@@ -1017,50 +931,67 @@ ProxyResolverV8Tracing::~ProxyResolverV8Tracing() {
thread_.reset();
}
-int ProxyResolverV8Tracing::GetProxyForURL(const GURL& url,
- ProxyInfo* results,
- const CompletionCallback& callback,
- RequestHandle* request,
- const BoundNetLog& net_log) {
+void ProxyResolverV8TracingImpl::GetProxyForURL(
+ const GURL& url,
+ ProxyInfo* results,
+ const CompletionCallback& callback,
+ ProxyResolver::RequestHandle* request,
+ scoped_ptr<Bindings> bindings) {
DCHECK(CalledOnValidThread());
DCHECK(!callback.is_null());
- scoped_refptr<Job> job = new Job(job_params_.get());
+ scoped_refptr<Job> job = new Job(job_params_.get(), bindings.Pass());
if (request)
*request = job.get();
- job->StartGetProxyForURL(url, results, net_log, callback);
- return ERR_IO_PENDING;
+ job->StartGetProxyForURL(url, results, callback);
}
-void ProxyResolverV8Tracing::CancelRequest(RequestHandle request) {
+void ProxyResolverV8TracingImpl::CancelRequest(
+ ProxyResolver::RequestHandle request) {
Job* job = reinterpret_cast<Job*>(request);
job->Cancel();
}
-LoadState ProxyResolverV8Tracing::GetLoadState(RequestHandle request) const {
+LoadState ProxyResolverV8TracingImpl::GetLoadState(
+ ProxyResolver::RequestHandle request) const {
Job* job = reinterpret_cast<Job*>(request);
return job->GetLoadState();
}
-} // namespace
+class ProxyResolverV8TracingFactoryImpl : public ProxyResolverV8TracingFactory {
+ public:
+ ProxyResolverV8TracingFactoryImpl();
+ ~ProxyResolverV8TracingFactoryImpl() override;
+
+ void CreateProxyResolverV8Tracing(
+ const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings,
+ scoped_ptr<ProxyResolverV8Tracing>* resolver,
+ const CompletionCallback& callback,
+ scoped_ptr<ProxyResolverFactory::Request>* request) override;
+
+ private:
+ class CreateJob;
+
+ void RemoveJob(CreateJob* job);
-class ProxyResolverFactoryV8Tracing::CreateJob
+ std::set<CreateJob*> jobs_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8TracingFactoryImpl);
+};
+
+class ProxyResolverV8TracingFactoryImpl::CreateJob
: public ProxyResolverFactory::Request {
public:
- CreateJob(ProxyResolverFactoryV8Tracing* factory,
- HostResolver* host_resolver,
- scoped_ptr<ProxyResolverErrorObserver> error_observer,
- NetLog* net_log,
- const ProxyResolver::LoadStateChangedCallback&
- load_state_changed_callback,
+ CreateJob(ProxyResolverV8TracingFactoryImpl* factory,
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings,
const scoped_refptr<ProxyResolverScriptData>& pac_script,
- scoped_ptr<ProxyResolver>* resolver_out,
+ scoped_ptr<ProxyResolverV8Tracing>* resolver_out,
const CompletionCallback& callback)
: factory_(factory),
thread_(new base::Thread("Proxy Resolver")),
- error_observer_(error_observer.Pass()),
resolver_out_(resolver_out),
callback_(callback),
num_outstanding_callbacks_(0) {
@@ -1068,14 +999,13 @@ class ProxyResolverFactoryV8Tracing::CreateJob
base::Thread::Options options;
options.timer_slack = base::TIMER_SLACK_MAXIMUM;
CHECK(thread_->StartWithOptions(options));
- job_params_.reset(new Job::Params(
- thread_->task_runner(), host_resolver, error_observer_.get(), net_log,
- load_state_changed_callback, &num_outstanding_callbacks_));
- create_resolver_job_ = new Job(job_params_.get());
+ job_params_.reset(
+ new Job::Params(thread_->task_runner(), &num_outstanding_callbacks_));
+ create_resolver_job_ = new Job(job_params_.get(), bindings.Pass());
create_resolver_job_->StartCreateV8Resolver(
pac_script, &v8_resolver_,
base::Bind(
- &ProxyResolverFactoryV8Tracing::CreateJob::OnV8ResolverCreated,
+ &ProxyResolverV8TracingFactoryImpl::CreateJob::OnV8ResolverCreated,
base::Unretained(this)));
}
@@ -1101,9 +1031,8 @@ class ProxyResolverFactoryV8Tracing::CreateJob
DCHECK(factory_);
if (error == OK) {
job_params_->v8_resolver = v8_resolver_.get();
- resolver_out_->reset(
- new ProxyResolverV8Tracing(error_observer_.Pass(), thread_.Pass(),
- v8_resolver_.Pass(), job_params_.Pass()));
+ resolver_out_->reset(new ProxyResolverV8TracingImpl(
+ thread_.Pass(), v8_resolver_.Pass(), job_params_.Pass()));
} else {
StopWorkerThread();
}
@@ -1120,58 +1049,51 @@ class ProxyResolverFactoryV8Tracing::CreateJob
thread_.reset();
}
- ProxyResolverFactoryV8Tracing* factory_;
+ ProxyResolverV8TracingFactoryImpl* factory_;
scoped_ptr<base::Thread> thread_;
- scoped_ptr<ProxyResolverErrorObserver> error_observer_;
scoped_ptr<Job::Params> job_params_;
scoped_refptr<Job> create_resolver_job_;
scoped_ptr<ProxyResolverV8> v8_resolver_;
- scoped_ptr<ProxyResolver>* resolver_out_;
+ scoped_ptr<ProxyResolverV8Tracing>* resolver_out_;
const CompletionCallback callback_;
int num_outstanding_callbacks_;
DISALLOW_COPY_AND_ASSIGN(CreateJob);
};
-ProxyResolverFactoryV8Tracing::ProxyResolverFactoryV8Tracing(
- HostResolver* host_resolver,
- NetLog* net_log,
- const ProxyResolver::LoadStateChangedCallback& callback,
- const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>&
- error_observer_factory)
- : ProxyResolverFactory(true),
- host_resolver_(host_resolver),
- net_log_(net_log),
- load_state_changed_callback_(callback),
- error_observer_factory_(error_observer_factory) {
+ProxyResolverV8TracingFactoryImpl::ProxyResolverV8TracingFactoryImpl() {
}
-ProxyResolverFactoryV8Tracing::~ProxyResolverFactoryV8Tracing() {
+ProxyResolverV8TracingFactoryImpl::~ProxyResolverV8TracingFactoryImpl() {
for (auto job : jobs_) {
job->FactoryDestroyed();
}
}
-// ProxyResolverFactory override.
-int ProxyResolverFactoryV8Tracing::CreateProxyResolver(
+void ProxyResolverV8TracingFactoryImpl::CreateProxyResolverV8Tracing(
const scoped_refptr<ProxyResolverScriptData>& pac_script,
- scoped_ptr<ProxyResolver>* resolver,
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings,
+ scoped_ptr<ProxyResolverV8Tracing>* resolver,
const CompletionCallback& callback,
- scoped_ptr<Request>* request) {
- scoped_ptr<CreateJob> job(new CreateJob(
- this, host_resolver_,
- error_observer_factory_.is_null() ? nullptr
- : error_observer_factory_.Run(),
- net_log_, load_state_changed_callback_, pac_script, resolver, callback));
+ scoped_ptr<ProxyResolverFactory::Request>* request) {
+ scoped_ptr<CreateJob> job(
+ new CreateJob(this, bindings.Pass(), pac_script, resolver, callback));
jobs_.insert(job.get());
*request = job.Pass();
- return ERR_IO_PENDING;
}
-void ProxyResolverFactoryV8Tracing::RemoveJob(
- ProxyResolverFactoryV8Tracing::CreateJob* job) {
+void ProxyResolverV8TracingFactoryImpl::RemoveJob(
+ ProxyResolverV8TracingFactoryImpl::CreateJob* job) {
size_t erased = jobs_.erase(job);
DCHECK_EQ(1u, erased);
}
+} // namespace
+
+// static
+scoped_ptr<ProxyResolverV8TracingFactory>
+ProxyResolverV8TracingFactory::Create() {
+ return make_scoped_ptr(new ProxyResolverV8TracingFactoryImpl());
+}
+
} // namespace net
diff --git a/net/proxy/proxy_resolver_v8_tracing.h b/net/proxy/proxy_resolver_v8_tracing.h
index c2a9de5..0b0ab35 100644
--- a/net/proxy/proxy_resolver_v8_tracing.h
+++ b/net/proxy/proxy_resolver_v8_tracing.h
@@ -5,8 +5,6 @@
#ifndef NET_PROXY_PROXY_RESOLVER_V8_TRACING_H_
#define NET_PROXY_PROXY_RESOLVER_V8_TRACING_H_
-#include <set>
-
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -17,50 +15,84 @@
namespace net {
class HostResolver;
-class NetLog;
-class ProxyResolverErrorObserver;
-// ProxyResolverFactoryV8Tracing is a ProxyResolverFactory that returns
-// non-blocking ProxyResolver instances. Each ProxyResolver instance executes
-// ProxyResolverV8 on a single helper thread, and does some magic to avoid
+// ProxyResolverV8Tracing is a non-blocking proxy resolver.
+class NET_EXPORT ProxyResolverV8Tracing {
+ public:
+ // Bindings is an interface used by ProxyResolverV8Tracing to delegate
+ // per-request functionality. Each instance will be destroyed on the origin
+ // thread of the ProxyResolverV8Tracing when the request completes or after
+ // the request is cancelled. In the cancellation case, the Bindings instance
+ // for a request may be destroyed after CancelRequest completes.
+ class Bindings {
+ public:
+ Bindings() {}
+ virtual ~Bindings() {}
+
+ // Invoked in response to an alert() call by the PAC script. This may be
+ // called after cancellation and from any thread.
+ virtual void Alert(const base::string16& message) = 0;
+
+ // Invoked in response to an error in the PAC script. This may be
+ // called after cancellation and from any thread.
+ virtual void OnError(int line_number, const base::string16& message) = 0;
+
+ // Returns a HostResolver to use for DNS resolution. This will only be
+ // called from the origin thread and will never be called after
+ // cancellation.
+ virtual HostResolver* GetHostResolver() = 0;
+
+ // Returns a BoundNetLog to be passed to the HostResolver returned by
+ // GetHostResolver(). This will only be called from the origin thread and
+ // will never be called after cancellation.
+ virtual BoundNetLog GetBoundNetLog() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Bindings);
+ };
+
+ virtual ~ProxyResolverV8Tracing() {}
+
+ // Gets a list of proxy servers to use for |url|. This request always
+ // runs asynchronously and notifies the result by running |callback|. If the
+ // result code is OK then the request was successful and |results| contains
+ // the proxy resolution information. If |request| is non-null, |*request| is
+ // written to, and can be passed to CancelRequest().
+ virtual void GetProxyForURL(const GURL& url,
+ ProxyInfo* results,
+ const CompletionCallback& callback,
+ ProxyResolver::RequestHandle* request,
+ scoped_ptr<Bindings> bindings) = 0;
+
+ // Cancels |request|.
+ virtual void CancelRequest(ProxyResolver::RequestHandle request) = 0;
+
+ // Gets the LoadState for |request|.
+ virtual LoadState GetLoadState(
+ ProxyResolver::RequestHandle request) const = 0;
+};
+
+// A factory for ProxyResolverV8Tracing instances. The default implementation,
+// returned by Create(), creates ProxyResolverV8Tracing instances that execute
+// ProxyResolverV8 on a single helper thread, and do some magic to avoid
// blocking in DNS. For more details see the design document:
// https://docs.google.com/a/google.com/document/d/16Ij5OcVnR3s0MH4Z5XkhI9VTPoMJdaBn9rKreAmGOdE/edit?pli=1
-class NET_EXPORT ProxyResolverFactoryV8Tracing : public ProxyResolverFactory {
+class NET_EXPORT ProxyResolverV8TracingFactory {
public:
- // Note that |host_resolver| and |net_log| are expected to outlive |this| and
- // any ProxyResolver instances created using |this|. |error_observer_factory|
- // will be invoked once per CreateProxyResolver() call to create a
- // ProxyResolverErrorObserver to be used by the ProxyResolver instance
- // returned by that call.
- ProxyResolverFactoryV8Tracing(
- HostResolver* host_resolver,
- NetLog* net_log,
- const ProxyResolver::LoadStateChangedCallback& callback,
- const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>&
- error_observer_factory);
- ~ProxyResolverFactoryV8Tracing() override;
-
- // ProxyResolverFactory override.
- int CreateProxyResolver(
+ ProxyResolverV8TracingFactory() {}
+ virtual ~ProxyResolverV8TracingFactory() = default;
+
+ virtual void CreateProxyResolverV8Tracing(
const scoped_refptr<ProxyResolverScriptData>& pac_script,
- scoped_ptr<ProxyResolver>* resolver,
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings,
+ scoped_ptr<ProxyResolverV8Tracing>* resolver,
const CompletionCallback& callback,
- scoped_ptr<Request>* request) override;
+ scoped_ptr<ProxyResolverFactory::Request>* request) = 0;
- private:
- class CreateJob;
+ static scoped_ptr<ProxyResolverV8TracingFactory> Create();
- void RemoveJob(CreateJob* job);
-
- HostResolver* const host_resolver_;
- NetLog* const net_log_;
- const ProxyResolver::LoadStateChangedCallback load_state_changed_callback_;
- const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>
- error_observer_factory_;
-
- std::set<CreateJob*> jobs_;
-
- DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactoryV8Tracing);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8TracingFactory);
};
} // namespace net
diff --git a/net/proxy/proxy_resolver_v8_tracing_unittest.cc b/net/proxy/proxy_resolver_v8_tracing_unittest.cc
index 296853c..6eda3b8 100644
--- a/net/proxy/proxy_resolver_v8_tracing_unittest.cc
+++ b/net/proxy/proxy_resolver_v8_tracing_unittest.cc
@@ -7,11 +7,8 @@
#include <string>
#include "base/files/file_util.h"
-#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
-#include "base/stl_util.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
+#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
@@ -21,11 +18,7 @@
#include "net/dns/host_cache.h"
#include "net/dns/mock_host_resolver.h"
#include "net/log/net_log.h"
-#include "net/log/test_net_log.h"
-#include "net/log/test_net_log_entry.h"
-#include "net/log/test_net_log_util.h"
#include "net/proxy/proxy_info.h"
-#include "net/proxy/proxy_resolver_error_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -39,7 +32,7 @@ class ProxyResolverV8TracingTest : public testing::Test {
// Drain any pending messages, which may be left over from cancellation.
// This way they get reliably run as part of the current test, rather than
// spilling into the next test's execution.
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
}
};
@@ -62,154 +55,153 @@ scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) {
return ProxyResolverScriptData::FromUTF8(file_contents);
}
-scoped_ptr<ProxyResolverErrorObserver> ReturnErrorObserver(
- scoped_ptr<ProxyResolverErrorObserver> error_observer) {
- return error_observer;
-}
-
-scoped_ptr<ProxyResolver> CreateResolver(
- NetLog* net_log,
- HostResolver* host_resolver,
- scoped_ptr<ProxyResolverErrorObserver> error_observer,
- const char* filename) {
- scoped_ptr<ProxyResolver> resolver;
- ProxyResolverFactoryV8Tracing factory(
- host_resolver, net_log, ProxyResolver::LoadStateChangedCallback(),
- base::Bind(&ReturnErrorObserver, base::Passed(&error_observer)));
- TestCompletionCallback callback;
- scoped_ptr<ProxyResolverFactory::Request> request;
- int rv = factory.CreateProxyResolver(LoadScriptData(filename), &resolver,
- callback.callback(), &request);
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, callback.WaitForResult());
- EXPECT_TRUE(resolver);
- return resolver.Pass();
-}
-
-class MockErrorObserver : public ProxyResolverErrorObserver {
+class MockBindings {
public:
- MockErrorObserver() : event_(true, false) {}
+ explicit MockBindings(HostResolver* host_resolver)
+ : host_resolver_(host_resolver), event_(true, false) {}
- void OnPACScriptError(int line_number, const base::string16& error) override {
- {
- base::AutoLock l(lock_);
- output += base::StringPrintf("Error: line %d: %s\n", line_number,
- base::UTF16ToASCII(error).c_str());
- }
+ void Alert(const base::string16& message) {
+ base::AutoLock l(lock_);
+ alerts_.push_back(base::UTF16ToASCII(message));
+ }
+ void OnError(int line_number, const base::string16& error) {
+ base::AutoLock l(lock_);
+ errors_.push_back(std::make_pair(line_number, base::UTF16ToASCII(error)));
event_.Signal();
}
- std::string GetOutput() {
+ HostResolver* host_resolver() { return host_resolver_; }
+
+ std::vector<std::string> GetAlerts() {
+ base::AutoLock l(lock_);
+ return alerts_;
+ }
+
+ std::vector<std::pair<int, std::string>> GetErrors() {
base::AutoLock l(lock_);
- return output;
+ return errors_;
}
- void WaitForOutput() {
- event_.Wait();
+ void WaitForError() { event_.Wait(); }
+
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> CreateBindings() {
+ return make_scoped_ptr(new ForwardingBindings(this));
}
private:
+ class ForwardingBindings : public ProxyResolverV8Tracing::Bindings {
+ public:
+ ForwardingBindings(MockBindings* bindings) : bindings_(bindings) {}
+
+ // ProxyResolverV8Tracing::Bindings overrides.
+ void Alert(const base::string16& message) override {
+ bindings_->Alert(message);
+ }
+
+ void OnError(int line_number, const base::string16& error) override {
+ bindings_->OnError(line_number, error);
+ }
+
+ BoundNetLog GetBoundNetLog() override { return BoundNetLog(); }
+
+ HostResolver* GetHostResolver() override {
+ return bindings_->host_resolver();
+ }
+
+ private:
+ MockBindings* bindings_;
+ };
+
base::Lock lock_;
- std::string output;
+ std::vector<std::string> alerts_;
+ std::vector<std::pair<int, std::string>> errors_;
+ HostResolver* const host_resolver_;
base::WaitableEvent event_;
};
+scoped_ptr<ProxyResolverV8Tracing> CreateResolver(
+ scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings,
+ const char* filename) {
+ scoped_ptr<ProxyResolverV8Tracing> resolver;
+ scoped_ptr<ProxyResolverV8TracingFactory> factory(
+ ProxyResolverV8TracingFactory::Create());
+ TestCompletionCallback callback;
+ scoped_ptr<ProxyResolverFactory::Request> request;
+ factory->CreateProxyResolverV8Tracing(LoadScriptData(filename),
+ bindings.Pass(), &resolver,
+ callback.callback(), &request);
+ EXPECT_EQ(OK, callback.WaitForResult());
+ EXPECT_TRUE(resolver);
+ return resolver.Pass();
+}
+
TEST_F(ProxyResolverV8TracingTest, Simple) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- &log, &host_resolver, make_scoped_ptr(error_observer), "simple.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "simple.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
- EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_EQ("foo:99", proxy_info.proxy_server().ToURI());
EXPECT_EQ(0u, host_resolver.num_resolve());
- // There were no errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- // Check the NetLogs -- nothing was logged.
- EXPECT_EQ(0u, log.GetSize());
- EXPECT_EQ(0u, request_log.GetSize());
+ // There were no alerts or errors.
+ EXPECT_TRUE(mock_bindings.GetAlerts().empty());
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
}
TEST_F(ProxyResolverV8TracingTest, JavascriptError) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- &log, &host_resolver, make_scoped_ptr(error_observer), "error.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "error.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
+ resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
- EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
EXPECT_EQ(0u, host_resolver.num_resolve());
- EXPECT_EQ("Error: line 5: Uncaught TypeError: Cannot read property 'split' "
- "of null\n", error_observer->GetOutput());
-
- // Check the NetLogs -- there was 1 alert and 1 javascript error, and they
- // were output to both the global log, and per-request log.
- TestNetLogEntry::List entries_list[2];
- log.GetEntries(&entries_list[0]);
- request_log.GetEntries(&entries_list[1]);
-
- for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
- const TestNetLogEntry::List& entries = entries_list[list_i];
- EXPECT_EQ(2u, entries.size());
- EXPECT_TRUE(
- LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::PHASE_NONE));
- EXPECT_TRUE(
- LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
- NetLog::PHASE_NONE));
-
- EXPECT_EQ("{\"message\":\"Prepare to DIE!\"}", entries[0].GetParamsJson());
- EXPECT_EQ("{\"line_number\":5,\"message\":\"Uncaught TypeError: Cannot "
- "read property 'split' of null\"}", entries[1].GetParamsJson());
- }
+ // Check the output -- there was 1 alert and 1 javascript error.
+ ASSERT_EQ(1u, mock_bindings.GetAlerts().size());
+ EXPECT_EQ("Prepare to DIE!", mock_bindings.GetAlerts()[0]);
+ ASSERT_EQ(1u, mock_bindings.GetErrors().size());
+ EXPECT_EQ(5, mock_bindings.GetErrors()[0].first);
+ EXPECT_EQ("Uncaught TypeError: Cannot read property 'split' of null",
+ mock_bindings.GetErrors()[0].second);
}
TEST_F(ProxyResolverV8TracingTest, TooManyAlerts) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver =
- CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
- "too_many_alerts.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "too_many_alerts.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
- EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, callback.WaitForResult());
// Iteration1 does a DNS resolve
@@ -220,45 +212,32 @@ TEST_F(ProxyResolverV8TracingTest, TooManyAlerts) {
EXPECT_EQ(1u, host_resolver.num_resolve());
// No errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- // Check the NetLogs -- the script generated 50 alerts, which were mirrored
- // to both the global and per-request logs.
- TestNetLogEntry::List entries_list[2];
- log.GetEntries(&entries_list[0]);
- request_log.GetEntries(&entries_list[1]);
-
- for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
- const TestNetLogEntry::List& entries = entries_list[list_i];
- EXPECT_EQ(50u, entries.size());
- for (size_t i = 0; i < entries.size(); ++i) {
- ASSERT_TRUE(
- LogContainsEvent(entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::PHASE_NONE));
- }
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
+
+ // Check the alerts -- the script generated 50 alerts.
+ std::vector<std::string> alerts = mock_bindings.GetAlerts();
+ ASSERT_EQ(50u, alerts.size());
+ for (size_t i = 0; i < alerts.size(); i++) {
+ EXPECT_EQ("Gee, all these alerts are silly!", alerts[i]);
}
}
// Verify that buffered alerts cannot grow unboundedly, even when the message is
// empty string.
TEST_F(ProxyResolverV8TracingTest, TooManyEmptyAlerts) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver =
- CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
- "too_many_empty_alerts.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver = CreateResolver(
+ mock_bindings.CreateBindings(), "too_many_empty_alerts.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
- EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_EQ("foo:3", proxy_info.proxy_server().ToURI());
@@ -266,22 +245,13 @@ TEST_F(ProxyResolverV8TracingTest, TooManyEmptyAlerts) {
EXPECT_EQ(1u, host_resolver.num_resolve());
// No errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- // Check the NetLogs -- the script generated 50 alerts, which were mirrored
- // to both the global and per-request logs.
- TestNetLogEntry::List entries_list[2];
- log.GetEntries(&entries_list[0]);
- request_log.GetEntries(&entries_list[1]);
-
- for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
- const TestNetLogEntry::List& entries = entries_list[list_i];
- EXPECT_EQ(1000u, entries.size());
- for (size_t i = 0; i < entries.size(); ++i) {
- ASSERT_TRUE(
- LogContainsEvent(entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::PHASE_NONE));
- }
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
+
+ // Check the alerts -- the script generated 1000 alerts.
+ std::vector<std::string> alerts = mock_bindings.GetAlerts();
+ ASSERT_EQ(1000u, alerts.size());
+ for (size_t i = 0; i < alerts.size(); i++) {
+ EXPECT_EQ("", alerts[i]);
}
}
@@ -289,10 +259,8 @@ TEST_F(ProxyResolverV8TracingTest, TooManyEmptyAlerts) {
// verifies the final result, and that the underlying DNS resolver received
// the correct set of queries.
TEST_F(ProxyResolverV8TracingTest, Dns) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddRuleForAddressFamily(
"host1", ADDRESS_FAMILY_IPV4, "166.155.144.44");
@@ -306,17 +274,16 @@ TEST_F(ProxyResolverV8TracingTest, Dns) {
"*", ADDRESS_FAMILY_IPV4, "122.133.144.155");
host_resolver.rules()->AddRule("*", "133.122.100.200");
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- &log, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "dns.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
- EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, callback.WaitForResult());
// The test does 13 DNS resolution, however only 7 of them are unique.
@@ -341,48 +308,34 @@ TEST_F(ProxyResolverV8TracingTest, Dns) {
EXPECT_EQ(kExpectedResult, proxy_info.proxy_server().ToURI());
// No errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- // Check the NetLogs -- the script generated 1 alert, mirrored to both
- // the per-request and global logs.
- TestNetLogEntry::List entries_list[2];
- log.GetEntries(&entries_list[0]);
- request_log.GetEntries(&entries_list[1]);
-
- for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
- const TestNetLogEntry::List& entries = entries_list[list_i];
- EXPECT_EQ(1u, entries.size());
- EXPECT_TRUE(
- LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::PHASE_NONE));
- EXPECT_EQ("{\"message\":\"iteration: 7\"}", entries[0].GetParamsJson());
- }
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
+
+ // The script generated 1 alert.
+ ASSERT_EQ(1u, mock_bindings.GetAlerts().size());
+ EXPECT_EQ("iteration: 7", mock_bindings.GetAlerts()[0]);
}
// This test runs a PAC script that does "myIpAddress()" followed by
// "dnsResolve()". This requires 2 restarts. However once the HostResolver's
// cache is warmed, subsequent calls should take 0 restarts.
TEST_F(ProxyResolverV8TracingTest, DnsChecksCache) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddRule("foopy", "166.155.144.11");
host_resolver.rules()->AddRule("*", "122.133.144.155");
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- &log, &host_resolver, make_scoped_ptr(error_observer), "simple_dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "simple_dns.js");
TestCompletionCallback callback1;
TestCompletionCallback callback2;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
- callback1.callback(), NULL, request_log.bound());
+ resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
+ callback1.callback(), NULL,
+ mock_bindings.CreateBindings());
- EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, callback1.WaitForResult());
// The test does 2 DNS resolutions.
@@ -391,11 +344,10 @@ TEST_F(ProxyResolverV8TracingTest, DnsChecksCache) {
// The first request took 2 restarts, hence on g_iteration=3.
EXPECT_EQ("166.155.144.11:3", proxy_info.proxy_server().ToURI());
- rv =
- resolver->GetProxyForURL(GURL("http://foopy/req2"), &proxy_info,
- callback2.callback(), NULL, request_log.bound());
+ resolver->GetProxyForURL(GURL("http://foopy/req2"), &proxy_info,
+ callback2.callback(), NULL,
+ mock_bindings.CreateBindings());
- EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_EQ(OK, callback2.WaitForResult());
EXPECT_EQ(4u, host_resolver.num_resolve());
@@ -403,37 +355,31 @@ TEST_F(ProxyResolverV8TracingTest, DnsChecksCache) {
// This time no restarts were required, so g_iteration incremented by 1.
EXPECT_EQ("166.155.144.11:4", proxy_info.proxy_server().ToURI());
- // No errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- EXPECT_EQ(0u, log.GetSize());
- EXPECT_EQ(0u, request_log.GetSize());
+ // There were no alerts or errors.
+ EXPECT_TRUE(mock_bindings.GetAlerts().empty());
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
}
// This test runs a weird PAC script that was designed to defeat the DNS tracing
// optimization. The proxy resolver should detect the inconsistency and
// fall-back to synchronous mode execution.
TEST_F(ProxyResolverV8TracingTest, FallBackToSynchronous1) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddRule("host1", "166.155.144.11");
host_resolver.rules()->AddRule("crazy4", "133.199.111.4");
host_resolver.rules()->AddRule("*", "122.133.144.155");
- scoped_ptr<ProxyResolver> resolver =
- CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
- "global_sideffects1.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "global_sideffects1.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
EXPECT_EQ(OK, callback.WaitForResult());
// The script itself only does 2 DNS resolves per execution, however it
@@ -445,32 +391,18 @@ TEST_F(ProxyResolverV8TracingTest, FallBackToSynchronous1) {
proxy_info.proxy_server().ToURI());
// No errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- // Check the NetLogs -- the script generated 1 alert, mirrored to both
- // the per-request and global logs.
- TestNetLogEntry::List entries_list[2];
- log.GetEntries(&entries_list[0]);
- request_log.GetEntries(&entries_list[1]);
-
- for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
- const TestNetLogEntry::List& entries = entries_list[list_i];
- EXPECT_EQ(1u, entries.size());
- EXPECT_TRUE(
- LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::PHASE_NONE));
- EXPECT_EQ("{\"message\":\"iteration: 4\"}", entries[0].GetParamsJson());
- }
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
+
+ ASSERT_EQ(1u, mock_bindings.GetAlerts().size());
+ EXPECT_EQ("iteration: 4", mock_bindings.GetAlerts()[0]);
}
// This test runs a weird PAC script that was designed to defeat the DNS tracing
// optimization. The proxy resolver should detect the inconsistency and
// fall-back to synchronous mode execution.
TEST_F(ProxyResolverV8TracingTest, FallBackToSynchronous2) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddRule("host1", "166.155.144.11");
host_resolver.rules()->AddRule("host2", "166.155.144.22");
@@ -478,29 +410,24 @@ TEST_F(ProxyResolverV8TracingTest, FallBackToSynchronous2) {
host_resolver.rules()->AddRule("host4", "166.155.144.44");
host_resolver.rules()->AddRule("*", "122.133.144.155");
- scoped_ptr<ProxyResolver> resolver =
- CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
- "global_sideffects2.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "global_sideffects2.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_EQ(3u, host_resolver.num_resolve());
EXPECT_EQ("166.155.144.44:100", proxy_info.proxy_server().ToURI());
- // No errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- // Check the NetLogs -- nothing was logged.
- EXPECT_EQ(0u, log.GetSize());
- EXPECT_EQ(0u, request_log.GetSize());
+ // There were no alerts or errors.
+ EXPECT_TRUE(mock_bindings.GetAlerts().empty());
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
}
// This test runs a weird PAC script that yields a never ending sequence
@@ -508,25 +435,21 @@ TEST_F(ProxyResolverV8TracingTest, FallBackToSynchronous2) {
// DNS resolves per request limit (20) after which every DNS resolve will
// fail.
TEST_F(ProxyResolverV8TracingTest, InfiniteDNSSequence) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddRule("host*", "166.155.144.11");
host_resolver.rules()->AddRule("*", "122.133.144.155");
- scoped_ptr<ProxyResolver> resolver =
- CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
- "global_sideffects3.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "global_sideffects3.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_EQ(20u, host_resolver.num_resolve());
@@ -540,11 +463,11 @@ TEST_F(ProxyResolverV8TracingTest, InfiniteDNSSequence) {
"null:21", proxy_info.proxy_server().ToURI());
// No errors.
- EXPECT_EQ("", error_observer->GetOutput());
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
- // Check the NetLogs -- 1 alert was logged.
- EXPECT_EQ(1u, log.GetSize());
- EXPECT_EQ(1u, request_log.GetSize());
+ // 1 alert.
+ EXPECT_EQ(1u, mock_bindings.GetAlerts().size());
+ EXPECT_EQ("iteration: 21", mock_bindings.GetAlerts()[0]);
}
// This test runs a weird PAC script that yields a never ending sequence
@@ -552,25 +475,21 @@ TEST_F(ProxyResolverV8TracingTest, InfiniteDNSSequence) {
// DNS resolves per request limit (20) after which every DNS resolve will
// fail.
TEST_F(ProxyResolverV8TracingTest, InfiniteDNSSequence2) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddRule("host*", "166.155.144.11");
host_resolver.rules()->AddRule("*", "122.133.144.155");
- scoped_ptr<ProxyResolver> resolver =
- CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
- "global_sideffects4.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "global_sideffects4.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_EQ(20u, host_resolver.num_resolve());
@@ -578,26 +497,23 @@ TEST_F(ProxyResolverV8TracingTest, InfiniteDNSSequence2) {
EXPECT_EQ("null21:34", proxy_info.proxy_server().ToURI());
// No errors.
- EXPECT_EQ("", error_observer->GetOutput());
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
- // Check the NetLogs -- 1 alert was logged.
- EXPECT_EQ(1u, log.GetSize());
- EXPECT_EQ(1u, request_log.GetSize());
+ // 1 alert.
+ EXPECT_EQ(1u, mock_bindings.GetAlerts().size());
+ EXPECT_EQ("iteration: 21", mock_bindings.GetAlerts()[0]);
}
void DnsDuringInitHelper(bool synchronous_host_resolver) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.set_synchronous_mode(synchronous_host_resolver);
- MockErrorObserver* error_observer = new MockErrorObserver;
host_resolver.rules()->AddRule("host1", "91.13.12.1");
host_resolver.rules()->AddRule("host2", "91.13.12.2");
- scoped_ptr<ProxyResolver> resolver =
- CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
- "dns_during_init.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "dns_during_init.js");
// Initialization did 2 dnsResolves.
EXPECT_EQ(2u, host_resolver.num_resolve());
@@ -611,10 +527,9 @@ void DnsDuringInitHelper(bool synchronous_host_resolver) {
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
EXPECT_EQ(OK, callback.WaitForResult());
// Fetched host1 and host2 again, since the ones done during initialization
@@ -624,21 +539,10 @@ void DnsDuringInitHelper(bool synchronous_host_resolver) {
EXPECT_EQ("91.13.12.1-91.13.12.2-145.88.13.3-137.89.8.45:99",
proxy_info.proxy_server().ToURI());
- // Check the NetLogs -- the script generated 2 alerts during initialization.
- EXPECT_EQ(0u, request_log.GetSize());
- TestNetLogEntry::List entries;
- log.GetEntries(&entries);
-
- ASSERT_EQ(2u, entries.size());
- EXPECT_TRUE(
- LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::PHASE_NONE));
- EXPECT_TRUE(
- LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
- NetLog::PHASE_NONE));
-
- EXPECT_EQ("{\"message\":\"Watsup\"}", entries[0].GetParamsJson());
- EXPECT_EQ("{\"message\":\"Watsup2\"}", entries[1].GetParamsJson());
+ // 2 alerts.
+ ASSERT_EQ(2u, mock_bindings.GetAlerts().size());
+ EXPECT_EQ("Watsup", mock_bindings.GetAlerts()[0]);
+ EXPECT_EQ("Watsup2", mock_bindings.GetAlerts()[1]);
}
// Tests a PAC script which does DNS resolves during initialization.
@@ -660,22 +564,21 @@ void CrashCallback(int) {
// times.
TEST_F(ProxyResolverV8TracingTest, CancelAll) {
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddSimulatedFailure("*");
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "dns.js");
const size_t kNumRequests = 5;
ProxyInfo proxy_info[kNumRequests];
ProxyResolver::RequestHandle request[kNumRequests];
for (size_t i = 0; i < kNumRequests; ++i) {
- int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info[i],
- base::Bind(&CrashCallback), &request[i],
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info[i],
+ base::Bind(&CrashCallback), &request[i],
+ mock_bindings.CreateBindings());
}
for (size_t i = 0; i < kNumRequests; ++i) {
@@ -688,12 +591,12 @@ TEST_F(ProxyResolverV8TracingTest, CancelAll) {
// times.
TEST_F(ProxyResolverV8TracingTest, CancelSome) {
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddSimulatedFailure("*");
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "dns.js");
ProxyInfo proxy_info1;
ProxyInfo proxy_info2;
@@ -701,14 +604,12 @@ TEST_F(ProxyResolverV8TracingTest, CancelSome) {
ProxyResolver::RequestHandle request2;
TestCompletionCallback callback;
- int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
- base::Bind(&CrashCallback), &request1,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info2,
- callback.callback(), &request2, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
+ base::Bind(&CrashCallback), &request1,
+ mock_bindings.CreateBindings());
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info2,
+ callback.callback(), &request2,
+ mock_bindings.CreateBindings());
resolver->CancelRequest(request1);
@@ -719,12 +620,12 @@ TEST_F(ProxyResolverV8TracingTest, CancelSome) {
// posted a task the completion task back to origin thread.
TEST_F(ProxyResolverV8TracingTest, CancelWhilePendingCompletionTask) {
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddSimulatedFailure("*");
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- nullptr, &host_resolver, make_scoped_ptr(error_observer), "error.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "error.js");
ProxyInfo proxy_info1;
ProxyInfo proxy_info2;
@@ -734,18 +635,17 @@ TEST_F(ProxyResolverV8TracingTest, CancelWhilePendingCompletionTask) {
ProxyResolver::RequestHandle request3;
TestCompletionCallback callback;
- int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
- base::Bind(&CrashCallback), &request1,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
+ base::Bind(&CrashCallback), &request1,
+ mock_bindings.CreateBindings());
- rv = resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info2,
- callback.callback(), &request2, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://throw-an-error"), &proxy_info2,
+ callback.callback(), &request2,
+ mock_bindings.CreateBindings());
// Wait until the first request has finished running on the worker thread.
// (The second request will output an error).
- error_observer->WaitForOutput();
+ mock_bindings.WaitForError();
// Cancel the first request, while it has a pending completion task on
// the origin thread.
@@ -754,10 +654,9 @@ TEST_F(ProxyResolverV8TracingTest, CancelWhilePendingCompletionTask) {
EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
// Start another request, to make sure it is able to complete.
- rv = resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"),
- &proxy_info3, callback.callback(), &request3,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"),
+ &proxy_info3, callback.callback(), &request3,
+ mock_bindings.CreateBindings());
EXPECT_EQ(OK, callback.WaitForResult());
@@ -836,29 +735,25 @@ class BlockableHostResolver : public HostResolver {
// when the request has an outstanding DNS request in flight.
TEST_F(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) {
BlockableHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "dns.js");
ProxyInfo proxy_info1;
ProxyInfo proxy_info2;
ProxyResolver::RequestHandle request1;
ProxyResolver::RequestHandle request2;
- int rv = resolver->GetProxyForURL(GURL("http://foo/req1"), &proxy_info1,
- base::Bind(&CrashCallback), &request1,
- BoundNetLog());
-
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/req1"), &proxy_info1,
+ base::Bind(&CrashCallback), &request1,
+ mock_bindings.CreateBindings());
host_resolver.WaitUntilRequestIsReceived();
- rv = resolver->GetProxyForURL(GURL("http://foo/req2"), &proxy_info2,
- base::Bind(&CrashCallback), &request2,
- BoundNetLog());
-
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/req2"), &proxy_info2,
+ base::Bind(&CrashCallback), &request2,
+ mock_bindings.CreateBindings());
host_resolver.WaitUntilRequestIsReceived();
@@ -872,7 +767,7 @@ TEST_F(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) {
// should have been cancelled.
}
-void CancelRequestAndPause(ProxyResolver* resolver,
+void CancelRequestAndPause(ProxyResolverV8Tracing* resolver,
ProxyResolver::RequestHandle request) {
resolver->CancelRequest(request);
@@ -887,19 +782,17 @@ void CancelRequestAndPause(ProxyResolver* resolver,
// cancellation while the worker thread is waiting on this event.
TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns) {
BlockableHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "dns.js");
ProxyInfo proxy_info;
ProxyResolver::RequestHandle request;
- int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- base::Bind(&CrashCallback), &request,
- BoundNetLog());
-
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ base::Bind(&CrashCallback), &request,
+ mock_bindings.CreateBindings());
host_resolver.SetAction(
base::Bind(CancelRequestAndPause, resolver.get(), request));
@@ -916,19 +809,17 @@ TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns) {
// the request is sent to the host resolver.
TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns2) {
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "dns.js");
ProxyInfo proxy_info;
ProxyResolver::RequestHandle request;
- int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
- base::Bind(&CrashCallback), &request,
- BoundNetLog());
-
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ base::Bind(&CrashCallback), &request,
+ mock_bindings.CreateBindings());
// Wait a bit, so the DNS task has hopefully been posted. The test will
// work whatever the delay is here, but it is most useful if the delay
@@ -942,19 +833,15 @@ TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns2) {
TEST_F(ProxyResolverV8TracingTest,
CancelCreateResolverWhileOutstandingBlockingDns) {
BlockableHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- ProxyResolverFactoryV8Tracing factory(
- &host_resolver, nullptr, ProxyResolver::LoadStateChangedCallback(),
- base::Bind(&ReturnErrorObserver,
- base::Passed(make_scoped_ptr(error_observer))));
-
- scoped_ptr<ProxyResolver> resolver;
+ scoped_ptr<ProxyResolverV8TracingFactory> factory(
+ ProxyResolverV8TracingFactory::Create());
+ scoped_ptr<ProxyResolverV8Tracing> resolver;
scoped_ptr<ProxyResolverFactory::Request> request;
- int rv = factory.CreateProxyResolver(LoadScriptData("dns_during_init.js"),
- &resolver, base::Bind(&CrashCallback),
- &request);
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ factory->CreateProxyResolverV8Tracing(
+ LoadScriptData("dns_during_init.js"), mock_bindings.CreateBindings(),
+ &resolver, base::Bind(&CrashCallback), &request);
host_resolver.WaitUntilRequestIsReceived();
@@ -964,20 +851,17 @@ TEST_F(ProxyResolverV8TracingTest,
TEST_F(ProxyResolverV8TracingTest, DeleteFactoryWhileOutstandingBlockingDns) {
BlockableHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- scoped_ptr<ProxyResolver> resolver;
+ scoped_ptr<ProxyResolverV8Tracing> resolver;
scoped_ptr<ProxyResolverFactory::Request> request;
{
- ProxyResolverFactoryV8Tracing factory(
- &host_resolver, nullptr, ProxyResolver::LoadStateChangedCallback(),
- base::Bind(&ReturnErrorObserver,
- base::Passed(make_scoped_ptr(error_observer))));
-
- int rv = factory.CreateProxyResolver(LoadScriptData("dns_during_init.js"),
- &resolver, base::Bind(&CrashCallback),
- &request);
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ scoped_ptr<ProxyResolverV8TracingFactory> factory(
+ ProxyResolverV8TracingFactory::Create());
+
+ factory->CreateProxyResolverV8Tracing(
+ LoadScriptData("dns_during_init.js"), mock_bindings.CreateBindings(),
+ &resolver, base::Bind(&CrashCallback), &request);
host_resolver.WaitUntilRequestIsReceived();
}
EXPECT_EQ(1, host_resolver.num_cancelled_requests());
@@ -985,20 +869,17 @@ TEST_F(ProxyResolverV8TracingTest, DeleteFactoryWhileOutstandingBlockingDns) {
TEST_F(ProxyResolverV8TracingTest, ErrorLoadingScript) {
BlockableHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
- ProxyResolverFactoryV8Tracing factory(
- &host_resolver, nullptr, ProxyResolver::LoadStateChangedCallback(),
- base::Bind(&ReturnErrorObserver,
- base::Passed(make_scoped_ptr(error_observer))));
-
- scoped_ptr<ProxyResolver> resolver;
+ scoped_ptr<ProxyResolverV8TracingFactory> factory(
+ ProxyResolverV8TracingFactory::Create());
+ scoped_ptr<ProxyResolverV8Tracing> resolver;
scoped_ptr<ProxyResolverFactory::Request> request;
TestCompletionCallback callback;
- int rv =
- factory.CreateProxyResolver(LoadScriptData("error_on_load.js"), &resolver,
- callback.callback(), &request);
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ factory->CreateProxyResolverV8Tracing(
+ LoadScriptData("error_on_load.js"), mock_bindings.CreateBindings(),
+ &resolver, callback.callback(), &request);
+
EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
EXPECT_FALSE(resolver);
}
@@ -1006,25 +887,21 @@ TEST_F(ProxyResolverV8TracingTest, ErrorLoadingScript) {
// This tests that the execution of a PAC script is terminated when the DNS
// dependencies are missing. If the test fails, then it will hang.
TEST_F(ProxyResolverV8TracingTest, Terminate) {
- TestNetLog log;
- BoundTestNetLog request_log;
MockCachingHostResolver host_resolver;
- MockErrorObserver* error_observer = new MockErrorObserver;
+ MockBindings mock_bindings(&host_resolver);
host_resolver.rules()->AddRule("host1", "182.111.0.222");
host_resolver.rules()->AddRule("host2", "111.33.44.55");
- scoped_ptr<ProxyResolver> resolver = CreateResolver(
- &log, &host_resolver, make_scoped_ptr(error_observer), "terminate.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver =
+ CreateResolver(mock_bindings.CreateBindings(), "terminate.js");
TestCompletionCallback callback;
ProxyInfo proxy_info;
- int rv =
- resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
- callback.callback(), NULL, request_log.bound());
-
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
+ callback.callback(), NULL,
+ mock_bindings.CreateBindings());
EXPECT_EQ(OK, callback.WaitForResult());
// The test does 2 DNS resolutions.
@@ -1032,11 +909,9 @@ TEST_F(ProxyResolverV8TracingTest, Terminate) {
EXPECT_EQ("foopy:3", proxy_info.proxy_server().ToURI());
- // No errors.
- EXPECT_EQ("", error_observer->GetOutput());
-
- EXPECT_EQ(0u, log.GetSize());
- EXPECT_EQ(0u, request_log.GetSize());
+ // No errors or alerts.
+ EXPECT_TRUE(mock_bindings.GetErrors().empty());
+ EXPECT_TRUE(mock_bindings.GetAlerts().empty());
}
// Tests that multiple instances of ProxyResolverV8Tracing can coexist and run
@@ -1048,6 +923,7 @@ TEST_F(ProxyResolverV8TracingTest, MultipleResolvers) {
// Setup resolver0
// ------------------------
MockHostResolver host_resolver0;
+ MockBindings mock_bindings0(&host_resolver0);
host_resolver0.rules()->AddRuleForAddressFamily(
"host1", ADDRESS_FAMILY_IPV4, "166.155.144.44");
host_resolver0.rules()
@@ -1059,38 +935,35 @@ TEST_F(ProxyResolverV8TracingTest, MultipleResolvers) {
host_resolver0.rules()->AddRuleForAddressFamily(
"*", ADDRESS_FAMILY_IPV4, "122.133.144.155");
host_resolver0.rules()->AddRule("*", "133.122.100.200");
- scoped_ptr<ProxyResolver> resolver0 =
- CreateResolver(nullptr, &host_resolver0,
- make_scoped_ptr(new MockErrorObserver), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver0 =
+ CreateResolver(mock_bindings0.CreateBindings(), "dns.js");
// ------------------------
// Setup resolver1
// ------------------------
- scoped_ptr<ProxyResolver> resolver1 =
- CreateResolver(nullptr, &host_resolver0,
- make_scoped_ptr(new MockErrorObserver), "dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver1 =
+ CreateResolver(mock_bindings0.CreateBindings(), "dns.js");
// ------------------------
// Setup resolver2
// ------------------------
- scoped_ptr<ProxyResolver> resolver2 =
- CreateResolver(nullptr, &host_resolver0,
- make_scoped_ptr(new MockErrorObserver), "simple.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver2 =
+ CreateResolver(mock_bindings0.CreateBindings(), "simple.js");
// ------------------------
// Setup resolver3
// ------------------------
MockHostResolver host_resolver3;
+ MockBindings mock_bindings3(&host_resolver3);
host_resolver3.rules()->AddRule("foo", "166.155.144.33");
- scoped_ptr<ProxyResolver> resolver3 =
- CreateResolver(nullptr, &host_resolver3,
- make_scoped_ptr(new MockErrorObserver), "simple_dns.js");
+ scoped_ptr<ProxyResolverV8Tracing> resolver3 =
+ CreateResolver(mock_bindings3.CreateBindings(), "simple_dns.js");
// ------------------------
// Queue up work for each resolver (which will be running in parallel).
// ------------------------
- ProxyResolver* resolver[] = {
+ ProxyResolverV8Tracing* resolver[] = {
resolver0.get(), resolver1.get(), resolver2.get(), resolver3.get(),
};
@@ -1102,10 +975,10 @@ TEST_F(ProxyResolverV8TracingTest, MultipleResolvers) {
for (size_t i = 0; i < kNumResults; ++i) {
size_t resolver_i = i % kNumResolvers;
- int rv = resolver[resolver_i]->GetProxyForURL(
+ resolver[resolver_i]->GetProxyForURL(
GURL("http://foo/"), &proxy_info[i], callback[i].callback(), NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ resolver_i == 3 ? mock_bindings3.CreateBindings()
+ : mock_bindings0.CreateBindings());
}
// ------------------------
diff --git a/net/proxy/proxy_resolver_v8_tracing_wrapper.cc b/net/proxy/proxy_resolver_v8_tracing_wrapper.cc
new file mode 100644
index 0000000..01dde66
--- /dev/null
+++ b/net/proxy/proxy_resolver_v8_tracing_wrapper.cc
@@ -0,0 +1,193 @@
+// Copyright 2015 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/proxy/proxy_resolver_v8_tracing_wrapper.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "net/base/net_errors.h"
+#include "net/log/net_log.h"
+#include "net/proxy/proxy_resolver_error_observer.h"
+
+namespace net {
+namespace {
+
+// Returns event parameters for a PAC error message (line number + message).
+scoped_ptr<base::Value> NetLogErrorCallback(
+ int line_number,
+ const base::string16* message,
+ NetLogCaptureMode /* capture_mode */) {
+ scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ dict->SetInteger("line_number", line_number);
+ dict->SetString("message", *message);
+ return dict.Pass();
+}
+
+class BindingsImpl : public ProxyResolverV8Tracing::Bindings {
+ public:
+ BindingsImpl(ProxyResolverErrorObserver* error_observer,
+ HostResolver* host_resolver,
+ NetLog* net_log,
+ const BoundNetLog& bound_net_log)
+ : error_observer_(error_observer),
+ host_resolver_(host_resolver),
+ net_log_(net_log),
+ bound_net_log_(bound_net_log) {}
+
+ // ProxyResolverV8Tracing::Bindings overrides.
+ void Alert(const base::string16& message) override {
+ // Send to the NetLog.
+ LogEventToCurrentRequestAndGlobally(
+ NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+ NetLog::StringCallback("message", &message));
+ }
+
+ void OnError(int line_number, const base::string16& message) override {
+ // Send the error to the NetLog.
+ LogEventToCurrentRequestAndGlobally(
+ NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
+ base::Bind(&NetLogErrorCallback, line_number, &message));
+ if (error_observer_)
+ error_observer_->OnPACScriptError(line_number, message);
+ }
+
+ HostResolver* GetHostResolver() override { return host_resolver_; }
+
+ BoundNetLog GetBoundNetLog() override { return bound_net_log_; }
+
+ private:
+ void LogEventToCurrentRequestAndGlobally(
+ NetLog::EventType type,
+ const NetLog::ParametersCallback& parameters_callback) {
+ bound_net_log_.AddEvent(type, parameters_callback);
+
+ // Emit to the global NetLog event stream.
+ if (net_log_)
+ net_log_->AddGlobalEntry(type, parameters_callback);
+ }
+
+ ProxyResolverErrorObserver* error_observer_;
+ HostResolver* host_resolver_;
+ NetLog* net_log_;
+ BoundNetLog bound_net_log_;
+};
+
+class ProxyResolverV8TracingWrapper : public ProxyResolver {
+ public:
+ ProxyResolverV8TracingWrapper(
+ scoped_ptr<ProxyResolverV8Tracing> resolver_impl,
+ NetLog* net_log,
+ HostResolver* host_resolver,
+ scoped_ptr<ProxyResolverErrorObserver> error_observer);
+
+ int GetProxyForURL(const GURL& url,
+ ProxyInfo* results,
+ const CompletionCallback& callback,
+ RequestHandle* request,
+ const BoundNetLog& net_log) override;
+
+ void CancelRequest(RequestHandle request) override;
+
+ LoadState GetLoadState(RequestHandle request) const override;
+
+ private:
+ scoped_ptr<ProxyResolverV8Tracing> resolver_impl_;
+ NetLog* net_log_;
+ HostResolver* host_resolver_;
+ scoped_ptr<ProxyResolverErrorObserver> error_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8TracingWrapper);
+};
+
+ProxyResolverV8TracingWrapper::ProxyResolverV8TracingWrapper(
+ scoped_ptr<ProxyResolverV8Tracing> resolver_impl,
+ NetLog* net_log,
+ HostResolver* host_resolver,
+ scoped_ptr<ProxyResolverErrorObserver> error_observer)
+ : resolver_impl_(resolver_impl.Pass()),
+ net_log_(net_log),
+ host_resolver_(host_resolver),
+ error_observer_(error_observer.Pass()) {
+}
+
+int ProxyResolverV8TracingWrapper::GetProxyForURL(
+ const GURL& url,
+ ProxyInfo* results,
+ const CompletionCallback& callback,
+ RequestHandle* request,
+ const BoundNetLog& net_log) {
+ resolver_impl_->GetProxyForURL(
+ url, results, callback, request,
+ make_scoped_ptr(new BindingsImpl(error_observer_.get(), host_resolver_,
+ net_log_, net_log)));
+ return ERR_IO_PENDING;
+}
+
+void ProxyResolverV8TracingWrapper::CancelRequest(RequestHandle request) {
+ resolver_impl_->CancelRequest(request);
+}
+
+LoadState ProxyResolverV8TracingWrapper::GetLoadState(
+ RequestHandle request) const {
+ return resolver_impl_->GetLoadState(request);
+}
+
+} // namespace
+
+ProxyResolverFactoryV8TracingWrapper::ProxyResolverFactoryV8TracingWrapper(
+ HostResolver* host_resolver,
+ NetLog* net_log,
+ const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>&
+ error_observer_factory)
+ : ProxyResolverFactory(true),
+ factory_impl_(ProxyResolverV8TracingFactory::Create()),
+ host_resolver_(host_resolver),
+ net_log_(net_log),
+ error_observer_factory_(error_observer_factory) {
+}
+
+ProxyResolverFactoryV8TracingWrapper::~ProxyResolverFactoryV8TracingWrapper() =
+ default;
+
+int ProxyResolverFactoryV8TracingWrapper::CreateProxyResolver(
+ const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ scoped_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ scoped_ptr<Request>* request) {
+ scoped_ptr<scoped_ptr<ProxyResolverV8Tracing>> v8_resolver(
+ new scoped_ptr<ProxyResolverV8Tracing>);
+ scoped_ptr<ProxyResolverErrorObserver> error_observer =
+ error_observer_factory_.Run();
+ // Note: Argument evaluation order is unspecified, so make copies before
+ // passing |v8_resolver| and |error_observer|.
+ scoped_ptr<ProxyResolverV8Tracing>* v8_resolver_local = v8_resolver.get();
+ ProxyResolverErrorObserver* error_observer_local = error_observer.get();
+ factory_impl_->CreateProxyResolverV8Tracing(
+ pac_script,
+ make_scoped_ptr(new BindingsImpl(error_observer_local, host_resolver_,
+ net_log_, BoundNetLog())),
+ v8_resolver_local,
+ base::Bind(&ProxyResolverFactoryV8TracingWrapper::OnProxyResolverCreated,
+ base::Unretained(this), base::Passed(&v8_resolver), resolver,
+ callback, base::Passed(&error_observer)),
+ request);
+ return ERR_IO_PENDING;
+}
+
+void ProxyResolverFactoryV8TracingWrapper::OnProxyResolverCreated(
+ scoped_ptr<scoped_ptr<ProxyResolverV8Tracing>> v8_resolver,
+ scoped_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ scoped_ptr<ProxyResolverErrorObserver> error_observer,
+ int error) {
+ if (error == OK) {
+ resolver->reset(new ProxyResolverV8TracingWrapper(
+ v8_resolver->Pass(), net_log_, host_resolver_, error_observer.Pass()));
+ }
+ callback.Run(error);
+}
+
+} // namespace net
diff --git a/net/proxy/proxy_resolver_v8_tracing_wrapper.h b/net/proxy/proxy_resolver_v8_tracing_wrapper.h
new file mode 100644
index 0000000..28343d8
--- /dev/null
+++ b/net/proxy/proxy_resolver_v8_tracing_wrapper.h
@@ -0,0 +1,65 @@
+// Copyright 2015 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_PROXY_PROXY_RESOLVER_V8_TRACING_WRAPPER_H_
+#define NET_PROXY_PROXY_RESOLVER_V8_TRACING_WRAPPER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_resolver.h"
+#include "net/proxy/proxy_resolver_factory.h"
+#include "net/proxy/proxy_resolver_v8_tracing.h"
+
+namespace net {
+
+class HostResolver;
+class NetLog;
+class ProxyResolverErrorObserver;
+
+// A wrapper for ProxyResolverV8TracingFactory that implements the
+// ProxyResolverFactory interface.
+class NET_EXPORT ProxyResolverFactoryV8TracingWrapper
+ : public ProxyResolverFactory {
+ public:
+ // Note that |host_resolver| and |net_log| are expected to outlive |this| and
+ // any ProxyResolver instances created using |this|. |error_observer_factory|
+ // will be invoked once per CreateProxyResolver() call to create a
+ // ProxyResolverErrorObserver to be used by the ProxyResolver instance
+ // returned by that call.
+ ProxyResolverFactoryV8TracingWrapper(
+ HostResolver* host_resolver,
+ NetLog* net_log,
+ const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>&
+ error_observer_factory);
+ ~ProxyResolverFactoryV8TracingWrapper() override;
+
+ // ProxyResolverFactory override.
+ int CreateProxyResolver(
+ const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ scoped_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ scoped_ptr<Request>* request) override;
+
+ private:
+ void OnProxyResolverCreated(
+ scoped_ptr<scoped_ptr<ProxyResolverV8Tracing>> v8_resolver,
+ scoped_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ scoped_ptr<ProxyResolverErrorObserver> error_observer,
+ int error);
+
+ scoped_ptr<ProxyResolverV8TracingFactory> factory_impl_;
+ HostResolver* const host_resolver_;
+ NetLog* const net_log_;
+ const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>
+ error_observer_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactoryV8TracingWrapper);
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_RESOLVER_V8_TRACING_WRAPPER_H_
diff --git a/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc b/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
new file mode 100644
index 0000000..7a77b82
--- /dev/null
+++ b/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
@@ -0,0 +1,1145 @@
+// Copyright (c) 2013 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/proxy/proxy_resolver_v8_tracing_wrapper.h"
+
+#include <string>
+
+#include "base/files/file_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
+#include "base/stl_util.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/platform_thread.h"
+#include "base/values.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "net/dns/host_cache.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/log/net_log.h"
+#include "net/log/test_net_log.h"
+#include "net/log/test_net_log_entry.h"
+#include "net/log/test_net_log_util.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_resolver_error_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace net {
+
+namespace {
+
+class ProxyResolverV8TracingWrapperTest : public testing::Test {
+ public:
+ void TearDown() override {
+ // Drain any pending messages, which may be left over from cancellation.
+ // This way they get reliably run as part of the current test, rather than
+ // spilling into the next test's execution.
+ base::MessageLoop::current()->RunUntilIdle();
+ }
+};
+
+scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) {
+ base::FilePath path;
+ PathService::Get(base::DIR_SOURCE_ROOT, &path);
+ path = path.AppendASCII("net");
+ path = path.AppendASCII("data");
+ path = path.AppendASCII("proxy_resolver_v8_tracing_unittest");
+ path = path.AppendASCII(filename);
+
+ // Try to read the file from disk.
+ std::string file_contents;
+ bool ok = base::ReadFileToString(path, &file_contents);
+
+ // If we can't load the file from disk, something is misconfigured.
+ EXPECT_TRUE(ok) << "Failed to read file: " << path.value();
+
+ // Load the PAC script into the ProxyResolver.
+ return ProxyResolverScriptData::FromUTF8(file_contents);
+}
+
+scoped_ptr<ProxyResolverErrorObserver> ReturnErrorObserver(
+ scoped_ptr<ProxyResolverErrorObserver> error_observer) {
+ return error_observer;
+}
+
+scoped_ptr<ProxyResolver> CreateResolver(
+ NetLog* net_log,
+ HostResolver* host_resolver,
+ scoped_ptr<ProxyResolverErrorObserver> error_observer,
+ const char* filename) {
+ scoped_ptr<ProxyResolver> resolver;
+ ProxyResolverFactoryV8TracingWrapper factory(
+ host_resolver, net_log,
+ base::Bind(&ReturnErrorObserver, base::Passed(&error_observer)));
+ TestCompletionCallback callback;
+ scoped_ptr<ProxyResolverFactory::Request> request;
+ int rv = factory.CreateProxyResolver(LoadScriptData(filename), &resolver,
+ callback.callback(), &request);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+ EXPECT_TRUE(resolver);
+ return resolver.Pass();
+}
+
+class MockErrorObserver : public ProxyResolverErrorObserver {
+ public:
+ MockErrorObserver() : event_(true, false) {}
+
+ void OnPACScriptError(int line_number, const base::string16& error) override {
+ {
+ base::AutoLock l(lock_);
+ output += base::StringPrintf("Error: line %d: %s\n", line_number,
+ base::UTF16ToASCII(error).c_str());
+ }
+ event_.Signal();
+ }
+
+ std::string GetOutput() {
+ base::AutoLock l(lock_);
+ return output;
+ }
+
+ void WaitForOutput() { event_.Wait(); }
+
+ private:
+ base::Lock lock_;
+ std::string output;
+
+ base::WaitableEvent event_;
+};
+
+TEST_F(ProxyResolverV8TracingWrapperTest, Simple) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ &log, &host_resolver, make_scoped_ptr(error_observer), "simple.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ EXPECT_EQ("foo:99", proxy_info.proxy_server().ToURI());
+
+ EXPECT_EQ(0u, host_resolver.num_resolve());
+
+ // There were no errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- nothing was logged.
+ EXPECT_EQ(0u, log.GetSize());
+ EXPECT_EQ(0u, request_log.GetSize());
+}
+
+TEST_F(ProxyResolverV8TracingWrapperTest, JavascriptError) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ &log, &host_resolver, make_scoped_ptr(error_observer), "error.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
+
+ EXPECT_EQ(0u, host_resolver.num_resolve());
+
+ EXPECT_EQ(
+ "Error: line 5: Uncaught TypeError: Cannot read property 'split' "
+ "of null\n",
+ error_observer->GetOutput());
+
+ // Check the NetLogs -- there was 1 alert and 1 javascript error, and they
+ // were output to both the global log, and per-request log.
+ TestNetLogEntry::List entries_list[2];
+ log.GetEntries(&entries_list[0]);
+ request_log.GetEntries(&entries_list[1]);
+
+ for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
+ const TestNetLogEntry::List& entries = entries_list[list_i];
+ EXPECT_EQ(2u, entries.size());
+ EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+ NetLog::PHASE_NONE));
+ EXPECT_TRUE(LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
+ NetLog::PHASE_NONE));
+
+ EXPECT_EQ("{\"message\":\"Prepare to DIE!\"}", entries[0].GetParamsJson());
+ EXPECT_EQ(
+ "{\"line_number\":5,\"message\":\"Uncaught TypeError: Cannot "
+ "read property 'split' of null\"}",
+ entries[1].GetParamsJson());
+ }
+}
+
+TEST_F(ProxyResolverV8TracingWrapperTest, TooManyAlerts) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver =
+ CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
+ "too_many_alerts.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ // Iteration1 does a DNS resolve
+ // Iteration2 exceeds the alert buffer
+ // Iteration3 runs in blocking mode and completes
+ EXPECT_EQ("foo:3", proxy_info.proxy_server().ToURI());
+
+ EXPECT_EQ(1u, host_resolver.num_resolve());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- the script generated 50 alerts, which were mirrored
+ // to both the global and per-request logs.
+ TestNetLogEntry::List entries_list[2];
+ log.GetEntries(&entries_list[0]);
+ request_log.GetEntries(&entries_list[1]);
+
+ for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
+ const TestNetLogEntry::List& entries = entries_list[list_i];
+ EXPECT_EQ(50u, entries.size());
+ for (size_t i = 0; i < entries.size(); ++i) {
+ ASSERT_TRUE(LogContainsEvent(
+ entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, NetLog::PHASE_NONE));
+ }
+ }
+}
+
+// Verify that buffered alerts cannot grow unboundedly, even when the message is
+// empty string.
+TEST_F(ProxyResolverV8TracingWrapperTest, TooManyEmptyAlerts) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver =
+ CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
+ "too_many_empty_alerts.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ EXPECT_EQ("foo:3", proxy_info.proxy_server().ToURI());
+
+ EXPECT_EQ(1u, host_resolver.num_resolve());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- the script generated 50 alerts, which were mirrored
+ // to both the global and per-request logs.
+ TestNetLogEntry::List entries_list[2];
+ log.GetEntries(&entries_list[0]);
+ request_log.GetEntries(&entries_list[1]);
+
+ for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
+ const TestNetLogEntry::List& entries = entries_list[list_i];
+ EXPECT_EQ(1000u, entries.size());
+ for (size_t i = 0; i < entries.size(); ++i) {
+ ASSERT_TRUE(LogContainsEvent(
+ entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, NetLog::PHASE_NONE));
+ }
+ }
+}
+
+// This test runs a PAC script that issues a sequence of DNS resolves. The test
+// verifies the final result, and that the underlying DNS resolver received
+// the correct set of queries.
+TEST_F(ProxyResolverV8TracingWrapperTest, Dns) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRuleForAddressFamily("host1", ADDRESS_FAMILY_IPV4,
+ "166.155.144.44");
+ host_resolver.rules()->AddIPLiteralRule("host1", "::1,192.168.1.1",
+ std::string());
+ host_resolver.rules()->AddSimulatedFailure("host2");
+ host_resolver.rules()->AddRule("host3", "166.155.144.33");
+ host_resolver.rules()->AddRule("host5", "166.155.144.55");
+ host_resolver.rules()->AddSimulatedFailure("host6");
+ host_resolver.rules()->AddRuleForAddressFamily("*", ADDRESS_FAMILY_IPV4,
+ "122.133.144.155");
+ host_resolver.rules()->AddRule("*", "133.122.100.200");
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ &log, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ // The test does 13 DNS resolution, however only 7 of them are unique.
+ EXPECT_EQ(7u, host_resolver.num_resolve());
+
+ const char* kExpectedResult =
+ "122.133.144.155-" // myIpAddress()
+ "null-" // dnsResolve('')
+ "__1_192.168.1.1-" // dnsResolveEx('host1')
+ "null-" // dnsResolve('host2')
+ "166.155.144.33-" // dnsResolve('host3')
+ "122.133.144.155-" // myIpAddress()
+ "166.155.144.33-" // dnsResolve('host3')
+ "__1_192.168.1.1-" // dnsResolveEx('host1')
+ "122.133.144.155-" // myIpAddress()
+ "null-" // dnsResolve('host2')
+ "-" // dnsResolveEx('host6')
+ "133.122.100.200-" // myIpAddressEx()
+ "166.155.144.44" // dnsResolve('host1')
+ ":99";
+
+ EXPECT_EQ(kExpectedResult, proxy_info.proxy_server().ToURI());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- the script generated 1 alert, mirrored to both
+ // the per-request and global logs.
+ TestNetLogEntry::List entries_list[2];
+ log.GetEntries(&entries_list[0]);
+ request_log.GetEntries(&entries_list[1]);
+
+ for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
+ const TestNetLogEntry::List& entries = entries_list[list_i];
+ EXPECT_EQ(1u, entries.size());
+ EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+ NetLog::PHASE_NONE));
+ EXPECT_EQ("{\"message\":\"iteration: 7\"}", entries[0].GetParamsJson());
+ }
+}
+
+// This test runs a PAC script that does "myIpAddress()" followed by
+// "dnsResolve()". This requires 2 restarts. However once the HostResolver's
+// cache is warmed, subsequent calls should take 0 restarts.
+TEST_F(ProxyResolverV8TracingWrapperTest, DnsChecksCache) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRule("foopy", "166.155.144.11");
+ host_resolver.rules()->AddRule("*", "122.133.144.155");
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ &log, &host_resolver, make_scoped_ptr(error_observer), "simple_dns.js");
+
+ TestCompletionCallback callback1;
+ TestCompletionCallback callback2;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
+ callback1.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback1.WaitForResult());
+
+ // The test does 2 DNS resolutions.
+ EXPECT_EQ(2u, host_resolver.num_resolve());
+
+ // The first request took 2 restarts, hence on g_iteration=3.
+ EXPECT_EQ("166.155.144.11:3", proxy_info.proxy_server().ToURI());
+
+ rv =
+ resolver->GetProxyForURL(GURL("http://foopy/req2"), &proxy_info,
+ callback2.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback2.WaitForResult());
+
+ EXPECT_EQ(4u, host_resolver.num_resolve());
+
+ // This time no restarts were required, so g_iteration incremented by 1.
+ EXPECT_EQ("166.155.144.11:4", proxy_info.proxy_server().ToURI());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ EXPECT_EQ(0u, log.GetSize());
+ EXPECT_EQ(0u, request_log.GetSize());
+}
+
+// This test runs a weird PAC script that was designed to defeat the DNS tracing
+// optimization. The proxy resolver should detect the inconsistency and
+// fall-back to synchronous mode execution.
+TEST_F(ProxyResolverV8TracingWrapperTest, FallBackToSynchronous1) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRule("host1", "166.155.144.11");
+ host_resolver.rules()->AddRule("crazy4", "133.199.111.4");
+ host_resolver.rules()->AddRule("*", "122.133.144.155");
+
+ scoped_ptr<ProxyResolver> resolver =
+ CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
+ "global_sideffects1.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ // The script itself only does 2 DNS resolves per execution, however it
+ // constructs the hostname using a global counter which changes on each
+ // invocation.
+ EXPECT_EQ(3u, host_resolver.num_resolve());
+
+ EXPECT_EQ("166.155.144.11-133.199.111.4:100",
+ proxy_info.proxy_server().ToURI());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- the script generated 1 alert, mirrored to both
+ // the per-request and global logs.
+ TestNetLogEntry::List entries_list[2];
+ log.GetEntries(&entries_list[0]);
+ request_log.GetEntries(&entries_list[1]);
+
+ for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
+ const TestNetLogEntry::List& entries = entries_list[list_i];
+ EXPECT_EQ(1u, entries.size());
+ EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+ NetLog::PHASE_NONE));
+ EXPECT_EQ("{\"message\":\"iteration: 4\"}", entries[0].GetParamsJson());
+ }
+}
+
+// This test runs a weird PAC script that was designed to defeat the DNS tracing
+// optimization. The proxy resolver should detect the inconsistency and
+// fall-back to synchronous mode execution.
+TEST_F(ProxyResolverV8TracingWrapperTest, FallBackToSynchronous2) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRule("host1", "166.155.144.11");
+ host_resolver.rules()->AddRule("host2", "166.155.144.22");
+ host_resolver.rules()->AddRule("host3", "166.155.144.33");
+ host_resolver.rules()->AddRule("host4", "166.155.144.44");
+ host_resolver.rules()->AddRule("*", "122.133.144.155");
+
+ scoped_ptr<ProxyResolver> resolver =
+ CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
+ "global_sideffects2.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ EXPECT_EQ(3u, host_resolver.num_resolve());
+
+ EXPECT_EQ("166.155.144.44:100", proxy_info.proxy_server().ToURI());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- nothing was logged.
+ EXPECT_EQ(0u, log.GetSize());
+ EXPECT_EQ(0u, request_log.GetSize());
+}
+
+// This test runs a weird PAC script that yields a never ending sequence
+// of DNS resolves when restarting. Running it will hit the maximum
+// DNS resolves per request limit (20) after which every DNS resolve will
+// fail.
+TEST_F(ProxyResolverV8TracingWrapperTest, InfiniteDNSSequence) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRule("host*", "166.155.144.11");
+ host_resolver.rules()->AddRule("*", "122.133.144.155");
+
+ scoped_ptr<ProxyResolver> resolver =
+ CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
+ "global_sideffects3.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ EXPECT_EQ(20u, host_resolver.num_resolve());
+
+ EXPECT_EQ(
+ "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
+ "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
+ "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
+ "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
+ "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
+ "null:21",
+ proxy_info.proxy_server().ToURI());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- 1 alert was logged.
+ EXPECT_EQ(1u, log.GetSize());
+ EXPECT_EQ(1u, request_log.GetSize());
+}
+
+// This test runs a weird PAC script that yields a never ending sequence
+// of DNS resolves when restarting. Running it will hit the maximum
+// DNS resolves per request limit (20) after which every DNS resolve will
+// fail.
+TEST_F(ProxyResolverV8TracingWrapperTest, InfiniteDNSSequence2) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRule("host*", "166.155.144.11");
+ host_resolver.rules()->AddRule("*", "122.133.144.155");
+
+ scoped_ptr<ProxyResolver> resolver =
+ CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
+ "global_sideffects4.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ EXPECT_EQ(20u, host_resolver.num_resolve());
+
+ EXPECT_EQ("null21:34", proxy_info.proxy_server().ToURI());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ // Check the NetLogs -- 1 alert was logged.
+ EXPECT_EQ(1u, log.GetSize());
+ EXPECT_EQ(1u, request_log.GetSize());
+}
+
+void DnsDuringInitHelper(bool synchronous_host_resolver) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ host_resolver.set_synchronous_mode(synchronous_host_resolver);
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRule("host1", "91.13.12.1");
+ host_resolver.rules()->AddRule("host2", "91.13.12.2");
+
+ scoped_ptr<ProxyResolver> resolver =
+ CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
+ "dns_during_init.js");
+
+ // Initialization did 2 dnsResolves.
+ EXPECT_EQ(2u, host_resolver.num_resolve());
+
+ host_resolver.rules()->ClearRules();
+ host_resolver.GetHostCache()->clear();
+
+ host_resolver.rules()->AddRule("host1", "145.88.13.3");
+ host_resolver.rules()->AddRule("host2", "137.89.8.45");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ // Fetched host1 and host2 again, since the ones done during initialization
+ // should not have been cached.
+ EXPECT_EQ(4u, host_resolver.num_resolve());
+
+ EXPECT_EQ("91.13.12.1-91.13.12.2-145.88.13.3-137.89.8.45:99",
+ proxy_info.proxy_server().ToURI());
+
+ // Check the NetLogs -- the script generated 2 alerts during initialization.
+ EXPECT_EQ(0u, request_log.GetSize());
+ TestNetLogEntry::List entries;
+ log.GetEntries(&entries);
+
+ ASSERT_EQ(2u, entries.size());
+ EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+ NetLog::PHASE_NONE));
+ EXPECT_TRUE(LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+ NetLog::PHASE_NONE));
+
+ EXPECT_EQ("{\"message\":\"Watsup\"}", entries[0].GetParamsJson());
+ EXPECT_EQ("{\"message\":\"Watsup2\"}", entries[1].GetParamsJson());
+}
+
+// Tests a PAC script which does DNS resolves during initialization.
+TEST_F(ProxyResolverV8TracingWrapperTest, DnsDuringInit) {
+ // Test with both both a host resolver that always completes asynchronously,
+ // and then again with one that completes synchronously.
+ DnsDuringInitHelper(false);
+ DnsDuringInitHelper(true);
+}
+
+void CrashCallback(int) {
+ // Be extra sure that if the callback ever gets invoked, the test will fail.
+ CHECK(false);
+}
+
+// Start some requests, cancel them all, and then destroy the resolver.
+// Note the execution order for this test can vary. Since multiple
+// threads are involved, the cancellation may be received a different
+// times.
+TEST_F(ProxyResolverV8TracingWrapperTest, CancelAll) {
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddSimulatedFailure("*");
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+
+ const size_t kNumRequests = 5;
+ ProxyInfo proxy_info[kNumRequests];
+ ProxyResolver::RequestHandle request[kNumRequests];
+
+ for (size_t i = 0; i < kNumRequests; ++i) {
+ int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info[i],
+ base::Bind(&CrashCallback), &request[i],
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ }
+
+ for (size_t i = 0; i < kNumRequests; ++i) {
+ resolver->CancelRequest(request[i]);
+ }
+}
+
+// Note the execution order for this test can vary. Since multiple
+// threads are involved, the cancellation may be received a different
+// times.
+TEST_F(ProxyResolverV8TracingWrapperTest, CancelSome) {
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddSimulatedFailure("*");
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+
+ ProxyInfo proxy_info1;
+ ProxyInfo proxy_info2;
+ ProxyResolver::RequestHandle request1;
+ ProxyResolver::RequestHandle request2;
+ TestCompletionCallback callback;
+
+ int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
+ base::Bind(&CrashCallback), &request1,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info2,
+ callback.callback(), &request2, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ resolver->CancelRequest(request1);
+
+ EXPECT_EQ(OK, callback.WaitForResult());
+}
+
+// Cancel a request after it has finished running on the worker thread, and has
+// posted a task the completion task back to origin thread.
+TEST_F(ProxyResolverV8TracingWrapperTest, CancelWhilePendingCompletionTask) {
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddSimulatedFailure("*");
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ nullptr, &host_resolver, make_scoped_ptr(error_observer), "error.js");
+
+ ProxyInfo proxy_info1;
+ ProxyInfo proxy_info2;
+ ProxyInfo proxy_info3;
+ ProxyResolver::RequestHandle request1;
+ ProxyResolver::RequestHandle request2;
+ ProxyResolver::RequestHandle request3;
+ TestCompletionCallback callback;
+
+ int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
+ base::Bind(&CrashCallback), &request1,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info2,
+ callback.callback(), &request2, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // Wait until the first request has finished running on the worker thread.
+ // (The second request will output an error).
+ error_observer->WaitForOutput();
+
+ // Cancel the first request, while it has a pending completion task on
+ // the origin thread.
+ resolver->CancelRequest(request1);
+
+ EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
+
+ // Start another request, to make sure it is able to complete.
+ rv = resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"),
+ &proxy_info3, callback.callback(), &request3,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ EXPECT_EQ("i-approve-this-message:42", proxy_info3.proxy_server().ToURI());
+}
+
+// This implementation of HostResolver allows blocking until a resolve request
+// has been received. The resolve requests it receives will never be completed.
+class BlockableHostResolver : public HostResolver {
+ public:
+ BlockableHostResolver()
+ : num_cancelled_requests_(0), waiting_for_resolve_(false) {}
+
+ int Resolve(const RequestInfo& info,
+ RequestPriority priority,
+ AddressList* addresses,
+ const CompletionCallback& callback,
+ RequestHandle* out_req,
+ const BoundNetLog& net_log) override {
+ EXPECT_FALSE(callback.is_null());
+ EXPECT_TRUE(out_req);
+
+ if (!action_.is_null())
+ action_.Run();
+
+ // Indicate to the caller that a request was received.
+ EXPECT_TRUE(waiting_for_resolve_);
+ base::MessageLoop::current()->Quit();
+
+ // This line is intentionally after action_.Run(), since one of the
+ // tests does a cancellation inside of Resolve(), and it is more
+ // interesting if *out_req hasn't been written yet at that point.
+ *out_req = reinterpret_cast<RequestHandle*>(1); // Magic value.
+
+ // Return ERR_IO_PENDING as this request will NEVER be completed.
+ // Expectation is for the caller to later cancel the request.
+ return ERR_IO_PENDING;
+ }
+
+ int ResolveFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ const BoundNetLog& net_log) override {
+ NOTREACHED();
+ return ERR_DNS_CACHE_MISS;
+ }
+
+ void CancelRequest(RequestHandle req) override {
+ EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req);
+ num_cancelled_requests_++;
+ }
+
+ void SetAction(const base::Callback<void(void)>& action) { action_ = action; }
+
+ // Waits until Resolve() has been called.
+ void WaitUntilRequestIsReceived() {
+ waiting_for_resolve_ = true;
+ base::MessageLoop::current()->Run();
+ DCHECK(waiting_for_resolve_);
+ waiting_for_resolve_ = false;
+ }
+
+ int num_cancelled_requests() const { return num_cancelled_requests_; }
+
+ private:
+ int num_cancelled_requests_;
+ bool waiting_for_resolve_;
+ base::Callback<void(void)> action_;
+};
+
+// This cancellation test exercises a more predictable cancellation codepath --
+// when the request has an outstanding DNS request in flight.
+TEST_F(ProxyResolverV8TracingWrapperTest,
+ CancelWhileOutstandingNonBlockingDns) {
+ BlockableHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+
+ ProxyInfo proxy_info1;
+ ProxyInfo proxy_info2;
+ ProxyResolver::RequestHandle request1;
+ ProxyResolver::RequestHandle request2;
+
+ int rv = resolver->GetProxyForURL(GURL("http://foo/req1"), &proxy_info1,
+ base::Bind(&CrashCallback), &request1,
+ BoundNetLog());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ host_resolver.WaitUntilRequestIsReceived();
+
+ rv = resolver->GetProxyForURL(GURL("http://foo/req2"), &proxy_info2,
+ base::Bind(&CrashCallback), &request2,
+ BoundNetLog());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ host_resolver.WaitUntilRequestIsReceived();
+
+ resolver->CancelRequest(request1);
+ resolver->CancelRequest(request2);
+
+ EXPECT_EQ(2, host_resolver.num_cancelled_requests());
+
+ // After leaving this scope, the ProxyResolver is destroyed.
+ // This should not cause any problems, as the outstanding work
+ // should have been cancelled.
+}
+
+void CancelRequestAndPause(ProxyResolver* resolver,
+ ProxyResolver::RequestHandle request) {
+ resolver->CancelRequest(request);
+
+ // Sleep for a little bit. This makes it more likely for the worker
+ // thread to have returned from its call, and serves as a regression
+ // test for http://crbug.com/173373.
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
+}
+
+// In non-blocking mode, the worker thread actually does block for
+// a short time to see if the result is in the DNS cache. Test
+// cancellation while the worker thread is waiting on this event.
+TEST_F(ProxyResolverV8TracingWrapperTest, CancelWhileBlockedInNonBlockingDns) {
+ BlockableHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+
+ ProxyInfo proxy_info;
+ ProxyResolver::RequestHandle request;
+
+ int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ base::Bind(&CrashCallback), &request,
+ BoundNetLog());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ host_resolver.SetAction(
+ base::Bind(CancelRequestAndPause, resolver.get(), request));
+
+ host_resolver.WaitUntilRequestIsReceived();
+
+ // At this point the host resolver ran Resolve(), and should have cancelled
+ // the request.
+
+ EXPECT_EQ(1, host_resolver.num_cancelled_requests());
+}
+
+// Cancel the request while there is a pending DNS request, however before
+// the request is sent to the host resolver.
+TEST_F(ProxyResolverV8TracingWrapperTest, CancelWhileBlockedInNonBlockingDns2) {
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");
+
+ ProxyInfo proxy_info;
+ ProxyResolver::RequestHandle request;
+
+ int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
+ base::Bind(&CrashCallback), &request,
+ BoundNetLog());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // Wait a bit, so the DNS task has hopefully been posted. The test will
+ // work whatever the delay is here, but it is most useful if the delay
+ // is large enough to allow a task to be posted back.
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
+ resolver->CancelRequest(request);
+
+ EXPECT_EQ(0u, host_resolver.num_resolve());
+}
+
+TEST_F(ProxyResolverV8TracingWrapperTest,
+ CancelCreateResolverWhileOutstandingBlockingDns) {
+ BlockableHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ ProxyResolverFactoryV8TracingWrapper factory(
+ &host_resolver, nullptr,
+ base::Bind(&ReturnErrorObserver,
+ base::Passed(make_scoped_ptr(error_observer))));
+
+ scoped_ptr<ProxyResolver> resolver;
+ scoped_ptr<ProxyResolverFactory::Request> request;
+ int rv = factory.CreateProxyResolver(LoadScriptData("dns_during_init.js"),
+ &resolver, base::Bind(&CrashCallback),
+ &request);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ host_resolver.WaitUntilRequestIsReceived();
+
+ request.reset();
+ EXPECT_EQ(1, host_resolver.num_cancelled_requests());
+}
+
+TEST_F(ProxyResolverV8TracingWrapperTest,
+ DeleteFactoryWhileOutstandingBlockingDns) {
+ BlockableHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ scoped_ptr<ProxyResolver> resolver;
+ scoped_ptr<ProxyResolverFactory::Request> request;
+ {
+ ProxyResolverFactoryV8TracingWrapper factory(
+ &host_resolver, nullptr,
+ base::Bind(&ReturnErrorObserver,
+ base::Passed(make_scoped_ptr(error_observer))));
+
+ int rv = factory.CreateProxyResolver(LoadScriptData("dns_during_init.js"),
+ &resolver, base::Bind(&CrashCallback),
+ &request);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ host_resolver.WaitUntilRequestIsReceived();
+ }
+ EXPECT_EQ(1, host_resolver.num_cancelled_requests());
+}
+
+TEST_F(ProxyResolverV8TracingWrapperTest, ErrorLoadingScript) {
+ BlockableHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ ProxyResolverFactoryV8TracingWrapper factory(
+ &host_resolver, nullptr,
+ base::Bind(&ReturnErrorObserver,
+ base::Passed(make_scoped_ptr(error_observer))));
+
+ scoped_ptr<ProxyResolver> resolver;
+ scoped_ptr<ProxyResolverFactory::Request> request;
+ TestCompletionCallback callback;
+ int rv =
+ factory.CreateProxyResolver(LoadScriptData("error_on_load.js"), &resolver,
+ callback.callback(), &request);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
+ EXPECT_FALSE(resolver);
+}
+
+// This tests that the execution of a PAC script is terminated when the DNS
+// dependencies are missing. If the test fails, then it will hang.
+TEST_F(ProxyResolverV8TracingWrapperTest, Terminate) {
+ TestNetLog log;
+ BoundTestNetLog request_log;
+ MockCachingHostResolver host_resolver;
+ MockErrorObserver* error_observer = new MockErrorObserver;
+
+ host_resolver.rules()->AddRule("host1", "182.111.0.222");
+ host_resolver.rules()->AddRule("host2", "111.33.44.55");
+
+ scoped_ptr<ProxyResolver> resolver = CreateResolver(
+ &log, &host_resolver, make_scoped_ptr(error_observer), "terminate.js");
+
+ TestCompletionCallback callback;
+ ProxyInfo proxy_info;
+
+ int rv =
+ resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
+ callback.callback(), NULL, request_log.bound());
+
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ // The test does 2 DNS resolutions.
+ EXPECT_EQ(2u, host_resolver.num_resolve());
+
+ EXPECT_EQ("foopy:3", proxy_info.proxy_server().ToURI());
+
+ // No errors.
+ EXPECT_EQ("", error_observer->GetOutput());
+
+ EXPECT_EQ(0u, log.GetSize());
+ EXPECT_EQ(0u, request_log.GetSize());
+}
+
+// Tests that multiple instances of ProxyResolverV8TracingWrapper can coexist
+// and run correctly at the same time. This is relevant because at the moment
+// (time this test was written) each ProxyResolverV8TracingWrapper creates its
+// own thread to run V8 on, however each thread is operating on the same
+// v8::Isolate.
+TEST_F(ProxyResolverV8TracingWrapperTest, MultipleResolvers) {
+ // ------------------------
+ // Setup resolver0
+ // ------------------------
+ MockHostResolver host_resolver0;
+ host_resolver0.rules()->AddRuleForAddressFamily("host1", ADDRESS_FAMILY_IPV4,
+ "166.155.144.44");
+ host_resolver0.rules()->AddIPLiteralRule("host1", "::1,192.168.1.1",
+ std::string());
+ host_resolver0.rules()->AddSimulatedFailure("host2");
+ host_resolver0.rules()->AddRule("host3", "166.155.144.33");
+ host_resolver0.rules()->AddRule("host5", "166.155.144.55");
+ host_resolver0.rules()->AddSimulatedFailure("host6");
+ host_resolver0.rules()->AddRuleForAddressFamily("*", ADDRESS_FAMILY_IPV4,
+ "122.133.144.155");
+ host_resolver0.rules()->AddRule("*", "133.122.100.200");
+ scoped_ptr<ProxyResolver> resolver0 =
+ CreateResolver(nullptr, &host_resolver0,
+ make_scoped_ptr(new MockErrorObserver), "dns.js");
+
+ // ------------------------
+ // Setup resolver1
+ // ------------------------
+ scoped_ptr<ProxyResolver> resolver1 =
+ CreateResolver(nullptr, &host_resolver0,
+ make_scoped_ptr(new MockErrorObserver), "dns.js");
+
+ // ------------------------
+ // Setup resolver2
+ // ------------------------
+ scoped_ptr<ProxyResolver> resolver2 =
+ CreateResolver(nullptr, &host_resolver0,
+ make_scoped_ptr(new MockErrorObserver), "simple.js");
+
+ // ------------------------
+ // Setup resolver3
+ // ------------------------
+ MockHostResolver host_resolver3;
+ host_resolver3.rules()->AddRule("foo", "166.155.144.33");
+ scoped_ptr<ProxyResolver> resolver3 =
+ CreateResolver(nullptr, &host_resolver3,
+ make_scoped_ptr(new MockErrorObserver), "simple_dns.js");
+
+ // ------------------------
+ // Queue up work for each resolver (which will be running in parallel).
+ // ------------------------
+
+ ProxyResolver* resolver[] = {
+ resolver0.get(), resolver1.get(), resolver2.get(), resolver3.get(),
+ };
+
+ const size_t kNumResolvers = arraysize(resolver);
+ const size_t kNumIterations = 20;
+ const size_t kNumResults = kNumResolvers * kNumIterations;
+ TestCompletionCallback callback[kNumResults];
+ ProxyInfo proxy_info[kNumResults];
+
+ for (size_t i = 0; i < kNumResults; ++i) {
+ size_t resolver_i = i % kNumResolvers;
+ int rv = resolver[resolver_i]->GetProxyForURL(
+ GURL("http://foo/"), &proxy_info[i], callback[i].callback(), NULL,
+ BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ }
+
+ // ------------------------
+ // Verify all of the results.
+ // ------------------------
+
+ const char* kExpectedForDnsJs =
+ "122.133.144.155-" // myIpAddress()
+ "null-" // dnsResolve('')
+ "__1_192.168.1.1-" // dnsResolveEx('host1')
+ "null-" // dnsResolve('host2')
+ "166.155.144.33-" // dnsResolve('host3')
+ "122.133.144.155-" // myIpAddress()
+ "166.155.144.33-" // dnsResolve('host3')
+ "__1_192.168.1.1-" // dnsResolveEx('host1')
+ "122.133.144.155-" // myIpAddress()
+ "null-" // dnsResolve('host2')
+ "-" // dnsResolveEx('host6')
+ "133.122.100.200-" // myIpAddressEx()
+ "166.155.144.44" // dnsResolve('host1')
+ ":99";
+
+ for (size_t i = 0; i < kNumResults; ++i) {
+ size_t resolver_i = i % kNumResolvers;
+ EXPECT_EQ(OK, callback[i].WaitForResult());
+
+ std::string proxy_uri = proxy_info[i].proxy_server().ToURI();
+
+ if (resolver_i == 0 || resolver_i == 1) {
+ EXPECT_EQ(kExpectedForDnsJs, proxy_uri);
+ } else if (resolver_i == 2) {
+ EXPECT_EQ("foo:99", proxy_uri);
+ } else if (resolver_i == 3) {
+ EXPECT_EQ("166.155.144.33:",
+ proxy_uri.substr(0, proxy_uri.find(':') + 1));
+ } else {
+ NOTREACHED();
+ }
+ }
+}
+
+} // namespace
+
+} // namespace net
diff --git a/net/proxy/proxy_service_v8.cc b/net/proxy/proxy_service_v8.cc
index 3634613..46a6605 100644
--- a/net/proxy/proxy_service_v8.cc
+++ b/net/proxy/proxy_service_v8.cc
@@ -10,7 +10,7 @@
#include "net/proxy/network_delegate_error_observer.h"
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_resolver_factory.h"
-#include "net/proxy/proxy_resolver_v8_tracing.h"
+#include "net/proxy/proxy_resolver_v8_tracing_wrapper.h"
#include "net/proxy/proxy_service.h"
namespace net {
@@ -30,8 +30,8 @@ ProxyService* CreateProxyServiceUsingV8ProxyResolver(
ProxyService* proxy_service = new ProxyService(
proxy_config_service,
- make_scoped_ptr(new ProxyResolverFactoryV8Tracing(
- host_resolver, net_log, ProxyResolver::LoadStateChangedCallback(),
+ make_scoped_ptr(new ProxyResolverFactoryV8TracingWrapper(
+ host_resolver, net_log,
base::Bind(&NetworkDelegateErrorObserver::Create, network_delegate,
base::ThreadTaskRunnerHandle::Get()))),
net_log);