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

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

Issue 2543523002: Implement main CertificateReportingService code and add unit tests. (Closed)
Patch Set: jialiul comments Created 4 years 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/safe_browsing/certificate_reporting_service.cc
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service.cc b/chrome/browser/safe_browsing/certificate_reporting_service.cc
index 52a20c7501cdc040239c5295ddf3d94269295877..e498cf123e0519968a49b1ed176bc7b398df1224 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind_helpers.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "chrome/browser/safe_browsing/certificate_reporting_service.h"
@@ -17,6 +18,10 @@ bool ReportCompareFunc(const CertificateReportingService::Report& item1,
} // namespace
+// static
+const char CertificateReportingService::kExtendedReportingUploadUrlInsecure[] =
+ "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/";
+
CertificateReportingService::BoundedReportList::BoundedReportList(
size_t max_size)
: max_size_(max_size) {
@@ -57,11 +62,15 @@ CertificateReportingService::Reporter::Reporter(
std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter,
std::unique_ptr<BoundedReportList> retry_list,
base::Clock* clock,
- base::TimeDelta report_ttl)
+ base::TimeDelta report_ttl,
+ EventObserver* event_observer,
+ bool retries_enabled)
: error_reporter_(std::move(error_reporter)),
retry_list_(std::move(retry_list)),
test_clock_(clock),
report_ttl_(report_ttl),
+ event_observer_(event_observer),
+ retries_enabled_(retries_enabled),
current_report_id_(0),
weak_factory_(this) {}
@@ -77,6 +86,9 @@ void CertificateReportingService::Reporter::Send(
void CertificateReportingService::Reporter::SendPending() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (!retries_enabled_) {
+ return;
+ }
base::Time now =
test_clock_ ? test_clock_->Now() : base::Time::NowFromSystemTime();
// Copy pending reports and clear the retry list.
@@ -102,6 +114,11 @@ CertificateReportingService::Reporter::GetQueueForTesting() const {
return retry_list_.get();
}
+void CertificateReportingService::Reporter::SetEventObserverForTesting(
+ EventObserver* observer) {
+ event_observer_ = observer;
+}
+
void CertificateReportingService::Reporter::SendInternal(
const CertificateReportingService::Report& report) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -118,13 +135,185 @@ void CertificateReportingService::Reporter::ErrorCallback(int report_id,
const GURL& url,
int error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- auto it = inflight_reports_.find(report_id);
- DCHECK(it != inflight_reports_.end());
- retry_list_->Add(it->second);
+ if (retries_enabled_) {
+ auto it = inflight_reports_.find(report_id);
+ DCHECK(it != inflight_reports_.end());
+ retry_list_->Add(it->second);
+ }
CHECK_GT(inflight_reports_.erase(report_id), 0u);
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&CertificateReportingService::EventObserver::OnSendComplete,
+ base::Unretained(event_observer_), report_id, 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::EventObserver::OnSendComplete,
+ base::Unretained(event_observer_), report_id, true));
+}
+
+CertificateReportingService::CertificateReportingService(
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+ std::unique_ptr<EventObserver> event_observer,
+ size_t max_queued_report_count,
+ base::TimeDelta max_report_age,
+ base::Clock* test_clock)
+ : enabled_(true),
+ url_request_context_(nullptr),
+ event_observer_(std::move(event_observer)),
+ max_queued_report_count_(max_queued_report_count),
+ max_report_age_(max_report_age),
+ test_clock_(test_clock),
+ made_send_attempt_(false) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ content::BrowserThread::PostTaskAndReply(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&CertificateReportingService::InitializeOnIOThread,
+ base::Unretained(this), enabled_, url_request_context_getter,
+ max_queued_report_count_, max_report_age_, test_clock_,
+ base::Unretained(event_observer_.get())),
+ base::Bind(&EventObserver::OnReset,
+ base::Unretained(event_observer_.get())));
+}
+
+CertificateReportingService::~CertificateReportingService() {
+ DCHECK(!reporter_);
+}
+
+void CertificateReportingService::Shutdown() {
+ // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once
+ // when all KeyedServices shut down. All calls after the first one is a no-op.
+ enabled_ = false;
+
+ Reset(base::Bind(&EventObserver::OnReset,
+ base::Unretained(event_observer_.get())));
+}
+
+void CertificateReportingService::Send(const std::string& serialized_report) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ made_send_attempt_ = true;
+ if (!reporter_) {
+ DidAttemptSend(false);
+ return;
+ }
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ content::BrowserThread::PostTaskAndReply(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&CertificateReportingService::Reporter::Send,
+ base::Unretained(reporter_.get()), serialized_report),
+ base::Bind(&CertificateReportingService::DidAttemptSend,
+ base::Unretained(this), true));
+}
+
+void CertificateReportingService::SendPending() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ made_send_attempt_ = true;
+ if (!reporter_) {
+ DidAttemptSend(false);
+ return;
+ }
+ content::BrowserThread::PostTaskAndReply(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&CertificateReportingService::Reporter::SendPending,
+ base::Unretained(reporter_.get())),
+ base::Bind(&CertificateReportingService::DidAttemptSend,
+ base::Unretained(this), true));
+}
+
+void CertificateReportingService::InitializeOnIOThread(
+ bool enabled,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+ size_t max_queued_report_count,
+ base::TimeDelta max_report_age,
+ base::Clock* test_clock,
+ EventObserver* event_observer) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK(!url_request_context_);
+ url_request_context_ = url_request_context_getter->GetURLRequestContext();
+ ResetOnIOThread(enabled, url_request_context_, max_queued_report_count,
+ max_report_age, test_clock, event_observer);
+}
+
+void CertificateReportingService::DidAttemptSend(bool sent) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ event_observer_->OnSendAttempt(sent);
+}
+
+void CertificateReportingService::SetEnabled(bool enabled) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ enabled_ = enabled;
+ Reset(base::Bind(&EventObserver::OnReset,
+ base::Unretained(event_observer_.get())));
+}
+
+CertificateReportingService::Reporter*
+CertificateReportingService::get_reporter_for_testing() const {
+ return reporter_.get();
+}
+
+void CertificateReportingService::SetEventObserverForTesting(
+ std::unique_ptr<CertificateReportingService::EventObserver> observer) {
+ event_observer_ = std::move(observer);
+ // reporter_ can be null if reporting is disabled.
+ if (reporter_) {
+ reporter_->SetEventObserverForTesting(event_observer_.get());
+ }
+}
+
+void CertificateReportingService::SetMaxQueuedReportCountForTesting(
+ size_t count) {
+ DCHECK(!made_send_attempt_);
+ max_queued_report_count_ = count;
+ Reset(base::Bind(base::DoNothing));
+}
+
+void CertificateReportingService::SetClockForTesting(base::Clock* clock) {
+ DCHECK(!made_send_attempt_);
+ test_clock_ = clock;
+ Reset(base::Bind(base::DoNothing));
+}
+
+void CertificateReportingService::SetMaxReportAgeForTesting(
+ base::TimeDelta max_report_age) {
+ DCHECK(!made_send_attempt_);
+ max_report_age_ = max_report_age;
+ Reset(base::Bind(base::DoNothing));
+}
+
+void CertificateReportingService::Reset(
+ const base::Callback<void()>& callback) {
+ content::BrowserThread::PostTaskAndReply(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&CertificateReportingService::ResetOnIOThread,
+ base::Unretained(this), enabled_, url_request_context_,
+ max_queued_report_count_, max_report_age_, test_clock_,
+ event_observer_.get()),
+ callback);
+}
+
+void CertificateReportingService::ResetOnIOThread(
+ bool enabled,
+ net::URLRequestContext* url_request_context,
+ size_t max_queued_report_count,
+ base::TimeDelta max_report_age,
+ base::Clock* test_clock,
+ EventObserver* event_observer) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ // url_request_context_ is null during shutdown.
+ if (!enabled || !url_request_context) {
+ reporter_.reset(nullptr);
+ return;
+ }
+ reporter_.reset(new Reporter(
+ std::unique_ptr<certificate_reporting::ErrorReporter>(
+ new certificate_reporting::ErrorReporter(
+ url_request_context, GURL(kExtendedReportingUploadUrlInsecure),
+ net::ReportSender::DO_NOT_SEND_COOKIES)),
+ std::unique_ptr<BoundedReportList>(
+ new BoundedReportList(max_queued_report_count)),
+ test_clock, max_report_age, event_observer, true /* retries_enabled */));
}

Powered by Google App Engine
This is Rietveld 408576698