Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: net/proxy/proxy_resolver_mojo.cc

Issue 917863005: Implementation of ProxyResolver that uses a Mojo service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@sam-v8-pac-utility-proxy
Patch Set: More review comments. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "net/proxy/proxy_resolver_mojo.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/stl_util.h"
10 #include "mojo/common/common_type_converters.h"
11 #include "net/base/net_errors.h"
12 #include "net/dns/mojo_host_resolver_impl.h"
13 #include "net/proxy/mojo_proxy_resolver_factory.h"
14 #include "net/proxy/mojo_proxy_type_converters.h"
15 #include "net/proxy/proxy_info.h"
16 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
17 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
18
19 namespace net {
20
21 class ProxyResolverMojo::Job : public interfaces::ProxyResolverRequestClient,
22 public mojo::ErrorHandler {
23 public:
24 Job(ProxyResolverMojo* resolver,
25 const GURL& url,
26 ProxyInfo* results,
27 const net::CompletionCallback& callback);
28 ~Job() override;
29
30 // Cancels the job and prevents the callback from being run.
31 void Cancel();
32
33 private:
34 // Overridden from mojo::ErrorHandler:
35 void OnConnectionError() override;
36
37 // Overridden from interfaces::ProxyResolverRequestClient:
38 void ReportResult(
39 int32_t error,
40 mojo::Array<interfaces::ProxyServerPtr> proxy_servers) override;
41
42 ProxyResolverMojo* resolver_;
43 const GURL url_;
44 ProxyInfo* results_;
45 net::CompletionCallback callback_;
46
47 base::ThreadChecker thread_checker_;
48 mojo::Binding<interfaces::ProxyResolverRequestClient> binding_;
49 };
50
51 ProxyResolverMojo::Job::Job(ProxyResolverMojo* resolver,
52 const GURL& url,
53 ProxyInfo* results,
54 const net::CompletionCallback& callback)
55 : resolver_(resolver),
56 url_(url),
57 results_(results),
58 callback_(callback),
59 binding_(this) {
60 binding_.set_error_handler(this);
61
62 interfaces::ProxyResolverRequestClientPtr client_ptr;
63 binding_.Bind(mojo::GetProxy(&client_ptr));
64 resolver_->mojo_proxy_resolver_ptr_->GetProxyForUrl(mojo::String::From(url_),
65 client_ptr.Pass());
66 }
67
68 ProxyResolverMojo::Job::~Job() {
69 DCHECK(thread_checker_.CalledOnValidThread());
70 if (!callback_.is_null())
71 callback_.Run(ERR_PAC_SCRIPT_TERMINATED);
72 }
73
74 void ProxyResolverMojo::Job::Cancel() {
75 DCHECK(thread_checker_.CalledOnValidThread());
76 DCHECK(!callback_.is_null());
77 callback_.Reset();
78 }
79
80 void ProxyResolverMojo::Job::OnConnectionError() {
81 DCHECK(thread_checker_.CalledOnValidThread());
82 DVLOG(1) << "ProxyResolverMojo::Job::OnConnectionError";
83 resolver_->RemoveJob(this);
84 }
85
86 void ProxyResolverMojo::Job::ReportResult(
87 int32_t error,
88 mojo::Array<interfaces::ProxyServerPtr> proxy_servers) {
89 DCHECK(thread_checker_.CalledOnValidThread());
90 DVLOG(1) << "ProxyResolverMojo::Job::ReportResult: " << error;
91
92 if (error == OK) {
93 *results_ = proxy_servers.To<ProxyInfo>();
94 DVLOG(1) << "Servers: " << results_->ToPacString();
95 }
96
97 callback_.Run(error);
98 callback_.Reset();
99 resolver_->RemoveJob(this);
100 }
101
102 ProxyResolverMojo::ProxyResolverMojo(
103 MojoProxyResolverFactory* mojo_proxy_resolver_factory,
104 HostResolver* host_resolver)
105 : ProxyResolver(true /* |expects_pac_bytes| */),
106 mojo_proxy_resolver_factory_(mojo_proxy_resolver_factory),
107 host_resolver_(host_resolver) {
108 }
109
110 ProxyResolverMojo::~ProxyResolverMojo() {
111 DCHECK(thread_checker_.CalledOnValidThread());
112 // All pending requests should have been cancelled.
113 DCHECK(pending_jobs_.empty());
114 DCHECK(set_pac_script_callback_.IsCancelled());
115 }
116
117 void ProxyResolverMojo::CancelSetPacScript() {
118 DCHECK(thread_checker_.CalledOnValidThread());
119 set_pac_script_callback_.Cancel();
120 }
121
122 int ProxyResolverMojo::SetPacScript(
123 const scoped_refptr<ProxyResolverScriptData>& pac_script,
124 const net::CompletionCallback& callback) {
125 DCHECK(thread_checker_.CalledOnValidThread());
126 DCHECK(set_pac_script_callback_.IsCancelled());
127 DCHECK(!callback.is_null());
128 if (pac_script->type() != ProxyResolverScriptData::TYPE_SCRIPT_CONTENTS ||
129 pac_script->utf16().empty()) {
130 return ERR_PAC_SCRIPT_FAILED;
131 }
132
133 DVLOG(1) << "ProxyResolverMojo::SetPacScript: " << pac_script->utf16();
134 set_pac_script_callback_.Reset(
135 base::Bind(&ProxyResolverMojo::OnSetPacScriptDone, base::Unretained(this),
136 pac_script, callback));
137
138 if (!mojo_proxy_resolver_ptr_)
139 SetUpServices();
140
141 mojo_proxy_resolver_ptr_->SetPacScript(
142 mojo::String::From(pac_script->utf16()),
143 set_pac_script_callback_.callback());
144
145 return ERR_IO_PENDING;
146 }
147
148 void ProxyResolverMojo::OnSetPacScriptDone(
149 const scoped_refptr<ProxyResolverScriptData>& pac_script,
150 const net::CompletionCallback& callback,
151 int32_t result) {
152 DCHECK(thread_checker_.CalledOnValidThread());
153 DCHECK(!set_pac_script_callback_.IsCancelled());
154 DVLOG(1) << "ProxyResolverMojo::OnSetPacScriptDone: " << result;
155
156 callback.Run(result);
157 set_pac_script_callback_.Cancel();
158 }
159
160 void ProxyResolverMojo::SetUpServices() {
161 DCHECK(thread_checker_.CalledOnValidThread());
162 // A Mojo service implementation must outlive its binding.
163 mojo_host_resolver_binding_.reset();
164
165 interfaces::HostResolverPtr mojo_host_resolver_ptr;
166 mojo_host_resolver_.reset(new MojoHostResolverImpl(host_resolver_));
167 mojo_host_resolver_binding_.reset(new mojo::Binding<interfaces::HostResolver>(
168 mojo_host_resolver_.get(), mojo::GetProxy(&mojo_host_resolver_ptr)));
169 mojo_proxy_resolver_ptr_.reset();
170 mojo_proxy_resolver_factory_->Create(
171 mojo::GetProxy(&mojo_proxy_resolver_ptr_), mojo_host_resolver_ptr.Pass());
172 mojo_proxy_resolver_ptr_.set_error_handler(this);
173 }
174
175 void ProxyResolverMojo::CancelPendingRequests() {
eroman 2015/03/06 04:46:14 nit: Please call this "AbortPendingRequests" or so
Anand Mistry (off Chromium) 2015/03/06 06:53:59 Done.
176 DCHECK(thread_checker_.CalledOnValidThread());
177 if (!set_pac_script_callback_.IsCancelled()) {
178 set_pac_script_callback_.callback().Run(ERR_PAC_SCRIPT_TERMINATED);
179 set_pac_script_callback_.Cancel();
180 }
181
182 // Need to use this loop because deleting a Job will cause its callback to be
183 // run with a failure error code, which may cause other Jobs to be deleted.
184 while (!pending_jobs_.empty()) {
eroman 2015/03/06 04:46:14 This seems incomplete. Running a callback here cou
Anand Mistry (off Chromium) 2015/03/06 06:53:59 The latter issue of setting up the new connection
185 auto it = pending_jobs_.begin();
186 Job* job = *it;
187 pending_jobs_.erase(it);
188
189 delete job;
190 }
191 }
192
193 void ProxyResolverMojo::OnConnectionError() {
194 DCHECK(thread_checker_.CalledOnValidThread());
195 DVLOG(1) << "ProxyResolverMojo::OnConnectionError";
196 CancelPendingRequests();
197
198 // Disconnect from the Mojo proxy resolver service. An attempt to reconnect
199 // will happen on the next |SetPacScript()| request.
200 mojo_proxy_resolver_ptr_.reset();
201 }
202
203 void ProxyResolverMojo::RemoveJob(Job* job) {
204 DCHECK(thread_checker_.CalledOnValidThread());
205 size_t num_erased = pending_jobs_.erase(job);
206 DCHECK(num_erased);
207 delete job;
208 }
209
210 int ProxyResolverMojo::GetProxyForURL(const GURL& url,
211 ProxyInfo* results,
212 const net::CompletionCallback& callback,
213 RequestHandle* request,
214 const BoundNetLog& net_log) {
215 DCHECK(thread_checker_.CalledOnValidThread());
216
217 // If the Mojo service is not connected, fail. The Mojo service is connected
218 // when the script is set, which must be done after construction and after a
219 // previous request returns ERR_PAC_SCRIPT_TERMINATED due to the Mojo proxy
220 // resolver process crashing.
221 if (!mojo_proxy_resolver_ptr_) {
222 DVLOG(1) << "ProxyResolverMojo::GetProxyForURL: Mojo not connected";
223 return ERR_PAC_SCRIPT_TERMINATED;
224 }
225
226 Job* job = new Job(this, url, results, callback);
227 bool inserted = pending_jobs_.insert(job).second;
228 DCHECK(inserted);
229 *request = job;
230
231 return ERR_IO_PENDING;
232 }
233
234 void ProxyResolverMojo::CancelRequest(RequestHandle request) {
235 DCHECK(thread_checker_.CalledOnValidThread());
236 Job* job = static_cast<Job*>(request);
237 DCHECK(job);
238 job->Cancel();
239 RemoveJob(job);
240 }
241
242 LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const {
243 // TODO(amistry): Implement real LoadState.
244 return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
245 }
246
247 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698