1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/proxy/mojo_proxy_resolver_factory_impl.h"
9 #include "base/stl_util.h"
10 #include "net/base/net_errors.h"
11 #include "net/dns/host_resolver_mojo.h"
12 #include "net/proxy/mojo_proxy_resolver_impl.h"
13 #include "net/proxy/proxy_resolver_error_observer_mojo.h"
14 #include "net/proxy/proxy_resolver_factory.h"
15 #include "net/proxy/proxy_resolver_v8.h"
16 #include "net/proxy/proxy_resolver_v8_tracing.h"
17 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
22 scoped_ptr
<ProxyResolverErrorObserver
> ReturnErrorObserver(
23 scoped_ptr
<ProxyResolverErrorObserver
> error_observer
) {
24 return error_observer
;
27 scoped_ptr
<ProxyResolverFactory
> CreateDefaultProxyResolver(
28 HostResolver
* host_resolver
,
29 scoped_ptr
<ProxyResolverErrorObserver
> error_observer
,
30 const ProxyResolver::LoadStateChangedCallback
& callback
) {
31 return make_scoped_ptr(new ProxyResolverFactoryV8Tracing(
32 host_resolver
, nullptr, callback
,
33 base::Bind(&ReturnErrorObserver
, base::Passed(&error_observer
))));
36 class LoadStateChangeForwarder
37 : public base::RefCounted
<LoadStateChangeForwarder
> {
39 LoadStateChangeForwarder() = default;
41 void OnLoadStateChanged(ProxyResolver::RequestHandle request_handle
,
42 LoadState load_state
) const {
43 if (!callback_
.is_null())
44 callback_
.Run(request_handle
, load_state
);
47 void set_load_state_changed_callback(
48 const ProxyResolver::LoadStateChangedCallback
& callback
) {
53 friend class base::RefCounted
<LoadStateChangeForwarder
>;
54 ~LoadStateChangeForwarder() = default;
56 ProxyResolver::LoadStateChangedCallback callback_
;
58 DISALLOW_COPY_AND_ASSIGN(LoadStateChangeForwarder
);
61 // A class to manage the lifetime of a MojoProxyResolverImpl and a
62 // HostResolverMojo. An instance will remain while the message pipes for both
63 // mojo connections remain open.
64 class MojoProxyResolverHolder
: public mojo::ErrorHandler
{
66 MojoProxyResolverHolder(
67 scoped_ptr
<HostResolverMojo
> host_resolver
,
68 scoped_ptr
<ProxyResolver
> proxy_resolver_impl
,
69 const scoped_refptr
<LoadStateChangeForwarder
>&
70 load_state_change_forwarder
,
71 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
);
74 // mojo::ErrorHandler override.
75 void OnConnectionError() override
;
77 scoped_ptr
<HostResolverMojo
> host_resolver_
;
78 MojoProxyResolverImpl mojo_proxy_resolver_
;
79 mojo::Binding
<interfaces::ProxyResolver
> binding_
;
81 DISALLOW_COPY_AND_ASSIGN(MojoProxyResolverHolder
);
84 MojoProxyResolverHolder::MojoProxyResolverHolder(
85 scoped_ptr
<HostResolverMojo
> host_resolver
,
86 scoped_ptr
<ProxyResolver
> proxy_resolver_impl
,
87 const scoped_refptr
<LoadStateChangeForwarder
>& load_state_change_forwarder
,
88 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
)
89 : host_resolver_(host_resolver
.Pass()),
91 proxy_resolver_impl
.Pass(),
92 base::Bind(&LoadStateChangeForwarder::set_load_state_changed_callback
,
93 load_state_change_forwarder
)),
94 binding_(&mojo_proxy_resolver_
, request
.Pass()) {
95 binding_
.set_error_handler(this);
96 host_resolver_
->set_disconnect_callback(base::Bind(
97 &MojoProxyResolverHolder::OnConnectionError
, base::Unretained(this)));
100 void MojoProxyResolverHolder::OnConnectionError() {
106 class MojoProxyResolverFactoryImpl::Job
: public mojo::ErrorHandler
{
108 Job(MojoProxyResolverFactoryImpl
* parent
,
109 const scoped_refptr
<ProxyResolverScriptData
>& pac_script
,
110 const MojoProxyResolverFactoryImpl::Factory
& proxy_resolver_factory
,
111 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
112 interfaces::HostResolverPtr host_resolver
,
113 interfaces::ProxyResolverErrorObserverPtr error_observer
,
114 interfaces::ProxyResolverFactoryRequestClientPtr client
);
118 // mojo::ErrorHandler override.
119 void OnConnectionError() override
;
121 void OnProxyResolverCreated(int error
);
123 MojoProxyResolverFactoryImpl
* const parent_
;
124 scoped_ptr
<HostResolverMojo
> host_resolver_
;
125 scoped_refptr
<LoadStateChangeForwarder
> load_state_change_forwarder_
;
126 scoped_ptr
<ProxyResolver
> proxy_resolver_impl_
;
127 mojo::InterfaceRequest
<interfaces::ProxyResolver
> proxy_request_
;
128 scoped_ptr
<net::ProxyResolverFactory
> factory_
;
129 scoped_ptr
<net::ProxyResolverFactory::Request
> request_
;
130 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr_
;
132 DISALLOW_COPY_AND_ASSIGN(Job
);
135 MojoProxyResolverFactoryImpl::Job::Job(
136 MojoProxyResolverFactoryImpl
* factory
,
137 const scoped_refptr
<ProxyResolverScriptData
>& pac_script
,
138 const MojoProxyResolverFactoryImpl::Factory
& proxy_resolver_factory
,
139 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
140 interfaces::HostResolverPtr host_resolver
,
141 interfaces::ProxyResolverErrorObserverPtr error_observer
,
142 interfaces::ProxyResolverFactoryRequestClientPtr client
)
144 host_resolver_(new HostResolverMojo(
145 host_resolver
.Pass(),
146 base::Bind(&MojoProxyResolverFactoryImpl::Job::OnConnectionError
,
147 base::Unretained(this)))),
148 load_state_change_forwarder_(new LoadStateChangeForwarder
),
149 proxy_request_(request
.Pass()),
150 factory_(proxy_resolver_factory
.Run(
151 host_resolver_
.get(),
152 ProxyResolverErrorObserverMojo::Create(error_observer
.Pass()),
153 base::Bind(&LoadStateChangeForwarder::OnLoadStateChanged
,
154 load_state_change_forwarder_
))),
155 client_ptr_(client
.Pass()) {
156 client_ptr_
.set_error_handler(this);
157 factory_
->CreateProxyResolver(
158 pac_script
, &proxy_resolver_impl_
,
159 base::Bind(&MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated
,
160 base::Unretained(this)),
164 MojoProxyResolverFactoryImpl::Job::~Job() = default;
166 void MojoProxyResolverFactoryImpl::Job::OnConnectionError() {
167 client_ptr_
->ReportResult(ERR_PAC_SCRIPT_TERMINATED
);
168 parent_
->RemoveJob(this);
171 void MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated(int error
) {
173 // The MojoProxyResolverHolder will delete itself if either
174 // |host_resolver_| or |proxy_request_| encounters a connection error.
175 new MojoProxyResolverHolder(
176 host_resolver_
.Pass(), proxy_resolver_impl_
.Pass(),
177 load_state_change_forwarder_
, proxy_request_
.Pass());
179 client_ptr_
->ReportResult(error
);
180 parent_
->RemoveJob(this);
183 MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl(
184 const MojoProxyResolverFactoryImpl::Factory
& proxy_resolver_factory
,
185 mojo::InterfaceRequest
<interfaces::ProxyResolverFactory
> request
)
186 : proxy_resolver_impl_factory_(proxy_resolver_factory
),
187 binding_(this, request
.Pass()) {
190 MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl(
191 mojo::InterfaceRequest
<interfaces::ProxyResolverFactory
> request
)
192 : MojoProxyResolverFactoryImpl(base::Bind(&CreateDefaultProxyResolver
),
196 MojoProxyResolverFactoryImpl::~MojoProxyResolverFactoryImpl() {
197 STLDeleteElements(&jobs_
);
200 void MojoProxyResolverFactoryImpl::CreateResolver(
201 const mojo::String
& pac_script
,
202 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
203 interfaces::HostResolverPtr host_resolver
,
204 interfaces::ProxyResolverErrorObserverPtr error_observer
,
205 interfaces::ProxyResolverFactoryRequestClientPtr client
) {
206 // The Job will call RemoveJob on |this| when either the create request
207 // finishes or |request| or |client| encounters a connection error.
208 jobs_
.insert(new Job(
209 this, ProxyResolverScriptData::FromUTF8(pac_script
.To
<std::string
>()),
210 proxy_resolver_impl_factory_
, request
.Pass(), host_resolver
.Pass(),
211 error_observer
.Pass(), client
.Pass()));
214 void MojoProxyResolverFactoryImpl::RemoveJob(Job
* job
) {
215 size_t erased
= jobs_
.erase(job
);
216 DCHECK_EQ(1u, erased
);