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

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: Corruption no longer counted as a DiskCache hit, now counted separately. 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
OLDNEW
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 {
38 MEMORY_CACHE_HIT = 0,
39 DISK_CACHE_HIT,
40 DISK_CACHE_CORRUPT,
41 CACHE_MISS,
42 CACHE_ERROR,
wtc 2014/07/10 18:21:38 Nit: without looking at the source code, the meani
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 : 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 if (rv < io_buf_len_)
448 return ERR_FAILED; 469 return ERR_FAILED;
wtc 2014/07/10 18:21:38 Nit: you missed this error return (entry_->ReadDat
brandonsalmon 2014/07/10 18:33:38 Do you think that this is also cache entry corrupt
wtc 2014/07/10 18:49:36 I don't know. You may want to read the entry_->Rea
449 470
450 cert_handle_ = X509Certificate::CreateOSCertHandleFromBytes(buffer_->data(), 471 cert_handle_ = X509Certificate::CreateOSCertHandleFromBytes(buffer_->data(),
451 io_buf_len_); 472 io_buf_len_);
452 if (!cert_handle_) 473 if (!cert_handle_) {
474 RecordCacheResult(DISK_CACHE_CORRUPT);
wtc 2014/07/10 18:21:38 This enum value should be named so it's clear only
453 return ERR_FAILED; 475 return ERR_FAILED;
476 }
454 477
478 RecordCacheResult(DISK_CACHE_HIT);
455 return OK; 479 return OK;
456 } 480 }
457 481
458 void DiskBasedCertCache::ReadWorker::Finish(int rv) { 482 void DiskBasedCertCache::ReadWorker::Finish(int rv) {
459 cleanup_callback_.Run(cert_handle_); 483 cleanup_callback_.Run(cert_handle_);
460 cleanup_callback_.Reset(); 484 cleanup_callback_.Reset();
461 RunCallbacks(); 485 RunCallbacks();
462 delete this; 486 delete this;
463 } 487 }
464 488
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 523 }
500 524
501 void DiskBasedCertCache::Get(const std::string& key, const GetCallback& cb) { 525 void DiskBasedCertCache::Get(const std::string& key, const GetCallback& cb) {
502 DCHECK(!key.empty()); 526 DCHECK(!key.empty());
503 527
504 // If the handle is already in the MRU cache, just return that (via callback). 528 // 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 529 // Note, this will also bring the cert_handle to the front of the recency
506 // list in the MRU cache. 530 // list in the MRU cache.
507 MRUCertCache::iterator mru_it = mru_cert_cache_.Get(key); 531 MRUCertCache::iterator mru_it = mru_cert_cache_.Get(key);
508 if (mru_it != mru_cert_cache_.end()) { 532 if (mru_it != mru_cert_cache_.end()) {
533 RecordCacheResult(MEMORY_CACHE_HIT);
509 ++mem_cache_hits_; 534 ++mem_cache_hits_;
510 cb.Run(mru_it->second); 535 cb.Run(mru_it->second);
511 return; 536 return;
512 } 537 }
513 ++mem_cache_misses_; 538 ++mem_cache_misses_;
514 539
515 ReadWorkerMap::iterator it = read_worker_map_.find(key); 540 ReadWorkerMap::iterator it = read_worker_map_.find(key);
516 541
517 if (it == read_worker_map_.end()) { 542 if (it == read_worker_map_.end()) {
518 ReadWorker* worker = 543 ReadWorker* worker =
519 new ReadWorker(backend_, 544 new ReadWorker(backend_,
520 key, 545 key,
521 base::Bind(&DiskBasedCertCache::FinishedReadOperation, 546 base::Bind(&DiskBasedCertCache::FinishedReadOperation,
522 weak_factory_.GetWeakPtr(), 547 weak_factory_.GetWeakPtr(),
523 key)); 548 key));
524 read_worker_map_[key] = worker; 549 read_worker_map_[key] = worker;
525 worker->AddCallback(cb); 550 worker->AddCallback(cb);
526 worker->Start(); 551 worker->Start();
527 } else { 552 } else {
528 it->second->AddCallback(cb); 553 it->second->AddCallback(cb);
529 } 554 }
530 } 555 }
531 556
532 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle, 557 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle,
533 const SetCallback& cb) { 558 const SetCallback& cb) {
534 DCHECK(!cb.is_null()); 559 DCHECK(!cb.is_null());
535 DCHECK(cert_handle); 560 DCHECK(cert_handle);
536 std::string key = GetCacheKeyToCert(cert_handle); 561 std::string key = GetCacheKeyForCert(cert_handle);
537 562
538 WriteWorkerMap::iterator it = write_worker_map_.find(key); 563 WriteWorkerMap::iterator it = write_worker_map_.find(key);
539 564
540 if (it == write_worker_map_.end()) { 565 if (it == write_worker_map_.end()) {
541 WriteWorker* worker = 566 WriteWorker* worker =
542 new WriteWorker(backend_, 567 new WriteWorker(backend_,
543 key, 568 key,
544 cert_handle, 569 cert_handle,
545 base::Bind(&DiskBasedCertCache::FinishedWriteOperation, 570 base::Bind(&DiskBasedCertCache::FinishedWriteOperation,
546 weak_factory_.GetWeakPtr(), 571 weak_factory_.GetWeakPtr(),
(...skipping 17 matching lines...) Expand all
564 589
565 void DiskBasedCertCache::FinishedWriteOperation( 590 void DiskBasedCertCache::FinishedWriteOperation(
566 const std::string& key, 591 const std::string& key,
567 X509Certificate::OSCertHandle cert_handle) { 592 X509Certificate::OSCertHandle cert_handle) {
568 write_worker_map_.erase(key); 593 write_worker_map_.erase(key);
569 if (!key.empty()) 594 if (!key.empty())
570 mru_cert_cache_.Put(key, X509Certificate::DupOSCertHandle(cert_handle)); 595 mru_cert_cache_.Put(key, X509Certificate::DupOSCertHandle(cert_handle));
571 } 596 }
572 597
573 } // namespace net 598 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698