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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "mojo/common/common_type_converters.h" | 10 #include "mojo/common/common_type_converters.h" |
11 #include "mojo/common/url_type_converters.h" | 11 #include "mojo/common/url_type_converters.h" |
12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
13 #include "net/dns/mojo_host_resolver_impl.h" | 13 #include "net/dns/mojo_host_resolver_impl.h" |
14 #include "net/proxy/mojo_proxy_resolver_factory.h" | |
15 #include "net/proxy/mojo_proxy_type_converters.h" | 14 #include "net/proxy/mojo_proxy_type_converters.h" |
16 #include "net/proxy/proxy_info.h" | 15 #include "net/proxy/proxy_info.h" |
17 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" | 16 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" |
18 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" | 17 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" |
19 | 18 |
20 namespace net { | 19 namespace net { |
21 | 20 |
22 class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient, | 21 class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient, |
23 public mojo::ErrorHandler { | 22 public mojo::ErrorHandler { |
24 public: | 23 public: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 callback_.Reset(); | 103 callback_.Reset(); |
105 resolver_->RemoveJob(this); | 104 resolver_->RemoveJob(this); |
106 callback.Run(error); | 105 callback.Run(error); |
107 } | 106 } |
108 | 107 |
109 void ProxyResolverMojo::Job::LoadStateChanged(int32_t load_state) { | 108 void ProxyResolverMojo::Job::LoadStateChanged(int32_t load_state) { |
110 load_state_ = static_cast<LoadState>(load_state); | 109 load_state_ = static_cast<LoadState>(load_state); |
111 } | 110 } |
112 | 111 |
113 ProxyResolverMojo::ProxyResolverMojo( | 112 ProxyResolverMojo::ProxyResolverMojo( |
114 MojoProxyResolverFactory* mojo_proxy_resolver_factory, | 113 interfaces::ProxyResolverPtr mojo_proxy_resolver, |
115 HostResolver* host_resolver) | 114 HostResolver* host_resolver, |
| 115 mojo::InterfaceRequest<interfaces::HostResolver> host_resolver_request, |
| 116 scoped_ptr<base::ScopedClosureRunner> runner) |
116 : ProxyResolver(true /* |expects_pac_bytes| */), | 117 : ProxyResolver(true /* |expects_pac_bytes| */), |
117 mojo_proxy_resolver_factory_(mojo_proxy_resolver_factory), | 118 mojo_proxy_resolver_ptr_(mojo_proxy_resolver.Pass()), |
118 host_resolver_(host_resolver) { | 119 host_resolver_(host_resolver), |
| 120 host_resolver_binding_(&host_resolver_, host_resolver_request.Pass()), |
| 121 runner_(runner.Pass()) { |
| 122 mojo_proxy_resolver_ptr_.set_error_handler(this); |
119 } | 123 } |
120 | 124 |
121 ProxyResolverMojo::~ProxyResolverMojo() { | 125 ProxyResolverMojo::~ProxyResolverMojo() { |
122 DCHECK(thread_checker_.CalledOnValidThread()); | 126 DCHECK(thread_checker_.CalledOnValidThread()); |
123 // All pending requests should have been cancelled. | 127 // All pending requests should have been cancelled. |
124 DCHECK(pending_jobs_.empty()); | 128 DCHECK(pending_jobs_.empty()); |
125 DCHECK(set_pac_script_callback_.IsCancelled()); | 129 DCHECK(set_pac_script_callback_.IsCancelled()); |
126 } | 130 } |
127 | 131 |
128 void ProxyResolverMojo::CancelSetPacScript() { | 132 void ProxyResolverMojo::CancelSetPacScript() { |
(...skipping 11 matching lines...) Expand all Loading... |
140 pac_script->utf16().empty()) { | 144 pac_script->utf16().empty()) { |
141 return ERR_PAC_SCRIPT_FAILED; | 145 return ERR_PAC_SCRIPT_FAILED; |
142 } | 146 } |
143 | 147 |
144 DVLOG(1) << "ProxyResolverMojo::SetPacScript: " << pac_script->utf16(); | 148 DVLOG(1) << "ProxyResolverMojo::SetPacScript: " << pac_script->utf16(); |
145 set_pac_script_callback_.Reset( | 149 set_pac_script_callback_.Reset( |
146 base::Bind(&ProxyResolverMojo::OnSetPacScriptDone, base::Unretained(this), | 150 base::Bind(&ProxyResolverMojo::OnSetPacScriptDone, base::Unretained(this), |
147 pac_script, callback)); | 151 pac_script, callback)); |
148 | 152 |
149 if (!mojo_proxy_resolver_ptr_) | 153 if (!mojo_proxy_resolver_ptr_) |
150 SetUpServices(); | 154 return ERR_PAC_SCRIPT_TERMINATED; |
151 | 155 |
152 mojo_proxy_resolver_ptr_->SetPacScript( | 156 mojo_proxy_resolver_ptr_->SetPacScript( |
153 mojo::String::From(pac_script->utf16()), | 157 mojo::String::From(pac_script->utf16()), |
154 set_pac_script_callback_.callback()); | 158 set_pac_script_callback_.callback()); |
155 | 159 |
156 return ERR_IO_PENDING; | 160 return ERR_IO_PENDING; |
157 } | 161 } |
158 | 162 |
159 void ProxyResolverMojo::OnSetPacScriptDone( | 163 void ProxyResolverMojo::OnSetPacScriptDone( |
160 const scoped_refptr<ProxyResolverScriptData>& pac_script, | 164 const scoped_refptr<ProxyResolverScriptData>& pac_script, |
161 const net::CompletionCallback& callback, | 165 const net::CompletionCallback& callback, |
162 int32_t result) { | 166 int32_t result) { |
163 DCHECK(thread_checker_.CalledOnValidThread()); | 167 DCHECK(thread_checker_.CalledOnValidThread()); |
164 DCHECK(!set_pac_script_callback_.IsCancelled()); | 168 DCHECK(!set_pac_script_callback_.IsCancelled()); |
165 DVLOG(1) << "ProxyResolverMojo::OnSetPacScriptDone: " << result; | 169 DVLOG(1) << "ProxyResolverMojo::OnSetPacScriptDone: " << result; |
166 | 170 |
167 // |callback| is owned by |set_pac_script_callback_|, so make a copy before | 171 // |callback| is owned by |set_pac_script_callback_|, so make a copy before |
168 // cancelling. | 172 // cancelling. |
169 auto callback_copy = callback; | 173 auto callback_copy = callback; |
170 set_pac_script_callback_.Cancel(); | 174 set_pac_script_callback_.Cancel(); |
171 callback_copy.Run(result); | 175 callback_copy.Run(result); |
172 } | 176 } |
173 | 177 |
174 void ProxyResolverMojo::SetUpServices() { | |
175 DCHECK(thread_checker_.CalledOnValidThread()); | |
176 // A Mojo service implementation must outlive its binding. | |
177 mojo_host_resolver_binding_.reset(); | |
178 | |
179 interfaces::HostResolverPtr mojo_host_resolver_ptr; | |
180 mojo_host_resolver_.reset(new MojoHostResolverImpl(host_resolver_)); | |
181 mojo_host_resolver_binding_.reset(new mojo::Binding<interfaces::HostResolver>( | |
182 mojo_host_resolver_.get(), mojo::GetProxy(&mojo_host_resolver_ptr))); | |
183 mojo_proxy_resolver_ptr_.reset(); | |
184 mojo_proxy_resolver_factory_->Create( | |
185 mojo::GetProxy(&mojo_proxy_resolver_ptr_), mojo_host_resolver_ptr.Pass()); | |
186 mojo_proxy_resolver_ptr_.set_error_handler(this); | |
187 } | |
188 | |
189 void ProxyResolverMojo::OnConnectionError() { | 178 void ProxyResolverMojo::OnConnectionError() { |
190 DCHECK(thread_checker_.CalledOnValidThread()); | 179 DCHECK(thread_checker_.CalledOnValidThread()); |
191 DVLOG(1) << "ProxyResolverMojo::OnConnectionError"; | 180 DVLOG(1) << "ProxyResolverMojo::OnConnectionError"; |
192 | 181 |
193 // Disconnect from the Mojo proxy resolver service. An attempt to reconnect | 182 // Disconnect from the Mojo proxy resolver service. An attempt to reconnect |
194 // will happen on the next |SetPacScript()| request. | 183 // will happen on the next |SetPacScript()| request. |
195 mojo_proxy_resolver_ptr_.reset(); | 184 mojo_proxy_resolver_ptr_.reset(); |
196 | 185 |
197 // This callback may call |SetPacScript()| and re-create the connection. So | 186 // This callback may call |SetPacScript()| and re-create the connection. So |
198 // disconnect from the Mojo service (above) before aborting the pending | 187 // disconnect from the Mojo service (above) before aborting the pending |
199 // request. | 188 // request. |
200 if (!set_pac_script_callback_.IsCancelled()) | 189 if (!set_pac_script_callback_.IsCancelled()) |
201 set_pac_script_callback_.callback().Run(ERR_PAC_SCRIPT_TERMINATED); | 190 set_pac_script_callback_.callback().Run(ERR_PAC_SCRIPT_TERMINATED); |
202 } | 191 } |
203 | 192 |
204 void ProxyResolverMojo::RemoveJob(Job* job) { | 193 void ProxyResolverMojo::RemoveJob(Job* job) { |
205 DCHECK(thread_checker_.CalledOnValidThread()); | 194 DCHECK(thread_checker_.CalledOnValidThread()); |
206 size_t num_erased = pending_jobs_.erase(job); | 195 size_t num_erased = pending_jobs_.erase(job); |
207 DCHECK(num_erased); | 196 DCHECK(num_erased); |
208 delete job; | 197 delete job; |
209 } | 198 } |
210 | 199 |
211 int ProxyResolverMojo::GetProxyForURL(const GURL& url, | 200 int ProxyResolverMojo::GetProxyForURL(const GURL& url, |
212 ProxyInfo* results, | 201 ProxyInfo* results, |
213 const net::CompletionCallback& callback, | 202 const net::CompletionCallback& callback, |
214 RequestHandle* request, | 203 RequestHandle* request, |
215 const BoundNetLog& net_log) { | 204 const BoundNetLog& net_log) { |
216 DCHECK(thread_checker_.CalledOnValidThread()); | 205 DCHECK(thread_checker_.CalledOnValidThread()); |
217 | 206 |
218 // If the Mojo service is not connected, fail. The Mojo service is connected | 207 if (!mojo_proxy_resolver_ptr_) |
219 // when the script is set, which must be done after construction and after a | |
220 // previous request returns ERR_PAC_SCRIPT_TERMINATED due to the Mojo proxy | |
221 // resolver process crashing. | |
222 if (!mojo_proxy_resolver_ptr_) { | |
223 DVLOG(1) << "ProxyResolverMojo::GetProxyForURL: Mojo not connected"; | |
224 return ERR_PAC_SCRIPT_TERMINATED; | 208 return ERR_PAC_SCRIPT_TERMINATED; |
225 } | |
226 | 209 |
227 Job* job = new Job(this, url, results, callback); | 210 Job* job = new Job(this, url, results, callback); |
228 bool inserted = pending_jobs_.insert(job).second; | 211 bool inserted = pending_jobs_.insert(job).second; |
229 DCHECK(inserted); | 212 DCHECK(inserted); |
230 *request = job; | 213 *request = job; |
231 | 214 |
232 return ERR_IO_PENDING; | 215 return ERR_IO_PENDING; |
233 } | 216 } |
234 | 217 |
235 void ProxyResolverMojo::CancelRequest(RequestHandle request) { | 218 void ProxyResolverMojo::CancelRequest(RequestHandle request) { |
236 DCHECK(thread_checker_.CalledOnValidThread()); | 219 DCHECK(thread_checker_.CalledOnValidThread()); |
237 Job* job = static_cast<Job*>(request); | 220 Job* job = static_cast<Job*>(request); |
238 DCHECK(job); | 221 DCHECK(job); |
239 job->Cancel(); | 222 job->Cancel(); |
240 RemoveJob(job); | 223 RemoveJob(job); |
241 } | 224 } |
242 | 225 |
243 LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const { | 226 LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const { |
244 Job* job = static_cast<Job*>(request); | 227 Job* job = static_cast<Job*>(request); |
245 CHECK_EQ(1u, pending_jobs_.count(job)); | 228 CHECK_EQ(1u, pending_jobs_.count(job)); |
246 return job->load_state(); | 229 return job->load_state(); |
247 } | 230 } |
248 | 231 |
249 } // namespace net | 232 } // namespace net |
OLD | NEW |