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_factory.h"
14 #include "net/proxy/proxy_resolver_v8.h"
15 #include "net/proxy/proxy_resolver_v8_tracing.h"
16 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
21 class DefaultProxyResolverFactory
: public LegacyProxyResolverFactory
{
23 DefaultProxyResolverFactory(
24 HostResolver
* host_resolver
,
25 const ProxyResolver::LoadStateChangedCallback
& callback
)
26 : LegacyProxyResolverFactory(true),
27 host_resolver_(host_resolver
),
28 callback_(callback
) {}
30 scoped_ptr
<ProxyResolver
> CreateProxyResolver() override
{
31 return make_scoped_ptr(new ProxyResolverV8Tracing(host_resolver_
, nullptr,
36 HostResolver
* const host_resolver_
;
37 const ProxyResolver::LoadStateChangedCallback callback_
;
40 scoped_ptr
<ProxyResolverFactory
> CreateDefaultProxyResolver(
41 HostResolver
* host_resolver
,
42 const ProxyResolver::LoadStateChangedCallback
& callback
) {
43 return make_scoped_ptr(
44 new DefaultProxyResolverFactory(host_resolver
, callback
));
47 class LoadStateChangeForwarder
48 : public base::RefCounted
<LoadStateChangeForwarder
> {
50 LoadStateChangeForwarder() = default;
52 void OnLoadStateChanged(ProxyResolver::RequestHandle request_handle
,
53 LoadState load_state
) const {
54 if (!callback_
.is_null())
55 callback_
.Run(request_handle
, load_state
);
58 void set_load_state_changed_callback(
59 const ProxyResolver::LoadStateChangedCallback
& callback
) {
64 friend class base::RefCounted
<LoadStateChangeForwarder
>;
65 ~LoadStateChangeForwarder() = default;
67 ProxyResolver::LoadStateChangedCallback callback_
;
69 DISALLOW_COPY_AND_ASSIGN(LoadStateChangeForwarder
);
72 // A class to manage the lifetime of a MojoProxyResolverImpl and a
73 // HostResolverMojo. An instance will remain while the message pipes for both
74 // mojo connections remain open.
75 class MojoProxyResolverHolder
: public mojo::ErrorHandler
{
77 MojoProxyResolverHolder(
78 scoped_ptr
<HostResolverMojo
> host_resolver
,
79 scoped_ptr
<ProxyResolver
> proxy_resolver_impl
,
80 const scoped_refptr
<LoadStateChangeForwarder
>&
81 load_state_change_forwarder
,
82 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
);
85 // mojo::ErrorHandler override.
86 void OnConnectionError() override
;
88 scoped_ptr
<HostResolverMojo
> host_resolver_
;
89 MojoProxyResolverImpl mojo_proxy_resolver_
;
90 mojo::Binding
<interfaces::ProxyResolver
> binding_
;
92 DISALLOW_COPY_AND_ASSIGN(MojoProxyResolverHolder
);
95 MojoProxyResolverHolder::MojoProxyResolverHolder(
96 scoped_ptr
<HostResolverMojo
> host_resolver
,
97 scoped_ptr
<ProxyResolver
> proxy_resolver_impl
,
98 const scoped_refptr
<LoadStateChangeForwarder
>& load_state_change_forwarder
,
99 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
)
100 : host_resolver_(host_resolver
.Pass()),
101 mojo_proxy_resolver_(
102 proxy_resolver_impl
.Pass(),
103 base::Bind(&LoadStateChangeForwarder::set_load_state_changed_callback
,
104 load_state_change_forwarder
)),
105 binding_(&mojo_proxy_resolver_
, request
.Pass()) {
106 binding_
.set_error_handler(this);
107 host_resolver_
->set_disconnect_callback(base::Bind(
108 &MojoProxyResolverHolder::OnConnectionError
, base::Unretained(this)));
111 void MojoProxyResolverHolder::OnConnectionError() {
117 class MojoProxyResolverFactoryImpl::Job
: public mojo::ErrorHandler
{
119 Job(MojoProxyResolverFactoryImpl
* parent
,
120 const scoped_refptr
<ProxyResolverScriptData
>& pac_script
,
121 const MojoProxyResolverFactoryImpl::Factory
& proxy_resolver_factory
,
122 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
123 interfaces::HostResolverPtr host_resolver
,
124 interfaces::ProxyResolverFactoryRequestClientPtr client
);
128 // mojo::ErrorHandler override.
129 void OnConnectionError() override
;
131 void OnProxyResolverCreated(int error
);
133 MojoProxyResolverFactoryImpl
* const parent_
;
134 scoped_ptr
<HostResolverMojo
> host_resolver_
;
135 scoped_refptr
<LoadStateChangeForwarder
> load_state_change_forwarder_
;
136 scoped_ptr
<ProxyResolver
> proxy_resolver_impl_
;
137 mojo::InterfaceRequest
<interfaces::ProxyResolver
> proxy_request_
;
138 scoped_ptr
<net::ProxyResolverFactory
> factory_
;
139 scoped_ptr
<net::ProxyResolverFactory::Request
> request_
;
140 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr_
;
142 DISALLOW_COPY_AND_ASSIGN(Job
);
145 MojoProxyResolverFactoryImpl::Job::Job(
146 MojoProxyResolverFactoryImpl
* factory
,
147 const scoped_refptr
<ProxyResolverScriptData
>& pac_script
,
148 const MojoProxyResolverFactoryImpl::Factory
& proxy_resolver_factory
,
149 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
150 interfaces::HostResolverPtr host_resolver
,
151 interfaces::ProxyResolverFactoryRequestClientPtr client
)
153 host_resolver_(new HostResolverMojo(
154 host_resolver
.Pass(),
155 base::Bind(&MojoProxyResolverFactoryImpl::Job::OnConnectionError
,
156 base::Unretained(this)))),
157 load_state_change_forwarder_(new LoadStateChangeForwarder
),
158 proxy_request_(request
.Pass()),
159 factory_(proxy_resolver_factory
.Run(
160 host_resolver_
.get(),
161 base::Bind(&LoadStateChangeForwarder::OnLoadStateChanged
,
162 load_state_change_forwarder_
))),
163 client_ptr_(client
.Pass()) {
164 client_ptr_
.set_error_handler(this);
165 factory_
->CreateProxyResolver(
166 pac_script
, &proxy_resolver_impl_
,
167 base::Bind(&MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated
,
168 base::Unretained(this)),
172 MojoProxyResolverFactoryImpl::Job::~Job() = default;
174 void MojoProxyResolverFactoryImpl::Job::OnConnectionError() {
175 client_ptr_
->ReportResult(ERR_PAC_SCRIPT_TERMINATED
);
176 parent_
->RemoveJob(this);
179 void MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated(int error
) {
181 // The MojoProxyResolverHolder will delete itself if either
182 // |host_resolver_| or |proxy_request_| encounters a connection error.
183 new MojoProxyResolverHolder(
184 host_resolver_
.Pass(), proxy_resolver_impl_
.Pass(),
185 load_state_change_forwarder_
, proxy_request_
.Pass());
187 client_ptr_
->ReportResult(error
);
188 parent_
->RemoveJob(this);
191 MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl(
192 const MojoProxyResolverFactoryImpl::Factory
& proxy_resolver_factory
,
193 mojo::InterfaceRequest
<interfaces::ProxyResolverFactory
> request
)
194 : proxy_resolver_impl_factory_(proxy_resolver_factory
),
195 binding_(this, request
.Pass()) {
198 MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl(
199 mojo::InterfaceRequest
<interfaces::ProxyResolverFactory
> request
)
200 : MojoProxyResolverFactoryImpl(base::Bind(&CreateDefaultProxyResolver
),
204 MojoProxyResolverFactoryImpl::~MojoProxyResolverFactoryImpl() {
205 STLDeleteElements(&jobs_
);
208 void MojoProxyResolverFactoryImpl::CreateResolver(
209 const mojo::String
& pac_script
,
210 mojo::InterfaceRequest
<interfaces::ProxyResolver
> request
,
211 interfaces::HostResolverPtr host_resolver
,
212 interfaces::ProxyResolverFactoryRequestClientPtr client
) {
213 // The Job will call RemoveJob on |this| when either the create request
214 // finishes or |request| or |client| encounters a connection error.
215 jobs_
.insert(new Job(
216 this, ProxyResolverScriptData::FromUTF8(pac_script
.To
<std::string
>()),
217 proxy_resolver_impl_factory_
, request
.Pass(), host_resolver
.Pass(),
221 void MojoProxyResolverFactoryImpl::RemoveJob(Job
* job
) {
222 size_t erased
= jobs_
.erase(job
);
223 DCHECK_EQ(1u, erased
);