OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/base/cert_verifier.h" | 5 #include "net/base/cert_verifier.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/lock.h" | 8 #include "base/lock.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stl_util-inl.h" | 10 #include "base/stl_util-inl.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 // Copies the contents of |verify_result| to the caller's | 102 // Copies the contents of |verify_result| to the caller's |
103 // CertVerifyResult and calls the callback. | 103 // CertVerifyResult and calls the callback. |
104 void Post(const CachedCertVerifyResult& verify_result) { | 104 void Post(const CachedCertVerifyResult& verify_result) { |
105 if (callback_) { | 105 if (callback_) { |
106 *verify_result_ = verify_result.result; | 106 *verify_result_ = verify_result.result; |
107 callback_->Run(verify_result.error); | 107 callback_->Run(verify_result.error); |
108 } | 108 } |
109 delete this; | 109 delete this; |
110 } | 110 } |
111 | 111 |
112 bool canceled() const { return !callback_; } | |
113 | |
112 private: | 114 private: |
113 CompletionCallback* callback_; | 115 CompletionCallback* callback_; |
114 CertVerifyResult* verify_result_; | 116 CertVerifyResult* verify_result_; |
115 }; | 117 }; |
116 | 118 |
117 | 119 |
118 // CertVerifierWorker runs on a worker thread and takes care of the blocking | 120 // CertVerifierWorker runs on a worker thread and takes care of the blocking |
119 // process of performing the certificate verification. Deletes itself | 121 // process of performing the certificate verification. Deletes itself |
120 // eventually if Start() succeeds. | 122 // eventually if Start() succeeds. |
121 class CertVerifierWorker { | 123 class CertVerifierWorker { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 }; | 231 }; |
230 | 232 |
231 // A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It | 233 // A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It |
232 // lives only on the CertVerifier's origin message loop. | 234 // lives only on the CertVerifier's origin message loop. |
233 class CertVerifierJob { | 235 class CertVerifierJob { |
234 public: | 236 public: |
235 explicit CertVerifierJob(CertVerifierWorker* worker) : worker_(worker) { | 237 explicit CertVerifierJob(CertVerifierWorker* worker) : worker_(worker) { |
236 } | 238 } |
237 | 239 |
238 ~CertVerifierJob() { | 240 ~CertVerifierJob() { |
239 if (worker_) | 241 if (worker_) { |
240 worker_->Cancel(); | 242 worker_->Cancel(); |
243 DeleteAllCanceled(); | |
244 } | |
241 } | 245 } |
242 | 246 |
243 void AddRequest(CertVerifierRequest* request) { | 247 void AddRequest(CertVerifierRequest* request) { |
244 requests_.push_back(request); | 248 requests_.push_back(request); |
245 } | 249 } |
246 | 250 |
247 void HandleResult(const CachedCertVerifyResult& verify_result) { | 251 void HandleResult(const CachedCertVerifyResult& verify_result) { |
248 worker_ = NULL; | 252 worker_ = NULL; |
249 PostAll(verify_result); | 253 PostAll(verify_result); |
250 } | 254 } |
251 | 255 |
252 private: | 256 private: |
253 void PostAll(const CachedCertVerifyResult& verify_result) { | 257 void PostAll(const CachedCertVerifyResult& verify_result) { |
254 std::vector<CertVerifierRequest*> requests; | 258 std::vector<CertVerifierRequest*> requests; |
255 requests_.swap(requests); | 259 requests_.swap(requests); |
256 | 260 |
257 for (std::vector<CertVerifierRequest*>::iterator | 261 for (std::vector<CertVerifierRequest*>::iterator |
258 i = requests.begin(); i != requests.end(); i++) { | 262 i = requests.begin(); i != requests.end(); i++) { |
259 (*i)->Post(verify_result); | 263 (*i)->Post(verify_result); |
260 // Post() causes the CertVerifierRequest to delete itself. | 264 // Post() causes the CertVerifierRequest to delete itself. |
261 } | 265 } |
262 } | 266 } |
263 | 267 |
268 void DeleteAllCanceled() { | |
269 for (std::vector<CertVerifierRequest*>::iterator | |
270 i = requests_.begin(); i != requests_.end(); i++) { | |
271 if ((*i)->canceled()) { | |
272 delete *i; | |
273 } else { | |
274 LOG(DFATAL) << "CertVerifierRequest leaked!"; | |
275 } | |
276 } | |
277 } | |
278 | |
264 std::vector<CertVerifierRequest*> requests_; | 279 std::vector<CertVerifierRequest*> requests_; |
265 CertVerifierWorker* worker_; | 280 CertVerifierWorker* worker_; |
266 }; | 281 }; |
267 | 282 |
268 | 283 |
269 CertVerifier::CertVerifier() | 284 CertVerifier::CertVerifier() |
270 : time_service_(new DefaultTimeService), | 285 : time_service_(new DefaultTimeService), |
271 requests_(0), | 286 requests_(0), |
272 cache_hits_(0), | 287 cache_hits_(0), |
273 inflight_joins_(0) { | 288 inflight_joins_(0) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
321 if (j != inflight_.end()) { | 336 if (j != inflight_.end()) { |
322 // An identical request is in flight already. We'll just attach our | 337 // An identical request is in flight already. We'll just attach our |
323 // callback. | 338 // callback. |
324 inflight_joins_++; | 339 inflight_joins_++; |
325 job = j->second; | 340 job = j->second; |
326 } else { | 341 } else { |
327 // Need to make a new request. | 342 // Need to make a new request. |
328 CertVerifierWorker* worker = new CertVerifierWorker(cert, hostname, flags, | 343 CertVerifierWorker* worker = new CertVerifierWorker(cert, hostname, flags, |
329 this); | 344 this); |
330 job = new CertVerifierJob(worker); | 345 job = new CertVerifierJob(worker); |
331 inflight_.insert(std::make_pair(key, job)); | |
332 if (!worker->Start()) { | 346 if (!worker->Start()) { |
333 inflight_.erase(key); | |
334 delete job; | 347 delete job; |
335 delete worker; | 348 delete worker; |
336 *out_req = NULL; | 349 *out_req = NULL; |
337 return ERR_FAILED; // TODO(wtc): Log an error message. | 350 LOG(ERROR) << "CertVerifierWorker couldn't be started."; |
351 return ERR_FAILED; | |
willchan no longer on Chromium
2011/01/04 21:33:54
Is this ERR_FAILED ok? I don't know if we can cho
| |
338 } | 352 } |
353 inflight_.insert(std::make_pair(key, job)); | |
339 } | 354 } |
340 | 355 |
341 CertVerifierRequest* request = | 356 CertVerifierRequest* request = |
342 new CertVerifierRequest(callback, verify_result); | 357 new CertVerifierRequest(callback, verify_result); |
343 job->AddRequest(request); | 358 job->AddRequest(request); |
344 *out_req = request; | 359 *out_req = request; |
345 return ERR_IO_PENDING; | 360 return ERR_IO_PENDING; |
346 } | 361 } |
347 | 362 |
348 void CertVerifier::CancelRequest(RequestHandle req) { | 363 void CertVerifier::CancelRequest(RequestHandle req) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 cur_request_callback_ = NULL; | 487 cur_request_callback_ = NULL; |
473 | 488 |
474 // Call the user's original callback. | 489 // Call the user's original callback. |
475 callback->Run(result); | 490 callback->Run(result); |
476 } | 491 } |
477 | 492 |
478 } // namespace net | 493 } // namespace net |
479 | 494 |
480 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::CertVerifierWorker); | 495 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::CertVerifierWorker); |
481 | 496 |
OLD | NEW |