OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/proxy/proxy_resolver_mojo.h" | 5 #include "net/proxy/proxy_resolver_mojo.h" |
6 | 6 |
| 7 #include <set> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/logging.h" | 10 #include "base/logging.h" |
9 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/threading/thread_checker.h" |
10 #include "mojo/common/common_type_converters.h" | 13 #include "mojo/common/common_type_converters.h" |
11 #include "mojo/common/url_type_converters.h" | 14 #include "mojo/common/url_type_converters.h" |
| 15 #include "net/base/load_states.h" |
12 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
13 #include "net/dns/mojo_host_resolver_impl.h" | 17 #include "net/dns/mojo_host_resolver_impl.h" |
| 18 #include "net/interfaces/host_resolver_service.mojom.h" |
| 19 #include "net/interfaces/proxy_resolver_service.mojom.h" |
14 #include "net/proxy/mojo_proxy_resolver_factory.h" | 20 #include "net/proxy/mojo_proxy_resolver_factory.h" |
15 #include "net/proxy/mojo_proxy_type_converters.h" | 21 #include "net/proxy/mojo_proxy_type_converters.h" |
16 #include "net/proxy/proxy_info.h" | 22 #include "net/proxy/proxy_info.h" |
| 23 #include "net/proxy/proxy_resolver.h" |
| 24 #include "net/proxy/proxy_resolver_error_observer.h" |
| 25 #include "net/proxy/proxy_resolver_script_data.h" |
17 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" | 26 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" |
18 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" | 27 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" |
19 | 28 |
20 namespace net { | 29 namespace net { |
| 30 namespace { |
| 31 |
| 32 class ErrorObserverHolder : public interfaces::ProxyResolverErrorObserver { |
| 33 public: |
| 34 ErrorObserverHolder( |
| 35 scoped_ptr<net::ProxyResolverErrorObserver> error_observer, |
| 36 mojo::InterfaceRequest<interfaces::ProxyResolverErrorObserver> request); |
| 37 ~ErrorObserverHolder() override; |
| 38 |
| 39 void OnPacScriptError(int32_t line_number, |
| 40 const mojo::String& error) override; |
| 41 |
| 42 private: |
| 43 scoped_ptr<net::ProxyResolverErrorObserver> error_observer_; |
| 44 mojo::Binding<interfaces::ProxyResolverErrorObserver> binding_; |
| 45 |
| 46 DISALLOW_COPY_AND_ASSIGN(ErrorObserverHolder); |
| 47 }; |
| 48 |
| 49 ErrorObserverHolder::ErrorObserverHolder( |
| 50 scoped_ptr<net::ProxyResolverErrorObserver> error_observer, |
| 51 mojo::InterfaceRequest<interfaces::ProxyResolverErrorObserver> request) |
| 52 : error_observer_(error_observer.Pass()), binding_(this, request.Pass()) { |
| 53 } |
| 54 |
| 55 ErrorObserverHolder::~ErrorObserverHolder() = default; |
| 56 |
| 57 void ErrorObserverHolder::OnPacScriptError(int32_t line_number, |
| 58 const mojo::String& error) { |
| 59 DCHECK(error_observer_); |
| 60 error_observer_->OnPACScriptError(line_number, error.To<base::string16>()); |
| 61 } |
| 62 |
| 63 // Implementation of ProxyResolver that connects to a Mojo service to evaluate |
| 64 // PAC scripts. This implementation only knows about Mojo services, and |
| 65 // therefore that service may live in or out of process. |
| 66 // |
| 67 // This implementation reports disconnections from the Mojo service (i.e. if the |
| 68 // service is out-of-process and that process crashes) using the error code |
| 69 // ERR_PAC_SCRIPT_TERMINATED. |
| 70 class ProxyResolverMojo : public ProxyResolver, public mojo::ErrorHandler { |
| 71 public: |
| 72 // Constructs a ProxyResolverMojo that connects to a mojo proxy resolver |
| 73 // implementation using |resolver_ptr|. The implementation uses |
| 74 // |host_resolver| as the DNS resolver, using |host_resolver_binding| to |
| 75 // communicate with it. When deleted, the closure contained within |
| 76 // |on_delete_callback_runner| will be run. |
| 77 // TODO(amistry): Add NetLog. |
| 78 ProxyResolverMojo( |
| 79 interfaces::ProxyResolverPtr resolver_ptr, |
| 80 scoped_ptr<interfaces::HostResolver> host_resolver, |
| 81 scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding, |
| 82 scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner, |
| 83 scoped_ptr<ErrorObserverHolder> error_observer); |
| 84 ~ProxyResolverMojo() override; |
| 85 |
| 86 // ProxyResolver implementation: |
| 87 int GetProxyForURL(const GURL& url, |
| 88 ProxyInfo* results, |
| 89 const net::CompletionCallback& callback, |
| 90 RequestHandle* request, |
| 91 const BoundNetLog& net_log) override; |
| 92 void CancelRequest(RequestHandle request) override; |
| 93 LoadState GetLoadState(RequestHandle request) const override; |
| 94 void CancelSetPacScript() override; |
| 95 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>& pac_script, |
| 96 const net::CompletionCallback& callback) override; |
| 97 |
| 98 private: |
| 99 class Job; |
| 100 |
| 101 // Overridden from mojo::ErrorHandler: |
| 102 void OnConnectionError() override; |
| 103 |
| 104 void RemoveJob(Job* job); |
| 105 |
| 106 // Connection to the Mojo proxy resolver. |
| 107 interfaces::ProxyResolverPtr mojo_proxy_resolver_ptr_; |
| 108 |
| 109 // Mojo host resolver service and binding. |
| 110 scoped_ptr<interfaces::HostResolver> mojo_host_resolver_; |
| 111 scoped_ptr<mojo::Binding<interfaces::HostResolver>> |
| 112 mojo_host_resolver_binding_; |
| 113 |
| 114 scoped_ptr<ErrorObserverHolder> error_observer_; |
| 115 |
| 116 std::set<Job*> pending_jobs_; |
| 117 |
| 118 base::ThreadChecker thread_checker_; |
| 119 |
| 120 scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_; |
| 121 |
| 122 DISALLOW_COPY_AND_ASSIGN(ProxyResolverMojo); |
| 123 }; |
21 | 124 |
22 class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient, | 125 class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient, |
23 public mojo::ErrorHandler { | 126 public mojo::ErrorHandler { |
24 public: | 127 public: |
25 Job(ProxyResolverMojo* resolver, | 128 Job(ProxyResolverMojo* resolver, |
26 const GURL& url, | 129 const GURL& url, |
27 ProxyInfo* results, | 130 ProxyInfo* results, |
28 const CompletionCallback& callback); | 131 const CompletionCallback& callback); |
29 ~Job() override; | 132 ~Job() override; |
30 | 133 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } | 210 } |
108 | 211 |
109 void ProxyResolverMojo::Job::LoadStateChanged(int32_t load_state) { | 212 void ProxyResolverMojo::Job::LoadStateChanged(int32_t load_state) { |
110 load_state_ = static_cast<LoadState>(load_state); | 213 load_state_ = static_cast<LoadState>(load_state); |
111 } | 214 } |
112 | 215 |
113 ProxyResolverMojo::ProxyResolverMojo( | 216 ProxyResolverMojo::ProxyResolverMojo( |
114 interfaces::ProxyResolverPtr resolver_ptr, | 217 interfaces::ProxyResolverPtr resolver_ptr, |
115 scoped_ptr<interfaces::HostResolver> host_resolver, | 218 scoped_ptr<interfaces::HostResolver> host_resolver, |
116 scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding, | 219 scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding, |
117 scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner) | 220 scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner, |
| 221 scoped_ptr<ErrorObserverHolder> error_observer) |
118 : ProxyResolver(true), | 222 : ProxyResolver(true), |
119 mojo_proxy_resolver_ptr_(resolver_ptr.Pass()), | 223 mojo_proxy_resolver_ptr_(resolver_ptr.Pass()), |
120 mojo_host_resolver_(host_resolver.Pass()), | 224 mojo_host_resolver_(host_resolver.Pass()), |
121 mojo_host_resolver_binding_(host_resolver_binding.Pass()), | 225 mojo_host_resolver_binding_(host_resolver_binding.Pass()), |
| 226 error_observer_(error_observer.Pass()), |
122 on_delete_callback_runner_(on_delete_callback_runner.Pass()) { | 227 on_delete_callback_runner_(on_delete_callback_runner.Pass()) { |
123 mojo_proxy_resolver_ptr_.set_error_handler(this); | 228 mojo_proxy_resolver_ptr_.set_error_handler(this); |
124 } | 229 } |
125 | 230 |
126 ProxyResolverMojo::~ProxyResolverMojo() { | 231 ProxyResolverMojo::~ProxyResolverMojo() { |
127 DCHECK(thread_checker_.CalledOnValidThread()); | 232 DCHECK(thread_checker_.CalledOnValidThread()); |
128 // All pending requests should have been cancelled. | 233 // All pending requests should have been cancelled. |
129 DCHECK(pending_jobs_.empty()); | 234 DCHECK(pending_jobs_.empty()); |
130 } | 235 } |
131 | 236 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 job->Cancel(); | 285 job->Cancel(); |
181 RemoveJob(job); | 286 RemoveJob(job); |
182 } | 287 } |
183 | 288 |
184 LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const { | 289 LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const { |
185 Job* job = static_cast<Job*>(request); | 290 Job* job = static_cast<Job*>(request); |
186 CHECK_EQ(1u, pending_jobs_.count(job)); | 291 CHECK_EQ(1u, pending_jobs_.count(job)); |
187 return job->load_state(); | 292 return job->load_state(); |
188 } | 293 } |
189 | 294 |
| 295 } // namespace |
| 296 |
190 class ProxyResolverFactoryMojo::Job | 297 class ProxyResolverFactoryMojo::Job |
191 : public interfaces::ProxyResolverFactoryRequestClient, | 298 : public interfaces::ProxyResolverFactoryRequestClient, |
192 public mojo::ErrorHandler, | 299 public mojo::ErrorHandler, |
193 public ProxyResolverFactory::Request { | 300 public ProxyResolverFactory::Request { |
194 public: | 301 public: |
195 Job(ProxyResolverFactoryMojo* factory, | 302 Job(ProxyResolverFactoryMojo* factory, |
196 const scoped_refptr<ProxyResolverScriptData>& pac_script, | 303 const scoped_refptr<ProxyResolverScriptData>& pac_script, |
197 scoped_ptr<ProxyResolver>* resolver, | 304 scoped_ptr<ProxyResolver>* resolver, |
198 const CompletionCallback& callback) | 305 const CompletionCallback& callback) |
199 : factory_(factory), | 306 : factory_(factory), |
200 resolver_(resolver), | 307 resolver_(resolver), |
201 callback_(callback), | 308 callback_(callback), |
202 binding_(this), | 309 binding_(this), |
203 host_resolver_(new MojoHostResolverImpl(factory_->host_resolver_)), | 310 host_resolver_(new MojoHostResolverImpl(factory_->host_resolver_)), |
204 host_resolver_binding_( | 311 host_resolver_binding_( |
205 new mojo::Binding<interfaces::HostResolver>(host_resolver_.get())) { | 312 new mojo::Binding<interfaces::HostResolver>(host_resolver_.get())) { |
206 interfaces::HostResolverPtr host_resolver_ptr; | 313 interfaces::HostResolverPtr host_resolver_ptr; |
207 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; | 314 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr; |
| 315 interfaces::ProxyResolverErrorObserverPtr error_observer_ptr; |
208 binding_.Bind(mojo::GetProxy(&client_ptr)); | 316 binding_.Bind(mojo::GetProxy(&client_ptr)); |
| 317 if (!factory_->error_observer_factory_.is_null()) { |
| 318 scoped_ptr<ProxyResolverErrorObserver> error_observer = |
| 319 factory_->error_observer_factory_.Run(); |
| 320 if (error_observer) { |
| 321 error_observer_.reset(new ErrorObserverHolder( |
| 322 error_observer.Pass(), mojo::GetProxy(&error_observer_ptr))); |
| 323 } |
| 324 } |
209 host_resolver_binding_->Bind(mojo::GetProxy(&host_resolver_ptr)); | 325 host_resolver_binding_->Bind(mojo::GetProxy(&host_resolver_ptr)); |
210 on_delete_callback_runner_ = factory_->mojo_proxy_factory_->CreateResolver( | 326 on_delete_callback_runner_ = factory_->mojo_proxy_factory_->CreateResolver( |
211 mojo::String::From(pac_script->utf16()), mojo::GetProxy(&resolver_ptr_), | 327 mojo::String::From(pac_script->utf16()), mojo::GetProxy(&resolver_ptr_), |
212 host_resolver_ptr.Pass(), client_ptr.Pass()); | 328 host_resolver_ptr.Pass(), error_observer_ptr.Pass(), client_ptr.Pass()); |
213 resolver_ptr_.set_error_handler(this); | 329 resolver_ptr_.set_error_handler(this); |
214 binding_.set_error_handler(this); | 330 binding_.set_error_handler(this); |
215 } | 331 } |
216 | 332 |
217 void OnConnectionError() override { | 333 void OnConnectionError() override { |
218 callback_.Run(ERR_PAC_SCRIPT_TERMINATED); | 334 callback_.Run(ERR_PAC_SCRIPT_TERMINATED); |
219 on_delete_callback_runner_.reset(); | 335 on_delete_callback_runner_.reset(); |
220 } | 336 } |
221 | 337 |
222 private: | 338 private: |
223 void ReportResult(int32_t error) override { | 339 void ReportResult(int32_t error) override { |
224 resolver_ptr_.set_error_handler(nullptr); | 340 resolver_ptr_.set_error_handler(nullptr); |
225 binding_.set_error_handler(nullptr); | 341 binding_.set_error_handler(nullptr); |
226 if (error == OK) { | 342 if (error == OK) { |
227 resolver_->reset(new ProxyResolverMojo( | 343 resolver_->reset(new ProxyResolverMojo( |
228 resolver_ptr_.Pass(), host_resolver_.Pass(), | 344 resolver_ptr_.Pass(), host_resolver_.Pass(), |
229 host_resolver_binding_.Pass(), on_delete_callback_runner_.Pass())); | 345 host_resolver_binding_.Pass(), on_delete_callback_runner_.Pass(), |
| 346 error_observer_.Pass())); |
230 } | 347 } |
231 on_delete_callback_runner_.reset(); | 348 on_delete_callback_runner_.reset(); |
232 callback_.Run(error); | 349 callback_.Run(error); |
233 } | 350 } |
234 | 351 |
235 ProxyResolverFactoryMojo* const factory_; | 352 ProxyResolverFactoryMojo* const factory_; |
236 scoped_ptr<ProxyResolver>* resolver_; | 353 scoped_ptr<ProxyResolver>* resolver_; |
237 const CompletionCallback callback_; | 354 const CompletionCallback callback_; |
238 interfaces::ProxyResolverPtr resolver_ptr_; | 355 interfaces::ProxyResolverPtr resolver_ptr_; |
239 mojo::Binding<interfaces::ProxyResolverFactoryRequestClient> binding_; | 356 mojo::Binding<interfaces::ProxyResolverFactoryRequestClient> binding_; |
240 scoped_ptr<interfaces::HostResolver> host_resolver_; | 357 scoped_ptr<interfaces::HostResolver> host_resolver_; |
241 scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding_; | 358 scoped_ptr<mojo::Binding<interfaces::HostResolver>> host_resolver_binding_; |
242 scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_; | 359 scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_; |
| 360 scoped_ptr<ErrorObserverHolder> error_observer_; |
243 }; | 361 }; |
244 | 362 |
245 ProxyResolverFactoryMojo::ProxyResolverFactoryMojo( | 363 ProxyResolverFactoryMojo::ProxyResolverFactoryMojo( |
246 MojoProxyResolverFactory* mojo_proxy_factory, | 364 MojoProxyResolverFactory* mojo_proxy_factory, |
247 HostResolver* host_resolver) | 365 HostResolver* host_resolver, |
| 366 const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>& |
| 367 error_observer_factory) |
248 : ProxyResolverFactory(true), | 368 : ProxyResolverFactory(true), |
249 mojo_proxy_factory_(mojo_proxy_factory), | 369 mojo_proxy_factory_(mojo_proxy_factory), |
250 host_resolver_(host_resolver) { | 370 host_resolver_(host_resolver), |
| 371 error_observer_factory_(error_observer_factory) { |
251 } | 372 } |
252 | 373 |
253 ProxyResolverFactoryMojo::~ProxyResolverFactoryMojo() = default; | 374 ProxyResolverFactoryMojo::~ProxyResolverFactoryMojo() = default; |
254 | 375 |
255 int ProxyResolverFactoryMojo::CreateProxyResolver( | 376 int ProxyResolverFactoryMojo::CreateProxyResolver( |
256 const scoped_refptr<ProxyResolverScriptData>& pac_script, | 377 const scoped_refptr<ProxyResolverScriptData>& pac_script, |
257 scoped_ptr<ProxyResolver>* resolver, | 378 scoped_ptr<ProxyResolver>* resolver, |
258 const CompletionCallback& callback, | 379 const CompletionCallback& callback, |
259 scoped_ptr<ProxyResolverFactory::Request>* request) { | 380 scoped_ptr<ProxyResolverFactory::Request>* request) { |
260 DCHECK(resolver); | 381 DCHECK(resolver); |
261 DCHECK(request); | 382 DCHECK(request); |
262 if (pac_script->type() != ProxyResolverScriptData::TYPE_SCRIPT_CONTENTS || | 383 if (pac_script->type() != ProxyResolverScriptData::TYPE_SCRIPT_CONTENTS || |
263 pac_script->utf16().empty()) { | 384 pac_script->utf16().empty()) { |
264 return ERR_PAC_SCRIPT_FAILED; | 385 return ERR_PAC_SCRIPT_FAILED; |
265 } | 386 } |
266 request->reset(new Job(this, pac_script, resolver, callback)); | 387 request->reset(new Job(this, pac_script, resolver, callback)); |
267 return ERR_IO_PENDING; | 388 return ERR_IO_PENDING; |
268 } | 389 } |
269 | 390 |
270 } // namespace net | 391 } // namespace net |
OLD | NEW |