Port Chromium's blink_tests target to GN.
[chromium-blink-merge.git] / net / proxy / mojo_proxy_resolver_factory_impl.cc
blob9134495ba3f46157ef127657c47730a3a5f7523e
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"
7 #include <string>
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"
18 namespace net {
19 namespace {
21 class DefaultProxyResolverFactory : public LegacyProxyResolverFactory {
22 public:
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,
32 nullptr, callback_));
35 private:
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> {
49 public:
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) {
60 callback_ = callback;
63 private:
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 {
76 public:
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);
84 private:
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() {
112 delete this;
115 } // namespace
117 class MojoProxyResolverFactoryImpl::Job : public mojo::ErrorHandler {
118 public:
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);
125 ~Job() override;
127 private:
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)
152 : parent_(factory),
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)),
169 &request_);
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) {
180 if (error == OK) {
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),
201 request.Pass()) {
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(),
218 client.Pass()));
221 void MojoProxyResolverFactoryImpl::RemoveJob(Job* job) {
222 size_t erased = jobs_.erase(job);
223 DCHECK_EQ(1u, erased);
224 delete job;
227 } // namespace net