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

Unified Diff: chrome/browser/ssl/certificate_reporting_service.cc

Issue 2483003003: Introduce CertificateReportingService class to handle certificate reports. (Closed)
Patch Set: Rebase Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ssl/certificate_reporting_service.cc
diff --git a/chrome/browser/ssl/certificate_reporting_service.cc b/chrome/browser/ssl/certificate_reporting_service.cc
new file mode 100644
index 0000000000000000000000000000000000000000..19b6ca2793903f48def7cd9c7bc966f78349325d
--- /dev/null
+++ b/chrome/browser/ssl/certificate_reporting_service.cc
@@ -0,0 +1,145 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/time/clock.h"
+#include "base/time/default_clock.h"
+#include "chrome/browser/ssl/certificate_reporting_service.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace {
+// First item is ordered before the second item if it's newer.
+bool ReportCompareFunc(const CertificateReportingService::Report& item1,
+ const CertificateReportingService::Report& item2) {
+ return item1.creation_time > item2.creation_time;
+}
+
+} // namespace
+
+void CertificateReportingService::BoundedReportList::Add(const Report& item) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(items_.size() <= max_size_);
+ if (items_.size() == max_size_) {
+ const Report& last = items_.back();
+ if (item.creation_time <= last.creation_time) {
+ // Report older than the oldest item in the queue, ignore.
+ return;
+ }
+ // Reached the maximum item count, remove the oldest item.
+ items_.pop_back();
+ }
+ items_.push_back(item);
+ std::sort(items_.begin(), items_.end(), ReportCompareFunc);
+}
+
+CertificateReportingService::BoundedReportList::BoundedReportList(
+ size_t max_size)
+ : max_size_(max_size) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void CertificateReportingService::BoundedReportList::Clear() {
+ items_.clear();
+}
+
+CertificateReportingService::BoundedReportList::~BoundedReportList() {}
+
+const std::vector<CertificateReportingService::Report>&
+CertificateReportingService::BoundedReportList::items() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return items_;
+}
+
+CertificateReportingService::Reporter::Reporter(
+ std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter,
+ std::unique_ptr<BoundedReportList> retry_list,
+ base::Clock* clock,
+ base::TimeDelta max_item_age,
+ EventObserver* event_observer)
+ : error_reporter_(std::move(error_reporter)),
+ retry_list_(std::move(retry_list)),
+ test_clock_(clock),
+ max_item_age_(max_item_age),
+ event_observer_(event_observer),
+ current_report_id_(0) {}
+
+void CertificateReportingService::Reporter::Send(
+ const std::string& serialized_report) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ base::Time now =
+ test_clock_ ? test_clock_->Now() : base::Time::NowFromSystemTime();
+ SendInternal(Report(current_report_id_++, now, serialized_report));
+}
+
+void CertificateReportingService::Reporter::SendPending() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ base::Time now =
+ test_clock_ ? test_clock_->Now() : base::Time::NowFromSystemTime();
+ // Copy pending reports and clear the retry list.
+ std::vector<Report> items = retry_list_->items();
+ retry_list_->Clear();
+ for (const Report& report : items) {
+ if (report.creation_time < now - max_item_age_) {
+ // Report too old, ignore.
+ continue;
+ }
+ SendInternal(report);
+ }
+ retry_list_->Clear();
+}
+
+size_t
+CertificateReportingService::Reporter::inflight_report_count_for_testing()
+ const {
+ return inflight_reports_.size();
+}
+
+CertificateReportingService::BoundedReportList*
+CertificateReportingService::Reporter::GetQueueForTesting() const {
+ return retry_list_.get();
+}
+
+void CertificateReportingService::Reporter::SetEventObserverForTesting(
+ EventObserver* observer) {
+ event_observer_ = observer;
+}
+
+CertificateReportingService::Reporter::~Reporter() {}
+
+void CertificateReportingService::Reporter::SendInternal(
+ const CertificateReportingService::Report& report) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ inflight_reports_[report.report_id] = report;
+ error_reporter_->SendExtendedReportingReport(
+ report.serialized_report,
+ base::Bind(&CertificateReportingService::Reporter::SuccessCallback, this,
+ report.report_id),
+ base::Bind(&CertificateReportingService::Reporter::ErrorCallback, this,
+ report.report_id));
+}
+
+void CertificateReportingService::Reporter::ErrorCallback(int report_id,
+ const GURL& url,
+ int error) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ retry_list_->Add(inflight_reports_[report_id]);
+ CHECK_GT(inflight_reports_.erase(report_id), 0u);
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&CertificateReportingService::Reporter::OnSendComplete, this,
+ false));
+}
+
+void CertificateReportingService::Reporter::SuccessCallback(int report_id) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ CHECK_GT(inflight_reports_.erase(report_id), 0u);
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&CertificateReportingService::Reporter::OnSendComplete, this,
+ true));
+}
+
+void CertificateReportingService::Reporter::OnSendComplete(bool success) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ event_observer_->OnSendComplete(success);
+}

Powered by Google App Engine
This is Rietveld 408576698