| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 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 "base/time/clock.h" |
| 6 #include "base/time/default_clock.h" |
| 7 #include "chrome/browser/ssl/certificate_reporting_service.h" |
| 8 #include "content/public/browser/browser_thread.h" |
| 9 |
| 10 namespace { |
| 11 // First item is ordered before the second item if it's newer. |
| 12 bool ReportCompareFunc(const CertificateReportingService::Report& item1, |
| 13 const CertificateReportingService::Report& item2) { |
| 14 return item1.creation_time > item2.creation_time; |
| 15 } |
| 16 |
| 17 } // namespace |
| 18 |
| 19 void CertificateReportingService::BoundedReportList::Add(const Report& item) { |
| 20 DCHECK(thread_checker_.CalledOnValidThread()); |
| 21 DCHECK(items_.size() <= max_size_); |
| 22 if (items_.size() == max_size_) { |
| 23 const Report& last = items_.back(); |
| 24 if (item.creation_time <= last.creation_time) { |
| 25 // Report older than the oldest item in the queue, ignore. |
| 26 return; |
| 27 } |
| 28 // Reached the maximum item count, remove the oldest item. |
| 29 items_.pop_back(); |
| 30 } |
| 31 items_.push_back(item); |
| 32 std::sort(items_.begin(), items_.end(), ReportCompareFunc); |
| 33 } |
| 34 |
| 35 CertificateReportingService::BoundedReportList::BoundedReportList( |
| 36 size_t max_size) |
| 37 : max_size_(max_size) { |
| 38 DCHECK(thread_checker_.CalledOnValidThread()); |
| 39 } |
| 40 |
| 41 void CertificateReportingService::BoundedReportList::Clear() { |
| 42 items_.clear(); |
| 43 } |
| 44 |
| 45 CertificateReportingService::BoundedReportList::~BoundedReportList() {} |
| 46 |
| 47 const std::vector<CertificateReportingService::Report>& |
| 48 CertificateReportingService::BoundedReportList::items() const { |
| 49 DCHECK(thread_checker_.CalledOnValidThread()); |
| 50 return items_; |
| 51 } |
| 52 |
| 53 CertificateReportingService::Reporter::Reporter( |
| 54 std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter, |
| 55 std::unique_ptr<BoundedReportList> retry_list, |
| 56 base::Clock* clock, |
| 57 base::TimeDelta max_item_age, |
| 58 EventObserver* event_observer) |
| 59 : error_reporter_(std::move(error_reporter)), |
| 60 retry_list_(std::move(retry_list)), |
| 61 test_clock_(clock), |
| 62 max_item_age_(max_item_age), |
| 63 event_observer_(event_observer), |
| 64 current_report_id_(0) {} |
| 65 |
| 66 void CertificateReportingService::Reporter::Send( |
| 67 const std::string& serialized_report) { |
| 68 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 69 base::Time now = |
| 70 test_clock_ ? test_clock_->Now() : base::Time::NowFromSystemTime(); |
| 71 SendInternal(Report(current_report_id_++, now, serialized_report)); |
| 72 } |
| 73 |
| 74 void CertificateReportingService::Reporter::SendPending() { |
| 75 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 76 base::Time now = |
| 77 test_clock_ ? test_clock_->Now() : base::Time::NowFromSystemTime(); |
| 78 // Copy pending reports and clear the retry list. |
| 79 std::vector<Report> items = retry_list_->items(); |
| 80 retry_list_->Clear(); |
| 81 for (const Report& report : items) { |
| 82 if (report.creation_time < now - max_item_age_) { |
| 83 // Report too old, ignore. |
| 84 continue; |
| 85 } |
| 86 SendInternal(report); |
| 87 } |
| 88 retry_list_->Clear(); |
| 89 } |
| 90 |
| 91 size_t |
| 92 CertificateReportingService::Reporter::inflight_report_count_for_testing() |
| 93 const { |
| 94 return inflight_reports_.size(); |
| 95 } |
| 96 |
| 97 CertificateReportingService::BoundedReportList* |
| 98 CertificateReportingService::Reporter::GetQueueForTesting() const { |
| 99 return retry_list_.get(); |
| 100 } |
| 101 |
| 102 void CertificateReportingService::Reporter::SetEventObserverForTesting( |
| 103 EventObserver* observer) { |
| 104 event_observer_ = observer; |
| 105 } |
| 106 |
| 107 CertificateReportingService::Reporter::~Reporter() {} |
| 108 |
| 109 void CertificateReportingService::Reporter::SendInternal( |
| 110 const CertificateReportingService::Report& report) { |
| 111 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 112 inflight_reports_[report.report_id] = report; |
| 113 error_reporter_->SendExtendedReportingReport( |
| 114 report.serialized_report, |
| 115 base::Bind(&CertificateReportingService::Reporter::SuccessCallback, this, |
| 116 report.report_id), |
| 117 base::Bind(&CertificateReportingService::Reporter::ErrorCallback, this, |
| 118 report.report_id)); |
| 119 } |
| 120 |
| 121 void CertificateReportingService::Reporter::ErrorCallback(int report_id, |
| 122 const GURL& url, |
| 123 int error) { |
| 124 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 125 retry_list_->Add(inflight_reports_[report_id]); |
| 126 CHECK_GT(inflight_reports_.erase(report_id), 0u); |
| 127 content::BrowserThread::PostTask( |
| 128 content::BrowserThread::UI, FROM_HERE, |
| 129 base::Bind(&CertificateReportingService::Reporter::OnSendComplete, this, |
| 130 false)); |
| 131 } |
| 132 |
| 133 void CertificateReportingService::Reporter::SuccessCallback(int report_id) { |
| 134 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 135 CHECK_GT(inflight_reports_.erase(report_id), 0u); |
| 136 content::BrowserThread::PostTask( |
| 137 content::BrowserThread::UI, FROM_HERE, |
| 138 base::Bind(&CertificateReportingService::Reporter::OnSendComplete, this, |
| 139 true)); |
| 140 } |
| 141 |
| 142 void CertificateReportingService::Reporter::OnSendComplete(bool success) { |
| 143 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 144 event_observer_->OnSendComplete(success); |
| 145 } |
| OLD | NEW |