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

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: Lazily connect to Mojo service and don't automatically set PAC script when reconnecting. 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 ReportResult(ERR_PAC_SCRIPT_FAILED,
Sam McNally 2015/03/02 02:43:05 Why report ERR_PAC_SCRIPT_FAILED here? Shouldn't t
Anand Mistry (off Chromium) 2015/03/02 06:44:00 Honestly, I've flip-flopped between the two and ca
84 mojo::Array<interfaces::ProxyServerPtr>());
85 }
86
87 void ProxyResolverMojo::Job::ReportResult(
88 int32_t error,
89 mojo::Array<interfaces::ProxyServerPtr> proxy_servers) {
90 DCHECK(thread_checker_.CalledOnValidThread());
91 DVLOG(1) << "ProxyResolverMojo::Job::ReportResult: " << error;
92
93 if (error == OK) {
94 *results_ = proxy_servers.To<ProxyInfo>();
95 DVLOG(1) << "Servers: " << results_->ToPacString();
96 }
97
98 callback_.Run(error);
99 callback_.Reset();
100 resolver_->RemoveJob(this);
101 }
102
103 ProxyResolverMojo::ProxyResolverMojo(
104 MojoProxyResolverFactory* mojo_proxy_resolver_factory,
105 HostResolver* host_resolver)
106 : ProxyResolver(true /* |expects_pac_bytes| */),
107 mojo_proxy_resolver_factory_(mojo_proxy_resolver_factory),
108 host_resolver_(host_resolver) {
109 }
110
111 ProxyResolverMojo::~ProxyResolverMojo() {
112 DCHECK(thread_checker_.CalledOnValidThread());
113 // All pending requests should have been cancelled.
114 DCHECK(pending_jobs_.empty());
115 DCHECK(set_pac_script_callback_.IsCancelled());
116 }
117
118 void ProxyResolverMojo::CancelSetPacScript() {
119 DCHECK(thread_checker_.CalledOnValidThread());
120 set_pac_script_callback_.Cancel();
121 }
122
123 int ProxyResolverMojo::SetPacScript(
124 const scoped_refptr<ProxyResolverScriptData>& pac_script,
125 const net::CompletionCallback& callback) {
126 DCHECK(thread_checker_.CalledOnValidThread());
127 DCHECK(set_pac_script_callback_.IsCancelled());
128 DCHECK(!callback.is_null());
129 if (pac_script->type() != ProxyResolverScriptData::TYPE_SCRIPT_CONTENTS ||
130 pac_script->utf16().empty()) {
131 return ERR_PAC_SCRIPT_FAILED;
132 }
133
134 DVLOG(1) << "ProxyResolverMojo::SetPacScript: " << pac_script->utf16();
135 set_pac_script_callback_.Reset(
136 base::Bind(&ProxyResolverMojo::OnSetPacScriptDone, base::Unretained(this),
137 pac_script, callback));
138
139 if (!mojo_proxy_resolver_ptr_)
140 SetUpServices();
141
142 mojo_proxy_resolver_ptr_->SetPacScript(
143 mojo::String::From(pac_script->utf16()),
144 set_pac_script_callback_.callback());
145
146 return ERR_IO_PENDING;
147 }
148
149 void ProxyResolverMojo::OnSetPacScriptDone(
150 const scoped_refptr<ProxyResolverScriptData>& pac_script,
151 const net::CompletionCallback& callback,
152 int32_t result) {
153 DCHECK(thread_checker_.CalledOnValidThread());
154 DCHECK(!set_pac_script_callback_.IsCancelled());
155 DVLOG(1) << "ProxyResolverMojo::OnSetPacScriptDone: " << result;
156
157 callback.Run(result);
158 set_pac_script_callback_.Cancel();
159 }
160
161 void ProxyResolverMojo::SetUpServices() {
162 DCHECK(thread_checker_.CalledOnValidThread());
163 // A Mojo service implementation must outlive its binding.
164 mojo_host_resolver_binding_.reset();
165
166 interfaces::HostResolverPtr mojo_host_resolver_ptr;
167 mojo_host_resolver_.reset(new MojoHostResolverImpl(host_resolver_));
168 mojo_host_resolver_binding_.reset(new mojo::Binding<interfaces::HostResolver>(
169 mojo_host_resolver_.get(), mojo::GetProxy(&mojo_host_resolver_ptr)));
170 mojo_proxy_resolver_ptr_.reset();
171 mojo_proxy_resolver_factory_->Create(
172 mojo::GetProxy(&mojo_proxy_resolver_ptr_), mojo_host_resolver_ptr.Pass());
173 mojo_proxy_resolver_ptr_.set_error_handler(this);
174 }
175
176 void ProxyResolverMojo::CancelPendingRequests() {
177 DCHECK(thread_checker_.CalledOnValidThread());
178 if (!set_pac_script_callback_.IsCancelled()) {
179 set_pac_script_callback_.callback().Run(ERR_PAC_SCRIPT_TERMINATED);
180 set_pac_script_callback_.Cancel();
181 }
182
183 // Need to use this loop because deleting a Job will cause its callback to be
184 // run with a failure error code, which may cause other Jobs to be deleted.
185 while (!pending_jobs_.empty()) {
186 auto it = pending_jobs_.begin();
187 Job* job = *it;
188 pending_jobs_.erase(it);
189
190 delete job;
191 }
192 }
193
194 void ProxyResolverMojo::OnConnectionError() {
195 DCHECK(thread_checker_.CalledOnValidThread());
196 DVLOG(1) << "ProxyResolverMojo::OnConnectionError";
197 CancelPendingRequests();
198
199 // Disconnect from the Mojo proxy resolver service. An attempt to reconnect
200 // will happen on the next request.
Sam McNally 2015/03/02 02:43:05 next SetPacScript request.
Anand Mistry (off Chromium) 2015/03/02 06:44:00 Done.
201 mojo_proxy_resolver_ptr_.reset();
202 }
203
204 void ProxyResolverMojo::RemoveJob(Job* job) {
205 DCHECK(thread_checker_.CalledOnValidThread());
206 size_t num_erased = pending_jobs_.erase(job);
207 DCHECK(num_erased);
208 delete job;
209 }
210
211 int ProxyResolverMojo::GetProxyForURL(const GURL& url,
212 ProxyInfo* results,
213 const net::CompletionCallback& callback,
214 RequestHandle* request,
215 const BoundNetLog& net_log) {
216 DCHECK(thread_checker_.CalledOnValidThread());
217
218 // If the Mojo service is not connected, fail. The Mojo service is connected
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 process
Sam McNally 2015/03/02 02:43:05 How about "proxy resolver process"?
Anand Mistry (off Chromium) 2015/03/02 06:44:00 Done.
221 // crashing.
222 if (!mojo_proxy_resolver_ptr_) {
223 DVLOG(1) << "ProxyResolverMojo::GetProxyForURL: Mojo not connected";
224 return ERR_PAC_SCRIPT_TERMINATED;
225 }
226
227 Job* job = new Job(this, url, results, callback);
228 bool inserted = pending_jobs_.insert(job).second;
229 DCHECK(inserted);
230 *request = job;
231
232 return ERR_IO_PENDING;
233 }
234
235 void ProxyResolverMojo::CancelRequest(RequestHandle request) {
236 DCHECK(thread_checker_.CalledOnValidThread());
237 Job* job = static_cast<Job*>(request);
238 DCHECK(job);
239 job->Cancel();
240 RemoveJob(job);
241 }
242
243 LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const {
244 // TODO(amistry): Implement real LoadState.
245 return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
246 }
247
248 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698