diff options
author | sammc <sammc@chromium.org> | 2015-05-15 05:20:59 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-15 12:21:12 +0000 |
commit | 359a8b7489247d20a4d83d5cc78ae684625f5f13 (patch) | |
tree | 5c7c0d726b010522be07ab6d1ce7a74af6f9d33b | |
parent | b9c370ab86c7f896a17853b1d502635efc834fbb (diff) | |
download | chromium_src-359a8b7489247d20a4d83d5cc78ae684625f5f13.zip chromium_src-359a8b7489247d20a4d83d5cc78ae684625f5f13.tar.gz chromium_src-359a8b7489247d20a4d83d5cc78ae684625f5f13.tar.bz2 |
Add support for ProxyResolverErrorObserver to ProxyResolverMojo.
BUG=467832
Review URL: https://codereview.chromium.org/1017453005
Cr-Commit-Position: refs/heads/master@{#330081}
20 files changed, 468 insertions, 116 deletions
diff --git a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.cc b/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.cc index 0be9eef..73ffff9 100644 --- a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.cc +++ b/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.cc @@ -64,6 +64,7 @@ UtilityProcessMojoProxyResolverFactory::CreateResolver( const mojo::String& pac_script, mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, net::interfaces::HostResolverPtr host_resolver, + net::interfaces::ProxyResolverErrorObserverPtr error_observer, net::interfaces::ProxyResolverFactoryRequestClientPtr client) { DCHECK(thread_checker_.CalledOnValidThread()); if (!resolver_factory_) @@ -78,7 +79,8 @@ UtilityProcessMojoProxyResolverFactory::CreateResolver( idle_timer_.Stop(); num_proxy_resolvers_++; resolver_factory_->CreateResolver(pac_script, req.Pass(), - host_resolver.Pass(), client.Pass()); + host_resolver.Pass(), error_observer.Pass(), + client.Pass()); return make_scoped_ptr(new base::ScopedClosureRunner( base::Bind(&UtilityProcessMojoProxyResolverFactory::OnResolverDestroyed, base::Unretained(this)))); diff --git a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h b/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h index 2b796a2..f6e9e21 100644 --- a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h +++ b/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h @@ -33,6 +33,7 @@ class UtilityProcessMojoProxyResolverFactory const mojo::String& pac_script, mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, net::interfaces::HostResolverPtr host_resolver, + net::interfaces::ProxyResolverErrorObserverPtr error_observer, net::interfaces::ProxyResolverFactoryRequestClientPtr client) override; private: diff --git a/net/BUILD.gn b/net/BUILD.gn index 70f5999..4a24c5a 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn @@ -839,6 +839,8 @@ if (use_v8_in_net && !is_android) { "proxy/mojo_proxy_resolver_factory_impl.h", "proxy/mojo_proxy_resolver_impl.cc", "proxy/mojo_proxy_resolver_impl.h", + "proxy/proxy_resolver_error_observer_mojo.cc", + "proxy/proxy_resolver_error_observer_mojo.h", ] deps = [ @@ -1493,6 +1495,7 @@ if (!is_android && !is_mac) { "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", "proxy/proxy_resolver_mojo_unittest.cc", "proxy/proxy_service_mojo_unittest.cc", ] diff --git a/net/interfaces/proxy_resolver_service.mojom b/net/interfaces/proxy_resolver_service.mojom index 57ab121..68f798e 100644 --- a/net/interfaces/proxy_resolver_service.mojom +++ b/net/interfaces/proxy_resolver_service.mojom @@ -42,11 +42,16 @@ interface ProxyResolverRequestClient { LoadStateChanged(int32 load_state); }; +interface ProxyResolverErrorObserver { + OnPacScriptError(int32 line_number, string error); +}; + interface ProxyResolverFactory { - // TODO(amistry): Add NetLog and ProxyResolverErrorObserver. + // TODO(amistry): Add NetLog. CreateResolver(string pac_script, ProxyResolver& resolver, HostResolver host_resolver, + ProxyResolverErrorObserver? error_observer, ProxyResolverFactoryRequestClient client); }; diff --git a/net/net.gyp b/net/net.gyp index 3db83b5..29ee1f9 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -319,6 +319,7 @@ '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', 'proxy/proxy_resolver_mojo_unittest.cc', 'proxy/proxy_service_mojo_unittest.cc', ], @@ -923,6 +924,8 @@ 'proxy/mojo_proxy_resolver_factory_impl.h', 'proxy/mojo_proxy_resolver_impl.cc', 'proxy/mojo_proxy_resolver_impl.h', + 'proxy/proxy_resolver_error_observer_mojo.cc', + 'proxy/proxy_resolver_error_observer_mojo.h', ], 'dependencies': [ 'mojo_type_converters', diff --git a/net/net.gypi b/net/net.gypi index e15717e..973ef998 100644 --- a/net/net.gypi +++ b/net/net.gypi @@ -1475,6 +1475,7 @@ 'proxy/proxy_config_unittest.cc', 'proxy/proxy_info_unittest.cc', 'proxy/proxy_list_unittest.cc', + 'proxy/proxy_resolver_error_observer_mojo_unittest.cc', 'proxy/proxy_resolver_mojo_unittest.cc', 'proxy/proxy_resolver_factory_unittest.cc', 'proxy/proxy_resolver_v8_tracing_unittest.cc', diff --git a/net/proxy/in_process_mojo_proxy_resolver_factory.cc b/net/proxy/in_process_mojo_proxy_resolver_factory.cc index b38a093..cb1cf21 100644 --- a/net/proxy/in_process_mojo_proxy_resolver_factory.cc +++ b/net/proxy/in_process_mojo_proxy_resolver_factory.cc @@ -30,9 +30,10 @@ InProcessMojoProxyResolverFactory::CreateResolver( const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> req, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) { factory_->CreateResolver(pac_script, req.Pass(), host_resolver.Pass(), - client.Pass()); + error_observer.Pass(), client.Pass()); return nullptr; } diff --git a/net/proxy/in_process_mojo_proxy_resolver_factory.h b/net/proxy/in_process_mojo_proxy_resolver_factory.h index 8794614..86895e9 100644 --- a/net/proxy/in_process_mojo_proxy_resolver_factory.h +++ b/net/proxy/in_process_mojo_proxy_resolver_factory.h @@ -25,6 +25,7 @@ class InProcessMojoProxyResolverFactory : public MojoProxyResolverFactory { const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> req, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) override; private: diff --git a/net/proxy/mojo_proxy_resolver_factory.h b/net/proxy/mojo_proxy_resolver_factory.h index a27b81a..89b70f4 100644 --- a/net/proxy/mojo_proxy_resolver_factory.h +++ b/net/proxy/mojo_proxy_resolver_factory.h @@ -24,6 +24,7 @@ class MojoProxyResolverFactory { const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> req, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) = 0; protected: diff --git a/net/proxy/mojo_proxy_resolver_factory_impl.cc b/net/proxy/mojo_proxy_resolver_factory_impl.cc index 15cdfa7..4a95aa7 100644 --- a/net/proxy/mojo_proxy_resolver_factory_impl.cc +++ b/net/proxy/mojo_proxy_resolver_factory_impl.cc @@ -10,7 +10,7 @@ #include "net/base/net_errors.h" #include "net/dns/host_resolver_mojo.h" #include "net/proxy/mojo_proxy_resolver_impl.h" -#include "net/proxy/proxy_resolver_error_observer.h" +#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" @@ -19,15 +19,18 @@ namespace net { namespace { -scoped_ptr<ProxyResolverErrorObserver> ReturnNullErrorObserver() { - return nullptr; +scoped_ptr<ProxyResolverErrorObserver> ReturnErrorObserver( + scoped_ptr<ProxyResolverErrorObserver> error_observer) { + return error_observer; } 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, base::Bind(&ReturnNullErrorObserver))); + host_resolver, nullptr, callback, + base::Bind(&ReturnErrorObserver, base::Passed(&error_observer)))); } class LoadStateChangeForwarder @@ -107,6 +110,7 @@ class MojoProxyResolverFactoryImpl::Job : public mojo::ErrorHandler { const MojoProxyResolverFactoryImpl::Factory& proxy_resolver_factory, mojo::InterfaceRequest<interfaces::ProxyResolver> request, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client); ~Job() override; @@ -134,6 +138,7 @@ MojoProxyResolverFactoryImpl::Job::Job( const MojoProxyResolverFactoryImpl::Factory& proxy_resolver_factory, mojo::InterfaceRequest<interfaces::ProxyResolver> request, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) : parent_(factory), host_resolver_(new HostResolverMojo( @@ -144,6 +149,7 @@ MojoProxyResolverFactoryImpl::Job::Job( 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_))), client_ptr_(client.Pass()) { @@ -195,13 +201,14 @@ void MojoProxyResolverFactoryImpl::CreateResolver( const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> request, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) { // The Job will call RemoveJob on |this| when either the create request // finishes or |request| or |client| encounters a connection error. jobs_.insert(new Job( this, ProxyResolverScriptData::FromUTF8(pac_script.To<std::string>()), proxy_resolver_impl_factory_, request.Pass(), host_resolver.Pass(), - client.Pass())); + error_observer.Pass(), client.Pass())); } void MojoProxyResolverFactoryImpl::RemoveJob(Job* job) { diff --git a/net/proxy/mojo_proxy_resolver_factory_impl.h b/net/proxy/mojo_proxy_resolver_factory_impl.h index 29bc653..bf652b7 100644 --- a/net/proxy/mojo_proxy_resolver_factory_impl.h +++ b/net/proxy/mojo_proxy_resolver_factory_impl.h @@ -14,12 +14,14 @@ namespace net { class HostResolver; +class ProxyResolverErrorObserver; class ProxyResolverFactory; class MojoProxyResolverFactoryImpl : public interfaces::ProxyResolverFactory { public: using Factory = base::Callback<scoped_ptr<net::ProxyResolverFactory>( HostResolver*, + scoped_ptr<ProxyResolverErrorObserver>, const ProxyResolver::LoadStateChangedCallback&)>; explicit MojoProxyResolverFactoryImpl( @@ -38,6 +40,7 @@ class MojoProxyResolverFactoryImpl : public interfaces::ProxyResolverFactory { const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> request, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) override; void RemoveJob(Job* job); diff --git a/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc b/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc index c5fb69b..2fe9d81 100644 --- a/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc +++ b/net/proxy/mojo_proxy_resolver_factory_impl_unittest.cc @@ -7,6 +7,7 @@ #include "base/strings/utf_string_conversions.h" #include "net/base/test_completion_callback.h" #include "net/proxy/mock_proxy_resolver.h" +#include "net/proxy/proxy_resolver_error_observer.h" #include "net/test/event_waiter.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" @@ -75,6 +76,7 @@ class MojoProxyResolverFactoryImplTest scoped_ptr<ProxyResolverFactory> CreateFakeProxyResolverFactory( HostResolver* host_resolver, + scoped_ptr<ProxyResolverErrorObserver> error_observer, const ProxyResolver::LoadStateChangedCallback& callback) { EXPECT_TRUE(host_resolver); EXPECT_FALSE(callback.is_null()); @@ -105,12 +107,14 @@ TEST_F(MojoProxyResolverFactoryImplTest, DisconnectHostResolver) { interfaces::HostResolverPtr host_resolver; mojo::InterfaceRequest<interfaces::HostResolver> host_resolver_request = mojo::GetProxy(&host_resolver); + interfaces::ProxyResolverErrorObserverPtr error_observer; + mojo::GetProxy(&error_observer); interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; mojo::Binding<ProxyResolverFactoryRequestClient> client_binding( this, mojo::GetProxy(&client_ptr)); - factory_->CreateResolver(mojo::String::From(kScriptData), - mojo::GetProxy(&proxy_resolver), - host_resolver.Pass(), client_ptr.Pass()); + factory_->CreateResolver( + mojo::String::From(kScriptData), mojo::GetProxy(&proxy_resolver), + host_resolver.Pass(), error_observer.Pass(), client_ptr.Pass()); proxy_resolver.set_error_handler(this); waiter_.WaitForEvent(RESOLVER_CREATED); EXPECT_EQ(0, instances_destroyed_); @@ -136,12 +140,14 @@ TEST_F(MojoProxyResolverFactoryImplTest, DisconnectProxyResolverClient) { mojo::GetProxy(&host_resolver); mojo::Binding<interfaces::HostResolver> binding(nullptr, &host_resolver); binding.set_error_handler(this); + interfaces::ProxyResolverErrorObserverPtr error_observer; + mojo::GetProxy(&error_observer); interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; mojo::Binding<ProxyResolverFactoryRequestClient> client_binding( this, mojo::GetProxy(&client_ptr)); - factory_->CreateResolver(mojo::String::From(kScriptData), - mojo::GetProxy(&proxy_resolver), - host_resolver.Pass(), client_ptr.Pass()); + factory_->CreateResolver( + mojo::String::From(kScriptData), mojo::GetProxy(&proxy_resolver), + host_resolver.Pass(), error_observer.Pass(), client_ptr.Pass()); proxy_resolver.set_error_handler(this); waiter_.WaitForEvent(RESOLVER_CREATED); EXPECT_EQ(0, instances_destroyed_); @@ -165,12 +171,14 @@ TEST_F(MojoProxyResolverFactoryImplTest, DisconnectBoth) { interfaces::HostResolverPtr host_resolver; mojo::InterfaceRequest<interfaces::HostResolver> host_resolver_request = mojo::GetProxy(&host_resolver); + interfaces::ProxyResolverErrorObserverPtr error_observer; + mojo::GetProxy(&error_observer); interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; mojo::Binding<ProxyResolverFactoryRequestClient> client_binding( this, mojo::GetProxy(&client_ptr)); - factory_->CreateResolver(mojo::String::From(kScriptData), - mojo::GetProxy(&proxy_resolver), - host_resolver.Pass(), client_ptr.Pass()); + factory_->CreateResolver( + mojo::String::From(kScriptData), mojo::GetProxy(&proxy_resolver), + host_resolver.Pass(), error_observer.Pass(), client_ptr.Pass()); proxy_resolver.set_error_handler(this); waiter_.WaitForEvent(RESOLVER_CREATED); EXPECT_EQ(0, instances_destroyed_); @@ -195,12 +203,14 @@ TEST_F(MojoProxyResolverFactoryImplTest, Error) { interfaces::HostResolverPtr host_resolver; mojo::InterfaceRequest<interfaces::HostResolver> host_resolver_request = mojo::GetProxy(&host_resolver); + interfaces::ProxyResolverErrorObserverPtr error_observer; + mojo::GetProxy(&error_observer); interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; mojo::Binding<ProxyResolverFactoryRequestClient> client_binding( this, mojo::GetProxy(&client_ptr)); - factory_->CreateResolver(mojo::String::From(kScriptData), - mojo::GetProxy(&proxy_resolver), - host_resolver.Pass(), client_ptr.Pass()); + factory_->CreateResolver( + mojo::String::From(kScriptData), mojo::GetProxy(&proxy_resolver), + host_resolver.Pass(), error_observer.Pass(), client_ptr.Pass()); proxy_resolver.set_error_handler(this); waiter_.WaitForEvent(RESOLVER_CREATED); EXPECT_EQ(0, instances_destroyed_); @@ -220,12 +230,14 @@ TEST_F(MojoProxyResolverFactoryImplTest, interfaces::HostResolverPtr host_resolver; mojo::InterfaceRequest<interfaces::HostResolver> host_resolver_request = mojo::GetProxy(&host_resolver); + interfaces::ProxyResolverErrorObserverPtr error_observer; + mojo::GetProxy(&error_observer); interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; mojo::Binding<ProxyResolverFactoryRequestClient> client_binding( this, mojo::GetProxy(&client_ptr)); - factory_->CreateResolver(mojo::String::From(kScriptData), - mojo::GetProxy(&proxy_resolver), - host_resolver.Pass(), client_ptr.Pass()); + factory_->CreateResolver( + mojo::String::From(kScriptData), mojo::GetProxy(&proxy_resolver), + host_resolver.Pass(), error_observer.Pass(), client_ptr.Pass()); proxy_resolver.set_error_handler(this); waiter_.WaitForEvent(RESOLVER_CREATED); EXPECT_EQ(0, instances_destroyed_); @@ -247,12 +259,14 @@ TEST_F(MojoProxyResolverFactoryImplTest, mojo::GetProxy(&host_resolver); mojo::Binding<interfaces::HostResolver> binding(nullptr, &host_resolver); binding.set_error_handler(this); + interfaces::ProxyResolverErrorObserverPtr error_observer; + mojo::GetProxy(&error_observer); interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; mojo::Binding<ProxyResolverFactoryRequestClient> client_binding( this, mojo::GetProxy(&client_ptr)); - factory_->CreateResolver(mojo::String::From(kScriptData), - mojo::GetProxy(&proxy_resolver), - host_resolver.Pass(), client_ptr.Pass()); + factory_->CreateResolver( + mojo::String::From(kScriptData), mojo::GetProxy(&proxy_resolver), + host_resolver.Pass(), error_observer.Pass(), client_ptr.Pass()); proxy_resolver.set_error_handler(this); waiter_.WaitForEvent(RESOLVER_CREATED); EXPECT_EQ(0, instances_destroyed_); @@ -271,12 +285,14 @@ TEST_F(MojoProxyResolverFactoryImplTest, mojo::GetProxy(&host_resolver); mojo::Binding<interfaces::HostResolver> binding(nullptr, &host_resolver); binding.set_error_handler(this); + interfaces::ProxyResolverErrorObserverPtr error_observer; + mojo::GetProxy(&error_observer); interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; mojo::Binding<ProxyResolverFactoryRequestClient> client_binding( this, mojo::GetProxy(&client_ptr)); - factory_->CreateResolver(mojo::String::From(kScriptData), - mojo::GetProxy(&proxy_resolver), - host_resolver.Pass(), client_ptr.Pass()); + factory_->CreateResolver( + mojo::String::From(kScriptData), mojo::GetProxy(&proxy_resolver), + host_resolver.Pass(), error_observer.Pass(), client_ptr.Pass()); proxy_resolver.set_error_handler(this); client_binding.set_error_handler(this); waiter_.WaitForEvent(RESOLVER_CREATED); diff --git a/net/proxy/proxy_resolver_error_observer_mojo.cc b/net/proxy/proxy_resolver_error_observer_mojo.cc new file mode 100644 index 0000000..a63d5d9 --- /dev/null +++ b/net/proxy/proxy_resolver_error_observer_mojo.cc @@ -0,0 +1,46 @@ +// 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_error_observer_mojo.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/thread_task_runner_handle.h" +#include "mojo/common/common_type_converters.h" + +namespace net { + +// static +scoped_ptr<ProxyResolverErrorObserver> ProxyResolverErrorObserverMojo::Create( + interfaces::ProxyResolverErrorObserverPtr error_observer) { + if (!error_observer) + return nullptr; + + return scoped_ptr<ProxyResolverErrorObserver>( + new ProxyResolverErrorObserverMojo(error_observer.Pass())); +} + +void ProxyResolverErrorObserverMojo::OnPACScriptError( + int line_number, + const base::string16& error) { + if (!task_runner_->RunsTasksOnCurrentThread()) { + task_runner_->PostTask( + FROM_HERE, base::Bind(&ProxyResolverErrorObserverMojo::OnPACScriptError, + weak_this_, line_number, error)); + return; + } + error_observer_->OnPacScriptError(line_number, mojo::String::From(error)); +} + +ProxyResolverErrorObserverMojo::ProxyResolverErrorObserverMojo( + interfaces::ProxyResolverErrorObserverPtr error_observer) + : error_observer_(error_observer.Pass()), + task_runner_(base::ThreadTaskRunnerHandle::Get()), + weak_factory_(this) { + weak_this_ = weak_factory_.GetWeakPtr(); +} + +ProxyResolverErrorObserverMojo::~ProxyResolverErrorObserverMojo() = default; + +} // namespace net diff --git a/net/proxy/proxy_resolver_error_observer_mojo.h b/net/proxy/proxy_resolver_error_observer_mojo.h new file mode 100644 index 0000000..95a8ff9 --- /dev/null +++ b/net/proxy/proxy_resolver_error_observer_mojo.h @@ -0,0 +1,43 @@ +// 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_ERROR_OBSERVER_MOJO_H_ +#define NET_PROXY_PROXY_RESOLVER_ERROR_OBSERVER_MOJO_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" +#include "net/interfaces/proxy_resolver_service.mojom.h" +#include "net/proxy/proxy_resolver_error_observer.h" + +namespace net { + +// An implementation of ProxyResolverErrorObserver that forwards errors to an +// interfaces::ProxyResolverErrorObserver mojo interface. +class ProxyResolverErrorObserverMojo : public ProxyResolverErrorObserver { + public: + static scoped_ptr<ProxyResolverErrorObserver> Create( + interfaces::ProxyResolverErrorObserverPtr error_observer); + + void OnPACScriptError(int line_number, const base::string16& error) override; + + private: + explicit ProxyResolverErrorObserverMojo( + interfaces::ProxyResolverErrorObserverPtr error_observer); + ~ProxyResolverErrorObserverMojo() override; + + // |error_observer_| may only be accessed when running on |task_runner_|. + interfaces::ProxyResolverErrorObserverPtr error_observer_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + // Creating a new WeakPtr is only valid on the original thread, but copying an + // existing WeakPtr is valid on any thread so keep |weak_this_| ready to copy. + base::WeakPtr<ProxyResolverErrorObserverMojo> weak_this_; + base::WeakPtrFactory<ProxyResolverErrorObserverMojo> weak_factory_; +}; + +} // namespace net + +#endif // NET_PROXY_PROXY_RESOLVER_ERROR_OBSERVER_MOJO_H_ diff --git a/net/proxy/proxy_resolver_error_observer_mojo_unittest.cc b/net/proxy/proxy_resolver_error_observer_mojo_unittest.cc new file mode 100644 index 0000000..d28bd05 --- /dev/null +++ b/net/proxy/proxy_resolver_error_observer_mojo_unittest.cc @@ -0,0 +1,103 @@ +// 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_error_observer_mojo.h" + +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/strings/utf_string_conversions.h" +#include "base/threading/thread.h" +#include "mojo/common/common_type_converters.h" +#include "net/test/event_waiter.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { +namespace { + +class ErrorObserverClient : public interfaces::ProxyResolverErrorObserver { + public: + enum Event { + ERROR_RECEIVED, + }; + + explicit ErrorObserverClient( + mojo::InterfaceRequest<interfaces::ProxyResolverErrorObserver> request); + + EventWaiter<Event>& event_waiter() { return event_waiter_; } + const std::vector<std::pair<int, base::string16>>& errors() const { + return errors_; + } + + private: + void OnPacScriptError(int32_t line_number, + const mojo::String& error) override; + + mojo::Binding<interfaces::ProxyResolverErrorObserver> binding_; + EventWaiter<Event> event_waiter_; + std::vector<std::pair<int, base::string16>> errors_; + + DISALLOW_COPY_AND_ASSIGN(ErrorObserverClient); +}; + +ErrorObserverClient::ErrorObserverClient( + mojo::InterfaceRequest<interfaces::ProxyResolverErrorObserver> request) + : binding_(this, request.Pass()) { +} + +void ErrorObserverClient::OnPacScriptError(int32_t line_number, + const mojo::String& error) { + errors_.push_back(std::make_pair(line_number, error.To<base::string16>())); + event_waiter_.NotifyEvent(ERROR_RECEIVED); +} + +} // namespace + +class ProxyResolverErrorObserverMojoTest : public testing::Test { + public: + ProxyResolverErrorObserver& error_observer() { return *error_observer_; } + ErrorObserverClient& client() { return *client_; } + + private: + void SetUp() override { + interfaces::ProxyResolverErrorObserverPtr error_observer_ptr; + client_.reset(new ErrorObserverClient(mojo::GetProxy(&error_observer_ptr))); + error_observer_ = + ProxyResolverErrorObserverMojo::Create(error_observer_ptr.Pass()); + ASSERT_TRUE(error_observer_); + } + + scoped_ptr<ErrorObserverClient> client_; + scoped_ptr<ProxyResolverErrorObserver> error_observer_; +}; + +TEST_F(ProxyResolverErrorObserverMojoTest, NullHandle) { + EXPECT_FALSE(ProxyResolverErrorObserverMojo::Create( + interfaces::ProxyResolverErrorObserverPtr())); +} + +TEST_F(ProxyResolverErrorObserverMojoTest, ErrorReportedOnMainThread) { + base::string16 error(base::ASCIIToUTF16("error message")); + error_observer().OnPACScriptError(123, error); + client().event_waiter().WaitForEvent(ErrorObserverClient::ERROR_RECEIVED); + ASSERT_EQ(1u, client().errors().size()); + EXPECT_EQ(123, client().errors()[0].first); + EXPECT_EQ(error, client().errors()[0].second); +} + +TEST_F(ProxyResolverErrorObserverMojoTest, ErrorReportedOnAnotherThread) { + base::Thread other_thread("error reporting thread"); + base::string16 error(base::ASCIIToUTF16("error message")); + other_thread.Start(); + other_thread.message_loop()->PostTask( + FROM_HERE, base::Bind(&ProxyResolverErrorObserver::OnPACScriptError, + base::Unretained(&error_observer()), 123, error)); + client().event_waiter().WaitForEvent(ErrorObserverClient::ERROR_RECEIVED); + ASSERT_EQ(1u, client().errors().size()); + EXPECT_EQ(123, client().errors()[0].first); + EXPECT_EQ(error, client().errors()[0].second); +} + +} // namespace net diff --git a/net/proxy/proxy_resolver_mojo.cc b/net/proxy/proxy_resolver_mojo.cc index c676827..c0e38fb 100644 --- a/net/proxy/proxy_resolver_mojo.cc +++ b/net/proxy/proxy_resolver_mojo.cc @@ -4,20 +4,123 @@ #include "net/proxy/proxy_resolver_mojo.h" +#include <set> + #include "base/bind.h" #include "base/logging.h" #include "base/stl_util.h" +#include "base/threading/thread_checker.h" #include "mojo/common/common_type_converters.h" #include "mojo/common/url_type_converters.h" +#include "net/base/load_states.h" #include "net/base/net_errors.h" #include "net/dns/mojo_host_resolver_impl.h" +#include "net/interfaces/host_resolver_service.mojom.h" +#include "net/interfaces/proxy_resolver_service.mojom.h" #include "net/proxy/mojo_proxy_resolver_factory.h" #include "net/proxy/mojo_proxy_type_converters.h" #include "net/proxy/proxy_info.h" +#include "net/proxy/proxy_resolver.h" +#include "net/proxy/proxy_resolver_error_observer.h" +#include "net/proxy/proxy_resolver_script_data.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" namespace net { +namespace { + +class ErrorObserverHolder : public interfaces::ProxyResolverErrorObserver { + public: + ErrorObserverHolder( + scoped_ptr<net::ProxyResolverErrorObserver> error_observer, + mojo::InterfaceRequest<interfaces::ProxyResolverErrorObserver> request); + ~ErrorObserverHolder() override; + + void OnPacScriptError(int32_t line_number, + const mojo::String& error) override; + + private: + scoped_ptr<net::ProxyResolverErrorObserver> error_observer_; + mojo::Binding<interfaces::ProxyResolverErrorObserver> binding_; + + DISALLOW_COPY_AND_ASSIGN(ErrorObserverHolder); +}; + +ErrorObserverHolder::ErrorObserverHolder( + scoped_ptr<net::ProxyResolverErrorObserver> error_observer, + mojo::InterfaceRequest<interfaces::ProxyResolverErrorObserver> request) + : error_observer_(error_observer.Pass()), binding_(this, request.Pass()) { +} + +ErrorObserverHolder::~ErrorObserverHolder() = default; + +void ErrorObserverHolder::OnPacScriptError(int32_t line_number, + const mojo::String& error) { + DCHECK(error_observer_); + error_observer_->OnPACScriptError(line_number, error.To<base::string16>()); +} + +// Implementation of ProxyResolver that connects to a Mojo service to evaluate +// PAC scripts. This implementation only knows about Mojo services, and +// therefore that service may live in or out of process. +// +// This implementation reports disconnections from the Mojo service (i.e. if the +// service is out-of-process and that process crashes) using the error code +// ERR_PAC_SCRIPT_TERMINATED. +class ProxyResolverMojo : public ProxyResolver, public mojo::ErrorHandler { + public: + // Constructs a ProxyResolverMojo that connects to a mojo proxy resolver + // implementation using |resolver_ptr|. The implementation uses + // |host_resolver| as the DNS resolver, using |host_resolver_binding| to + // communicate with it. When deleted, the closure contained within + // |on_delete_callback_runner| will be run. + // TODO(amistry): Add NetLog. + ProxyResolverMojo( + interfaces::ProxyResolverPtr resolver_ptr, + scoped_ptr<interfaces::HostResolver> host_resolver, + scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding, + scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner, + scoped_ptr<ErrorObserverHolder> error_observer); + ~ProxyResolverMojo() override; + + // ProxyResolver implementation: + int GetProxyForURL(const GURL& url, + ProxyInfo* results, + const net::CompletionCallback& callback, + RequestHandle* request, + const BoundNetLog& net_log) override; + void CancelRequest(RequestHandle request) override; + LoadState GetLoadState(RequestHandle request) const override; + void CancelSetPacScript() override; + int SetPacScript(const scoped_refptr<ProxyResolverScriptData>& pac_script, + const net::CompletionCallback& callback) override; + + private: + class Job; + + // Overridden from mojo::ErrorHandler: + void OnConnectionError() override; + + void RemoveJob(Job* job); + + // Connection to the Mojo proxy resolver. + interfaces::ProxyResolverPtr mojo_proxy_resolver_ptr_; + + // Mojo host resolver service and binding. + scoped_ptr<interfaces::HostResolver> mojo_host_resolver_; + scoped_ptr<mojo::Binding<interfaces::HostResolver>> + mojo_host_resolver_binding_; + + scoped_ptr<ErrorObserverHolder> error_observer_; + + std::set<Job*> pending_jobs_; + + base::ThreadChecker thread_checker_; + + scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_; + + DISALLOW_COPY_AND_ASSIGN(ProxyResolverMojo); +}; class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient, public mojo::ErrorHandler { @@ -114,11 +217,13 @@ ProxyResolverMojo::ProxyResolverMojo( interfaces::ProxyResolverPtr resolver_ptr, scoped_ptr<interfaces::HostResolver> host_resolver, scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding, - scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner) + scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner, + scoped_ptr<ErrorObserverHolder> error_observer) : ProxyResolver(true), mojo_proxy_resolver_ptr_(resolver_ptr.Pass()), mojo_host_resolver_(host_resolver.Pass()), mojo_host_resolver_binding_(host_resolver_binding.Pass()), + error_observer_(error_observer.Pass()), on_delete_callback_runner_(on_delete_callback_runner.Pass()) { mojo_proxy_resolver_ptr_.set_error_handler(this); } @@ -187,6 +292,8 @@ LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const { return job->load_state(); } +} // namespace + class ProxyResolverFactoryMojo::Job : public interfaces::ProxyResolverFactoryRequestClient, public mojo::ErrorHandler, @@ -205,11 +312,20 @@ class ProxyResolverFactoryMojo::Job new mojo::Binding<interfaces::HostResolver>(host_resolver_.get())) { interfaces::HostResolverPtr host_resolver_ptr; interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; + interfaces::ProxyResolverErrorObserverPtr error_observer_ptr; binding_.Bind(mojo::GetProxy(&client_ptr)); + if (!factory_->error_observer_factory_.is_null()) { + scoped_ptr<ProxyResolverErrorObserver> error_observer = + factory_->error_observer_factory_.Run(); + if (error_observer) { + error_observer_.reset(new ErrorObserverHolder( + error_observer.Pass(), mojo::GetProxy(&error_observer_ptr))); + } + } host_resolver_binding_->Bind(mojo::GetProxy(&host_resolver_ptr)); on_delete_callback_runner_ = factory_->mojo_proxy_factory_->CreateResolver( mojo::String::From(pac_script->utf16()), mojo::GetProxy(&resolver_ptr_), - host_resolver_ptr.Pass(), client_ptr.Pass()); + host_resolver_ptr.Pass(), error_observer_ptr.Pass(), client_ptr.Pass()); resolver_ptr_.set_error_handler(this); binding_.set_error_handler(this); } @@ -226,7 +342,8 @@ class ProxyResolverFactoryMojo::Job if (error == OK) { resolver_->reset(new ProxyResolverMojo( resolver_ptr_.Pass(), host_resolver_.Pass(), - host_resolver_binding_.Pass(), on_delete_callback_runner_.Pass())); + host_resolver_binding_.Pass(), on_delete_callback_runner_.Pass(), + error_observer_.Pass())); } on_delete_callback_runner_.reset(); callback_.Run(error); @@ -240,14 +357,18 @@ class ProxyResolverFactoryMojo::Job scoped_ptr<interfaces::HostResolver> host_resolver_; scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding_; scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_; + scoped_ptr<ErrorObserverHolder> error_observer_; }; ProxyResolverFactoryMojo::ProxyResolverFactoryMojo( MojoProxyResolverFactory* mojo_proxy_factory, - HostResolver* host_resolver) + HostResolver* host_resolver, + const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>& + error_observer_factory) : ProxyResolverFactory(true), mojo_proxy_factory_(mojo_proxy_factory), - host_resolver_(host_resolver) { + host_resolver_(host_resolver), + error_observer_factory_(error_observer_factory) { } ProxyResolverFactoryMojo::~ProxyResolverFactoryMojo() = default; diff --git a/net/proxy/proxy_resolver_mojo.h b/net/proxy/proxy_resolver_mojo.h index ada4352..7c82746 100644 --- a/net/proxy/proxy_resolver_mojo.h +++ b/net/proxy/proxy_resolver_mojo.h @@ -5,95 +5,27 @@ #ifndef NET_PROXY_PROXY_RESOLVER_MOJO_H_ #define NET_PROXY_PROXY_RESOLVER_MOJO_H_ -#include <set> - -#include "base/callback_helpers.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/threading/thread_checker.h" #include "net/base/completion_callback.h" -#include "net/base/load_states.h" -#include "net/interfaces/host_resolver_service.mojom.h" -#include "net/interfaces/proxy_resolver_service.mojom.h" -#include "net/proxy/proxy_resolver.h" #include "net/proxy/proxy_resolver_factory.h" -#include "net/proxy/proxy_resolver_script_data.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" -class GURL; - namespace net { - -class BoundNetLog; class HostResolver; -class ProxyInfo; +class ProxyResolverErrorObserver; +class ProxyResolverScriptData; class MojoProxyResolverFactory; -// Implementation of ProxyResolver that connects to a Mojo service to evaluate -// PAC scripts. This implementation only knows about Mojo services, and -// therefore that service may live in or out of process. -// -// This implementation reports disconnections from the Mojo service (i.e. if the -// service is out-of-process and that process crashes) using the error code -// ERR_PAC_SCRIPT_TERMINATED. -class ProxyResolverMojo : public ProxyResolver, public mojo::ErrorHandler { - public: - // Constructs a ProxyResolverMojo that connects to a mojo proxy resolver - // implementation using |resolver_ptr|. The implementation uses - // |host_resolver| as the DNS resolver, using |host_resolver_binding| to - // communicate with it. When deleted, the closure contained within - // |on_delete_callback_runner| will be run. - // TODO(amistry): Add ProxyResolverErrorObserver and NetLog. - ProxyResolverMojo( - interfaces::ProxyResolverPtr resolver_ptr, - scoped_ptr<interfaces::HostResolver> host_resolver, - scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding, - scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner); - ~ProxyResolverMojo() override; - - // ProxyResolver implementation: - int GetProxyForURL(const GURL& url, - ProxyInfo* results, - const net::CompletionCallback& callback, - RequestHandle* request, - const BoundNetLog& net_log) override; - void CancelRequest(RequestHandle request) override; - LoadState GetLoadState(RequestHandle request) const override; - void CancelSetPacScript() override; - int SetPacScript(const scoped_refptr<ProxyResolverScriptData>& pac_script, - const net::CompletionCallback& callback) override; - - private: - class Job; - - // Overridden from mojo::ErrorHandler: - void OnConnectionError() override; - - void RemoveJob(Job* job); - - // Connection to the Mojo proxy resolver. - interfaces::ProxyResolverPtr mojo_proxy_resolver_ptr_; - - // Mojo host resolver service and binding. - scoped_ptr<interfaces::HostResolver> mojo_host_resolver_; - scoped_ptr<mojo::Binding<interfaces::HostResolver>> - mojo_host_resolver_binding_; - - std::set<Job*> pending_jobs_; - - base::ThreadChecker thread_checker_; - - scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_; - - DISALLOW_COPY_AND_ASSIGN(ProxyResolverMojo); -}; - // Implementation of ProxyResolverFactory that connects to a Mojo service to // create implementations of a Mojo proxy resolver to back a ProxyResolverMojo. class ProxyResolverFactoryMojo : public ProxyResolverFactory { public: - ProxyResolverFactoryMojo(MojoProxyResolverFactory* mojo_proxy_factory, - HostResolver* host_resolver); + ProxyResolverFactoryMojo( + MojoProxyResolverFactory* mojo_proxy_factory, + HostResolver* host_resolver, + const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>& + error_observer_factory); ~ProxyResolverFactoryMojo() override; // ProxyResolverFactory override. @@ -108,6 +40,8 @@ class ProxyResolverFactoryMojo : public ProxyResolverFactory { MojoProxyResolverFactory* const mojo_proxy_factory_; HostResolver* const host_resolver_; + const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()> + error_observer_factory_; DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactoryMojo); }; diff --git a/net/proxy/proxy_resolver_mojo_unittest.cc b/net/proxy/proxy_resolver_mojo_unittest.cc index 83bdf00..a99e755 100644 --- a/net/proxy/proxy_resolver_mojo_unittest.cc +++ b/net/proxy/proxy_resolver_mojo_unittest.cc @@ -15,12 +15,15 @@ #include "base/run_loop.h" #include "base/stl_util.h" #include "mojo/common/common_type_converters.h" +#include "net/base/load_states.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" #include "net/log/net_log.h" #include "net/proxy/mojo_proxy_resolver_factory.h" #include "net/proxy/mojo_proxy_type_converters.h" #include "net/proxy/proxy_info.h" +#include "net/proxy/proxy_resolver.h" +#include "net/proxy/proxy_resolver_error_observer.h" #include "net/proxy/proxy_resolver_script_data.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" @@ -316,6 +319,7 @@ class MockMojoProxyResolverFactory : public interfaces::ProxyResolverFactory { const mojo::String& pac_url, mojo::InterfaceRequest<interfaces::ProxyResolver> request, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) override; void WakeWaiter(); @@ -368,6 +372,7 @@ void MockMojoProxyResolverFactory::CreateResolver( const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> request, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) { ASSERT_FALSE(create_resolver_actions_.empty()); CreateProxyResolverAction action = create_resolver_actions_.front(); @@ -409,8 +414,9 @@ class ProxyResolverMojoTest : public testing::Test, void SetUp() override { mock_proxy_resolver_factory_.reset(new MockMojoProxyResolverFactory( &mock_proxy_resolver_, mojo::GetProxy(&factory_ptr_))); - proxy_resolver_factory_mojo_.reset( - new ProxyResolverFactoryMojo(this, nullptr)); + proxy_resolver_factory_mojo_.reset(new ProxyResolverFactoryMojo( + this, nullptr, + base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>())); } scoped_ptr<Request> MakeRequest(const GURL& url) { @@ -421,9 +427,10 @@ class ProxyResolverMojoTest : public testing::Test, const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> req, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) override { factory_ptr_->CreateResolver(pac_script, req.Pass(), host_resolver.Pass(), - client.Pass()); + error_observer.Pass(), client.Pass()); return make_scoped_ptr( new base::ScopedClosureRunner(on_delete_callback_.closure())); } diff --git a/net/proxy/proxy_service_mojo.cc b/net/proxy/proxy_service_mojo.cc index 86da99a..fe81853 100644 --- a/net/proxy/proxy_service_mojo.cc +++ b/net/proxy/proxy_service_mojo.cc @@ -5,11 +5,13 @@ #include "net/proxy/proxy_service_mojo.h" #include "base/logging.h" +#include "base/message_loop/message_loop_proxy.h" #include "net/dns/mojo_host_resolver_impl.h" #include "net/interfaces/proxy_resolver_service.mojom.h" #include "net/proxy/in_process_mojo_proxy_resolver_factory.h" #include "net/proxy/mojo_proxy_resolver_factory.h" #include "net/proxy/mojo_proxy_resolver_impl.h" +#include "net/proxy/network_delegate_error_observer.h" #include "net/proxy/proxy_resolver_factory.h" #include "net/proxy/proxy_resolver_mojo.h" #include "net/proxy/proxy_resolver_v8_tracing.h" @@ -31,8 +33,11 @@ ProxyService* CreateProxyServiceUsingMojoFactory( DCHECK(host_resolver); ProxyService* proxy_service = new ProxyService( - proxy_config_service, make_scoped_ptr(new ProxyResolverFactoryMojo( - mojo_proxy_factory, host_resolver)), + proxy_config_service, + make_scoped_ptr(new ProxyResolverFactoryMojo( + mojo_proxy_factory, host_resolver, + base::Bind(&NetworkDelegateErrorObserver::Create, network_delegate, + base::MessageLoopProxy::current()))), net_log); // Configure fetchers to use for PAC script downloads and auto-detect. diff --git a/net/proxy/proxy_service_mojo_unittest.cc b/net/proxy/proxy_service_mojo_unittest.cc index 5caf2a5..334bafa 100644 --- a/net/proxy/proxy_service_mojo_unittest.cc +++ b/net/proxy/proxy_service_mojo_unittest.cc @@ -8,7 +8,9 @@ #include "base/callback_helpers.h" #include "base/memory/scoped_ptr.h" +#include "base/strings/utf_string_conversions.h" #include "net/base/load_flags.h" +#include "net/base/network_delegate_impl.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" #include "net/log/net_log.h" @@ -18,6 +20,7 @@ #include "net/proxy/mojo_proxy_resolver_factory.h" #include "net/proxy/proxy_config_service_fixed.h" #include "net/proxy/proxy_service.h" +#include "net/test/event_waiter.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -36,6 +39,31 @@ const char kDnsResolvePacScript[] = " return 'DIRECT';\n" " return 'QUIC bar:4321';\n" "}"; +const char kErrorPacScript[] = + "function FindProxyForURL(url, host) {\n" + " throw new Error('test error');\n" + "}"; + +class TestNetworkDelegate : public NetworkDelegateImpl { + public: + enum Event { + PAC_SCRIPT_ERROR, + }; + + EventWaiter<Event>& event_waiter() { return event_waiter_; } + + void OnPACScriptError(int line_number, const base::string16& error) override; + + private: + EventWaiter<Event> event_waiter_; +}; + +void TestNetworkDelegate::OnPACScriptError(int line_number, + const base::string16& error) { + event_waiter_.NotifyEvent(PAC_SCRIPT_ERROR); + EXPECT_EQ(2, line_number); + EXPECT_TRUE(base::UTF16ToUTF8(error).find("test error") != std::string::npos); +} } // namespace @@ -50,20 +78,23 @@ class ProxyServiceMojoTest : public testing::Test, this, new ProxyConfigServiceFixed( ProxyConfig::CreateFromCustomPacURL(GURL(kPacUrl))), fetcher_, new DoNothingDhcpProxyScriptFetcher(), &mock_host_resolver_, - nullptr /* NetLog* */, nullptr /* NetworkDelegate* */)); + nullptr /* NetLog* */, &network_delegate_)); } scoped_ptr<base::ScopedClosureRunner> CreateResolver( const mojo::String& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> req, interfaces::HostResolverPtr host_resolver, + interfaces::ProxyResolverErrorObserverPtr error_observer, interfaces::ProxyResolverFactoryRequestClientPtr client) override { InProcessMojoProxyResolverFactory::GetInstance()->CreateResolver( - pac_script, req.Pass(), host_resolver.Pass(), client.Pass()); + pac_script, req.Pass(), host_resolver.Pass(), error_observer.Pass(), + client.Pass()); return make_scoped_ptr( new base::ScopedClosureRunner(on_delete_closure_.closure())); } + TestNetworkDelegate network_delegate_; MockHostResolver mock_host_resolver_; MockProxyScriptFetcher* fetcher_; // Owned by |proxy_service_|. scoped_ptr<ProxyService> proxy_service_; @@ -112,4 +143,22 @@ TEST_F(ProxyServiceMojoTest, DnsResolution) { on_delete_closure_.WaitForResult(); } +TEST_F(ProxyServiceMojoTest, Error) { + ProxyInfo info; + TestCompletionCallback callback; + EXPECT_EQ(ERR_IO_PENDING, + proxy_service_->ResolveProxy(GURL("http://foo"), LOAD_NORMAL, &info, + callback.callback(), nullptr, nullptr, + BoundNetLog())); + + // Proxy script fetcher should have a fetch triggered by the first + // |ResolveProxy()| request. + EXPECT_TRUE(fetcher_->has_pending_request()); + EXPECT_EQ(GURL(kPacUrl), fetcher_->pending_request_url()); + fetcher_->NotifyFetchCompletion(OK, kErrorPacScript); + + network_delegate_.event_waiter().WaitForEvent( + TestNetworkDelegate::PAC_SCRIPT_ERROR); +} + } // namespace net |