OLD | NEW |
---|---|
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 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/http/disk_based_cert_cache.h" | 5 #include "net/http/disk_based_cert_cache.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/metrics/histogram.h" | |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
15 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
16 #include "net/disk_cache/disk_cache.h" | 17 #include "net/disk_cache/disk_cache.h" |
17 | 18 |
18 namespace net { | 19 namespace net { |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 // TODO(brandonsalmon): change this number to improve performance. | 23 // TODO(brandonsalmon): change this number to improve performance. |
23 const size_t kMemoryCacheMaxSize = 30; | 24 const size_t kMemoryCacheMaxSize = 30; |
24 | 25 |
25 // Used to obtain a unique cache key for a certificate in the form of | 26 // Used to obtain a unique cache key for a certificate in the form of |
26 // "cert:<hash>". | 27 // "cert:<hash>". |
27 std::string GetCacheKeyToCert(const X509Certificate::OSCertHandle cert_handle) { | 28 std::string GetCacheKeyForCert( |
29 const X509Certificate::OSCertHandle cert_handle) { | |
28 SHA1HashValue fingerprint = | 30 SHA1HashValue fingerprint = |
29 X509Certificate::CalculateFingerprint(cert_handle); | 31 X509Certificate::CalculateFingerprint(cert_handle); |
30 | 32 |
31 return "cert:" + | 33 return "cert:" + |
32 base::HexEncode(fingerprint.data, arraysize(fingerprint.data)); | 34 base::HexEncode(fingerprint.data, arraysize(fingerprint.data)); |
33 } | 35 } |
34 | 36 |
37 enum CacheResult { MEMORY_CACHE_HIT = 0, DISK_CACHE_HIT, CACHE_MISS }; | |
jar (doing other things)
2014/07/10 00:04:58
nit: Add one more enum:
CACHE_RESULT_MAX
Use that
| |
38 | |
39 void RecordCacheResult(CacheResult result) { | |
40 UMA_HISTOGRAM_ENUMERATION( | |
41 "DiskBasedCertCache.CertIoCacheResult", result, CACHE_MISS); | |
jar (doing other things)
2014/07/10 00:04:58
nit: Replace CACHE_MISS With CACHE_RESULT_MAX
| |
42 } | |
43 | |
35 } // namespace | 44 } // namespace |
36 | 45 |
37 // WriteWorkers represent pending Set jobs in the DiskBasedCertCache. Each | 46 // WriteWorkers represent pending Set jobs in the DiskBasedCertCache. Each |
38 // certificate requested to be cached is assigned a Writeworker on a one-to-one | 47 // certificate requested to be cached is assigned a Writeworker on a one-to-one |
39 // basis. The same certificate should not have multiple WriteWorkers at the same | 48 // basis. The same certificate should not have multiple WriteWorkers at the same |
40 // time; instead, add a user callback to the existing WriteWorker. | 49 // time; instead, add a user callback to the existing WriteWorker. |
41 class DiskBasedCertCache::WriteWorker { | 50 class DiskBasedCertCache::WriteWorker { |
42 public: | 51 public: |
43 // |backend| is the backend to store |certificate| in, using | 52 // |backend| is the backend to store |certificate| in, using |
44 // |key| as the key for the disk_cache::Entry. | 53 // |key| as the key for the disk_cache::Entry. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 canceled_(false), | 125 canceled_(false), |
117 entry_(NULL), | 126 entry_(NULL), |
118 state_(STATE_NONE), | 127 state_(STATE_NONE), |
119 io_buf_len_(0), | 128 io_buf_len_(0), |
120 cleanup_callback_(cleanup_callback), | 129 cleanup_callback_(cleanup_callback), |
121 io_callback_( | 130 io_callback_( |
122 base::Bind(&WriteWorker::OnIOComplete, base::Unretained(this))) { | 131 base::Bind(&WriteWorker::OnIOComplete, base::Unretained(this))) { |
123 } | 132 } |
124 | 133 |
125 DiskBasedCertCache::WriteWorker::~WriteWorker() { | 134 DiskBasedCertCache::WriteWorker::~WriteWorker() { |
126 X509Certificate::FreeOSCertHandle(cert_handle_); | 135 if (cert_handle_) |
136 X509Certificate::FreeOSCertHandle(cert_handle_); | |
127 if (entry_) | 137 if (entry_) |
128 entry_->Close(); | 138 entry_->Close(); |
129 } | 139 } |
130 | 140 |
131 void DiskBasedCertCache::WriteWorker::Start() { | 141 void DiskBasedCertCache::WriteWorker::Start() { |
132 DCHECK_EQ(STATE_NONE, state_); | 142 DCHECK_EQ(STATE_NONE, state_); |
133 state_ = STATE_CREATE; | 143 state_ = STATE_CREATE; |
134 int rv = DoLoop(OK); | 144 int rv = DoLoop(OK); |
135 | 145 |
136 if (rv == ERR_IO_PENDING) | 146 if (rv == ERR_IO_PENDING) |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 | 431 |
422 return rv; | 432 return rv; |
423 } | 433 } |
424 | 434 |
425 int DiskBasedCertCache::ReadWorker::DoOpen() { | 435 int DiskBasedCertCache::ReadWorker::DoOpen() { |
426 state_ = STATE_OPEN_COMPLETE; | 436 state_ = STATE_OPEN_COMPLETE; |
427 return backend_->OpenEntry(key_, &entry_, io_callback_); | 437 return backend_->OpenEntry(key_, &entry_, io_callback_); |
428 } | 438 } |
429 | 439 |
430 int DiskBasedCertCache::ReadWorker::DoOpenComplete(int rv) { | 440 int DiskBasedCertCache::ReadWorker::DoOpenComplete(int rv) { |
431 if (rv < 0) | 441 if (rv < 0) { |
442 // Errors other than ERR_CACHE_MISS are not recorded as either a hit | |
jar (doing other things)
2014/07/10 00:04:58
Consider adding one more enum, which captures thes
| |
443 // or a miss. | |
444 if (rv == ERR_CACHE_MISS) | |
445 RecordCacheResult(CACHE_MISS); | |
432 return rv; | 446 return rv; |
447 } | |
448 RecordCacheResult(DISK_CACHE_HIT); | |
433 | 449 |
434 state_ = STATE_READ; | 450 state_ = STATE_READ; |
435 return OK; | 451 return OK; |
436 } | 452 } |
437 | 453 |
438 int DiskBasedCertCache::ReadWorker::DoRead() { | 454 int DiskBasedCertCache::ReadWorker::DoRead() { |
439 state_ = STATE_READ_COMPLETE; | 455 state_ = STATE_READ_COMPLETE; |
440 io_buf_len_ = entry_->GetDataSize(0 /* index */); | 456 io_buf_len_ = entry_->GetDataSize(0 /* index */); |
441 buffer_ = new IOBuffer(io_buf_len_); | 457 buffer_ = new IOBuffer(io_buf_len_); |
442 return entry_->ReadData( | 458 return entry_->ReadData( |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 } | 515 } |
500 | 516 |
501 void DiskBasedCertCache::Get(const std::string& key, const GetCallback& cb) { | 517 void DiskBasedCertCache::Get(const std::string& key, const GetCallback& cb) { |
502 DCHECK(!key.empty()); | 518 DCHECK(!key.empty()); |
503 | 519 |
504 // If the handle is already in the MRU cache, just return that (via callback). | 520 // If the handle is already in the MRU cache, just return that (via callback). |
505 // Note, this will also bring the cert_handle to the front of the recency | 521 // Note, this will also bring the cert_handle to the front of the recency |
506 // list in the MRU cache. | 522 // list in the MRU cache. |
507 MRUCertCache::iterator mru_it = mru_cert_cache_.Get(key); | 523 MRUCertCache::iterator mru_it = mru_cert_cache_.Get(key); |
508 if (mru_it != mru_cert_cache_.end()) { | 524 if (mru_it != mru_cert_cache_.end()) { |
525 RecordCacheResult(MEMORY_CACHE_HIT); | |
509 ++mem_cache_hits_; | 526 ++mem_cache_hits_; |
510 cb.Run(mru_it->second); | 527 cb.Run(mru_it->second); |
511 return; | 528 return; |
512 } | 529 } |
513 ++mem_cache_misses_; | 530 ++mem_cache_misses_; |
514 | 531 |
515 ReadWorkerMap::iterator it = read_worker_map_.find(key); | 532 ReadWorkerMap::iterator it = read_worker_map_.find(key); |
516 | 533 |
517 if (it == read_worker_map_.end()) { | 534 if (it == read_worker_map_.end()) { |
518 ReadWorker* worker = | 535 ReadWorker* worker = |
519 new ReadWorker(backend_, | 536 new ReadWorker(backend_, |
520 key, | 537 key, |
521 base::Bind(&DiskBasedCertCache::FinishedReadOperation, | 538 base::Bind(&DiskBasedCertCache::FinishedReadOperation, |
522 weak_factory_.GetWeakPtr(), | 539 weak_factory_.GetWeakPtr(), |
523 key)); | 540 key)); |
524 read_worker_map_[key] = worker; | 541 read_worker_map_[key] = worker; |
525 worker->AddCallback(cb); | 542 worker->AddCallback(cb); |
526 worker->Start(); | 543 worker->Start(); |
527 } else { | 544 } else { |
528 it->second->AddCallback(cb); | 545 it->second->AddCallback(cb); |
529 } | 546 } |
530 } | 547 } |
531 | 548 |
532 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle, | 549 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle, |
533 const SetCallback& cb) { | 550 const SetCallback& cb) { |
534 DCHECK(!cb.is_null()); | 551 DCHECK(!cb.is_null()); |
535 DCHECK(cert_handle); | 552 DCHECK(cert_handle); |
536 std::string key = GetCacheKeyToCert(cert_handle); | 553 std::string key = GetCacheKeyForCert(cert_handle); |
537 | 554 |
538 WriteWorkerMap::iterator it = write_worker_map_.find(key); | 555 WriteWorkerMap::iterator it = write_worker_map_.find(key); |
539 | 556 |
540 if (it == write_worker_map_.end()) { | 557 if (it == write_worker_map_.end()) { |
541 WriteWorker* worker = | 558 WriteWorker* worker = |
542 new WriteWorker(backend_, | 559 new WriteWorker(backend_, |
543 key, | 560 key, |
544 cert_handle, | 561 cert_handle, |
545 base::Bind(&DiskBasedCertCache::FinishedWriteOperation, | 562 base::Bind(&DiskBasedCertCache::FinishedWriteOperation, |
546 weak_factory_.GetWeakPtr(), | 563 weak_factory_.GetWeakPtr(), |
(...skipping 17 matching lines...) Expand all Loading... | |
564 | 581 |
565 void DiskBasedCertCache::FinishedWriteOperation( | 582 void DiskBasedCertCache::FinishedWriteOperation( |
566 const std::string& key, | 583 const std::string& key, |
567 X509Certificate::OSCertHandle cert_handle) { | 584 X509Certificate::OSCertHandle cert_handle) { |
568 write_worker_map_.erase(key); | 585 write_worker_map_.erase(key); |
569 if (!key.empty()) | 586 if (!key.empty()) |
570 mru_cert_cache_.Put(key, X509Certificate::DupOSCertHandle(cert_handle)); | 587 mru_cert_cache_.Put(key, X509Certificate::DupOSCertHandle(cert_handle)); |
571 } | 588 } |
572 | 589 |
573 } // namespace net | 590 } // namespace net |
OLD | NEW |