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

Side by Side Diff: net/http/disk_based_cert_cache.cc

Issue 378063002: Adding cache hit/miss histograms to DiskBasedCertCache. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@DBCC_MRU_Implement
Patch Set: Resolved merge conflicts (hopefully). Created 6 years, 5 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
« no previous file with comments | « net/http/disk_based_cert_cache.h ('k') | net/http/disk_based_cert_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 {
38 MEMORY_CACHE_HIT = 0,
39 DISK_CACHE_HIT,
40 DISK_CACHE_ENTRY_CORRUPT,
41 DISK_CACHE_ERROR,
42 CACHE_MISS,
43 CACHE_RESULT_MAX
44 };
45
46 void RecordCacheResult(CacheResult result) {
47 UMA_HISTOGRAM_ENUMERATION(
48 "DiskBasedCertCache.CertIoCacheResult", result, CACHE_RESULT_MAX);
49 }
50
35 } // namespace 51 } // namespace
36 52
37 // WriteWorkers represent pending Set jobs in the DiskBasedCertCache. Each 53 // WriteWorkers represent pending Set jobs in the DiskBasedCertCache. Each
38 // certificate requested to be cached is assigned a Writeworker on a one-to-one 54 // 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 55 // basis. The same certificate should not have multiple WriteWorkers at the same
40 // time; instead, add a user callback to the existing WriteWorker. 56 // time; instead, add a user callback to the existing WriteWorker.
41 class DiskBasedCertCache::WriteWorker { 57 class DiskBasedCertCache::WriteWorker {
42 public: 58 public:
43 // |backend| is the backend to store |certificate| in, using 59 // |backend| is the backend to store |certificate| in, using
44 // |key| as the key for the disk_cache::Entry. 60 // |key| as the key for the disk_cache::Entry.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 canceled_(false), 132 canceled_(false),
117 entry_(NULL), 133 entry_(NULL),
118 state_(STATE_NONE), 134 state_(STATE_NONE),
119 io_buf_len_(0), 135 io_buf_len_(0),
120 cleanup_callback_(cleanup_callback), 136 cleanup_callback_(cleanup_callback),
121 io_callback_( 137 io_callback_(
122 base::Bind(&WriteWorker::OnIOComplete, base::Unretained(this))) { 138 base::Bind(&WriteWorker::OnIOComplete, base::Unretained(this))) {
123 } 139 }
124 140
125 DiskBasedCertCache::WriteWorker::~WriteWorker() { 141 DiskBasedCertCache::WriteWorker::~WriteWorker() {
126 X509Certificate::FreeOSCertHandle(cert_handle_); 142 if (cert_handle_)
143 X509Certificate::FreeOSCertHandle(cert_handle_);
127 if (entry_) 144 if (entry_)
128 entry_->Close(); 145 entry_->Close();
129 } 146 }
130 147
131 void DiskBasedCertCache::WriteWorker::Start() { 148 void DiskBasedCertCache::WriteWorker::Start() {
132 DCHECK_EQ(STATE_NONE, state_); 149 DCHECK_EQ(STATE_NONE, state_);
133 state_ = STATE_CREATE; 150 state_ = STATE_CREATE;
134 int rv = DoLoop(OK); 151 int rv = DoLoop(OK);
135 152
136 if (rv == ERR_IO_PENDING) 153 if (rv == ERR_IO_PENDING)
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 438
422 return rv; 439 return rv;
423 } 440 }
424 441
425 int DiskBasedCertCache::ReadWorker::DoOpen() { 442 int DiskBasedCertCache::ReadWorker::DoOpen() {
426 state_ = STATE_OPEN_COMPLETE; 443 state_ = STATE_OPEN_COMPLETE;
427 return backend_->OpenEntry(key_, &entry_, io_callback_); 444 return backend_->OpenEntry(key_, &entry_, io_callback_);
428 } 445 }
429 446
430 int DiskBasedCertCache::ReadWorker::DoOpenComplete(int rv) { 447 int DiskBasedCertCache::ReadWorker::DoOpenComplete(int rv) {
431 if (rv < 0) 448 if (rv < 0) {
449 // Errors other than ERR_CACHE_MISS are not recorded as either a hit
450 // or a miss.
451 RecordCacheResult(rv == ERR_CACHE_MISS ? CACHE_MISS : DISK_CACHE_ERROR);
432 return rv; 452 return rv;
453 }
433 454
434 state_ = STATE_READ; 455 state_ = STATE_READ;
435 return OK; 456 return OK;
436 } 457 }
437 458
438 int DiskBasedCertCache::ReadWorker::DoRead() { 459 int DiskBasedCertCache::ReadWorker::DoRead() {
439 state_ = STATE_READ_COMPLETE; 460 state_ = STATE_READ_COMPLETE;
440 io_buf_len_ = entry_->GetDataSize(0 /* index */); 461 io_buf_len_ = entry_->GetDataSize(0 /* index */);
441 buffer_ = new IOBuffer(io_buf_len_); 462 buffer_ = new IOBuffer(io_buf_len_);
442 return entry_->ReadData( 463 return entry_->ReadData(
443 0 /* index */, 0 /* offset */, buffer_, io_buf_len_, io_callback_); 464 0 /* index */, 0 /* offset */, buffer_, io_buf_len_, io_callback_);
444 } 465 }
445 466
446 int DiskBasedCertCache::ReadWorker::DoReadComplete(int rv) { 467 int DiskBasedCertCache::ReadWorker::DoReadComplete(int rv) {
447 if (rv < io_buf_len_) 468 // The cache should return the entire buffer length. If it does not,
469 // it is probably indicative of an issue other than corruption.
470 if (rv < io_buf_len_) {
471 RecordCacheResult(DISK_CACHE_ERROR);
448 return ERR_FAILED; 472 return ERR_FAILED;
449 473 }
450 cert_handle_ = X509Certificate::CreateOSCertHandleFromBytes(buffer_->data(), 474 cert_handle_ = X509Certificate::CreateOSCertHandleFromBytes(buffer_->data(),
451 io_buf_len_); 475 io_buf_len_);
452 if (!cert_handle_) 476 if (!cert_handle_) {
477 RecordCacheResult(DISK_CACHE_ENTRY_CORRUPT);
453 return ERR_FAILED; 478 return ERR_FAILED;
479 }
454 480
481 RecordCacheResult(DISK_CACHE_HIT);
455 return OK; 482 return OK;
456 } 483 }
457 484
458 void DiskBasedCertCache::ReadWorker::Finish(int rv) { 485 void DiskBasedCertCache::ReadWorker::Finish(int rv) {
459 cleanup_callback_.Run(cert_handle_); 486 cleanup_callback_.Run(cert_handle_);
460 cleanup_callback_.Reset(); 487 cleanup_callback_.Reset();
461 RunCallbacks(); 488 RunCallbacks();
462 delete this; 489 delete this;
463 } 490 }
464 491
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 526 }
500 527
501 void DiskBasedCertCache::Get(const std::string& key, const GetCallback& cb) { 528 void DiskBasedCertCache::Get(const std::string& key, const GetCallback& cb) {
502 DCHECK(!key.empty()); 529 DCHECK(!key.empty());
503 530
504 // If the handle is already in the MRU cache, just return that (via callback). 531 // 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 532 // Note, this will also bring the cert_handle to the front of the recency
506 // list in the MRU cache. 533 // list in the MRU cache.
507 MRUCertCache::iterator mru_it = mru_cert_cache_.Get(key); 534 MRUCertCache::iterator mru_it = mru_cert_cache_.Get(key);
508 if (mru_it != mru_cert_cache_.end()) { 535 if (mru_it != mru_cert_cache_.end()) {
536 RecordCacheResult(MEMORY_CACHE_HIT);
509 ++mem_cache_hits_; 537 ++mem_cache_hits_;
510 cb.Run(mru_it->second); 538 cb.Run(mru_it->second);
511 return; 539 return;
512 } 540 }
513 ++mem_cache_misses_; 541 ++mem_cache_misses_;
514 542
515 ReadWorkerMap::iterator it = read_worker_map_.find(key); 543 ReadWorkerMap::iterator it = read_worker_map_.find(key);
516 544
517 if (it == read_worker_map_.end()) { 545 if (it == read_worker_map_.end()) {
518 ReadWorker* worker = 546 ReadWorker* worker =
519 new ReadWorker(backend_, 547 new ReadWorker(backend_,
520 key, 548 key,
521 base::Bind(&DiskBasedCertCache::FinishedReadOperation, 549 base::Bind(&DiskBasedCertCache::FinishedReadOperation,
522 weak_factory_.GetWeakPtr(), 550 weak_factory_.GetWeakPtr(),
523 key)); 551 key));
524 read_worker_map_[key] = worker; 552 read_worker_map_[key] = worker;
525 worker->AddCallback(cb); 553 worker->AddCallback(cb);
526 worker->Start(); 554 worker->Start();
527 } else { 555 } else {
528 it->second->AddCallback(cb); 556 it->second->AddCallback(cb);
529 } 557 }
530 } 558 }
531 559
532 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle, 560 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle,
533 const SetCallback& cb) { 561 const SetCallback& cb) {
534 DCHECK(!cb.is_null()); 562 DCHECK(!cb.is_null());
535 DCHECK(cert_handle); 563 DCHECK(cert_handle);
536 std::string key = GetCacheKeyToCert(cert_handle); 564 std::string key = GetCacheKeyForCert(cert_handle);
537 565
538 WriteWorkerMap::iterator it = write_worker_map_.find(key); 566 WriteWorkerMap::iterator it = write_worker_map_.find(key);
539 567
540 if (it == write_worker_map_.end()) { 568 if (it == write_worker_map_.end()) {
541 WriteWorker* worker = 569 WriteWorker* worker =
542 new WriteWorker(backend_, 570 new WriteWorker(backend_,
543 key, 571 key,
544 cert_handle, 572 cert_handle,
545 base::Bind(&DiskBasedCertCache::FinishedWriteOperation, 573 base::Bind(&DiskBasedCertCache::FinishedWriteOperation,
546 weak_factory_.GetWeakPtr(), 574 weak_factory_.GetWeakPtr(),
(...skipping 17 matching lines...) Expand all
564 592
565 void DiskBasedCertCache::FinishedWriteOperation( 593 void DiskBasedCertCache::FinishedWriteOperation(
566 const std::string& key, 594 const std::string& key,
567 X509Certificate::OSCertHandle cert_handle) { 595 X509Certificate::OSCertHandle cert_handle) {
568 write_worker_map_.erase(key); 596 write_worker_map_.erase(key);
569 if (!key.empty()) 597 if (!key.empty())
570 mru_cert_cache_.Put(key, X509Certificate::DupOSCertHandle(cert_handle)); 598 mru_cert_cache_.Put(key, X509Certificate::DupOSCertHandle(cert_handle));
571 } 599 }
572 600
573 } // namespace net 601 } // namespace net
OLDNEW
« no previous file with comments | « net/http/disk_based_cert_cache.h ('k') | net/http/disk_based_cert_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698