| // 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/mojo_proxy_resolver_factory_impl.h" |
| |
| #include <string> |
| #include <utility> |
| |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/stl_util.h" |
| #include "net/base/net_errors.h" |
| #include "net/proxy/mojo_proxy_resolver_impl.h" |
| #include "net/proxy/mojo_proxy_resolver_v8_tracing_bindings.h" |
| #include "net/proxy/proxy_resolver_factory.h" |
| #include "net/proxy/proxy_resolver_v8_tracing.h" |
| |
| namespace net { |
| namespace { |
| |
| // A class to manage the lifetime of a MojoProxyResolverImpl. An instance will |
| // remain while the message pipe for the mojo connection remains open. |
| class MojoProxyResolverHolder { |
| public: |
| MojoProxyResolverHolder( |
| std::unique_ptr<ProxyResolverV8Tracing> proxy_resolver_impl, |
| mojo::InterfaceRequest<interfaces::ProxyResolver> request); |
| |
| private: |
| // Mojo error handler. |
| void OnConnectionError(); |
| |
| MojoProxyResolverImpl mojo_proxy_resolver_; |
| mojo::Binding<interfaces::ProxyResolver> binding_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MojoProxyResolverHolder); |
| }; |
| |
| MojoProxyResolverHolder::MojoProxyResolverHolder( |
| std::unique_ptr<ProxyResolverV8Tracing> proxy_resolver_impl, |
| mojo::InterfaceRequest<interfaces::ProxyResolver> request) |
| : mojo_proxy_resolver_(std::move(proxy_resolver_impl)), |
| binding_(&mojo_proxy_resolver_, std::move(request)) { |
| binding_.set_connection_error_handler(base::Bind( |
| &MojoProxyResolverHolder::OnConnectionError, base::Unretained(this))); |
| } |
| |
| void MojoProxyResolverHolder::OnConnectionError() { |
| delete this; |
| } |
| |
| } // namespace |
| |
| class MojoProxyResolverFactoryImpl::Job { |
| public: |
| Job(MojoProxyResolverFactoryImpl* parent, |
| const scoped_refptr<ProxyResolverScriptData>& pac_script, |
| ProxyResolverV8TracingFactory* proxy_resolver_factory, |
| mojo::InterfaceRequest<interfaces::ProxyResolver> request, |
| interfaces::ProxyResolverFactoryRequestClientPtr client); |
| ~Job(); |
| |
| private: |
| // Mojo error handler. |
| void OnConnectionError(); |
| |
| void OnProxyResolverCreated(int error); |
| |
| MojoProxyResolverFactoryImpl* const parent_; |
| std::unique_ptr<ProxyResolverV8Tracing> proxy_resolver_impl_; |
| mojo::InterfaceRequest<interfaces::ProxyResolver> proxy_request_; |
| ProxyResolverV8TracingFactory* factory_; |
| std::unique_ptr<net::ProxyResolverFactory::Request> request_; |
| interfaces::ProxyResolverFactoryRequestClientPtr client_ptr_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Job); |
| }; |
| |
| MojoProxyResolverFactoryImpl::Job::Job( |
| MojoProxyResolverFactoryImpl* factory, |
| const scoped_refptr<ProxyResolverScriptData>& pac_script, |
| ProxyResolverV8TracingFactory* proxy_resolver_factory, |
| mojo::InterfaceRequest<interfaces::ProxyResolver> request, |
| interfaces::ProxyResolverFactoryRequestClientPtr client) |
| : parent_(factory), |
| proxy_request_(std::move(request)), |
| factory_(proxy_resolver_factory), |
| client_ptr_(std::move(client)) { |
| client_ptr_.set_connection_error_handler( |
| base::Bind(&MojoProxyResolverFactoryImpl::Job::OnConnectionError, |
| base::Unretained(this))); |
| factory_->CreateProxyResolverV8Tracing( |
| pac_script, |
| base::WrapUnique(new MojoProxyResolverV8TracingBindings< |
| interfaces::ProxyResolverFactoryRequestClient>( |
| client_ptr_.get())), |
| &proxy_resolver_impl_, |
| base::Bind(&MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated, |
| base::Unretained(this)), |
| &request_); |
| } |
| |
| MojoProxyResolverFactoryImpl::Job::~Job() = default; |
| |
| void MojoProxyResolverFactoryImpl::Job::OnConnectionError() { |
| client_ptr_->ReportResult(ERR_PAC_SCRIPT_TERMINATED); |
| parent_->RemoveJob(this); |
| } |
| |
| void MojoProxyResolverFactoryImpl::Job::OnProxyResolverCreated(int error) { |
| if (error == OK) { |
| // The MojoProxyResolverHolder will delete itself if |proxy_request_| |
| // encounters a connection error. |
| new MojoProxyResolverHolder(std::move(proxy_resolver_impl_), |
| std::move(proxy_request_)); |
| } |
| client_ptr_->ReportResult(error); |
| parent_->RemoveJob(this); |
| } |
| |
| MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl( |
| std::unique_ptr<ProxyResolverV8TracingFactory> proxy_resolver_factory, |
| mojo::InterfaceRequest<interfaces::ProxyResolverFactory> request) |
| : proxy_resolver_impl_factory_(std::move(proxy_resolver_factory)), |
| binding_(this, std::move(request)) {} |
| |
| MojoProxyResolverFactoryImpl::MojoProxyResolverFactoryImpl( |
| mojo::InterfaceRequest<interfaces::ProxyResolverFactory> request) |
| : MojoProxyResolverFactoryImpl(ProxyResolverV8TracingFactory::Create(), |
| std::move(request)) {} |
| |
| MojoProxyResolverFactoryImpl::~MojoProxyResolverFactoryImpl() { |
| base::STLDeleteElements(&jobs_); |
| } |
| |
| void MojoProxyResolverFactoryImpl::CreateResolver( |
| const mojo::String& pac_script, |
| mojo::InterfaceRequest<interfaces::ProxyResolver> request, |
| 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_.get(), std::move(request), |
| std::move(client))); |
| } |
| |
| void MojoProxyResolverFactoryImpl::RemoveJob(Job* job) { |
| size_t erased = jobs_.erase(job); |
| DCHECK_EQ(1u, erased); |
| delete job; |
| } |
| |
| } // namespace net |