| Index: components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
|
| diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
|
| index 00cca9f3bbd6524dc214107acc00b772a5405eb4..13942ad271dc5387facf02eb27634359926db3a2 100644
|
| --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
|
| +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
|
| @@ -1,19 +1,20 @@
|
| // 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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h"
|
|
|
| #include "base/metrics/histogram.h"
|
| #include "base/optional.h"
|
| #include "base/rand_util.h"
|
| +#include "base/time/time.h"
|
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
|
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h"
|
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
|
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
|
| #include "components/data_reduction_proxy/proto/client_config.pb.h"
|
| #include "components/data_reduction_proxy/proto/pageload_metrics.pb.h"
|
| #include "net/base/load_flags.h"
|
| #include "net/url_request/url_fetcher.h"
|
| #include "net/url_request/url_request_context_getter.h"
|
| #include "net/url_request/url_request_status.h"
|
| @@ -21,26 +22,29 @@
|
|
|
| namespace data_reduction_proxy {
|
|
|
| namespace {
|
|
|
| static const char kHistogramSucceeded[] =
|
| "DataReductionProxy.Pingback.Succeeded";
|
| static const char kHistogramAttempted[] =
|
| "DataReductionProxy.Pingback.Attempted";
|
|
|
| -// Creates a PageloadMetrics protobuf for this page load and serializes to a
|
| -// string.
|
| -std::string SerializeData(const DataReductionProxyData& request_data,
|
| - const DataReductionProxyPageLoadTiming& timing) {
|
| - RecordPageloadMetricsRequest batched_request;
|
| - PageloadMetrics* request = batched_request.add_pageloads();
|
| +// Creates a RecordPageloadMetrics protobuf for this page load based on page
|
| +// timing and data reduction proxy state.
|
| +std::unique_ptr<RecordPageloadMetricsRequest>
|
| +CreateRecordPageloadMetricsRequest(
|
| + const DataReductionProxyData& request_data,
|
| + const DataReductionProxyPageLoadTiming& timing) {
|
| + std::unique_ptr<RecordPageloadMetricsRequest> batched_request(
|
| + new RecordPageloadMetricsRequest());
|
| + PageloadMetrics* request = batched_request->add_pageloads();
|
| request->set_session_key(request_data.session_key());
|
| // For the timing events, any of them could be zero. Fill the message as a
|
| // best effort.
|
| request->set_allocated_first_request_time(
|
| protobuf_parser::CreateTimestampFromTime(timing.navigation_start)
|
| .release());
|
| if (request_data.original_request_url().is_valid())
|
| request->set_first_request_url(request_data.original_request_url().spec());
|
| if (timing.first_contentful_paint) {
|
| request->set_allocated_time_to_first_contentful_paint(
|
| @@ -59,22 +63,32 @@ std::string SerializeData(const DataReductionProxyData& request_data,
|
| protobuf_parser::CreateDurationFromTimeDelta(
|
| timing.response_start.value())
|
| .release());
|
| }
|
| if (timing.load_event_start) {
|
| request->set_allocated_page_load_time(
|
| protobuf_parser::CreateDurationFromTimeDelta(
|
| timing.load_event_start.value())
|
| .release());
|
| }
|
| + return batched_request;
|
| +}
|
| +
|
| +// Adds |current_time| as the metrics sent time to |request_data|, and returns
|
| +// the serialized request.
|
| +std::string AddTimeAndSerializeRequest(
|
| + RecordPageloadMetricsRequest* request_data,
|
| + base::Time current_time) {
|
| + request_data->set_allocated_metrics_sent_time(
|
| + protobuf_parser::CreateTimestampFromTime(current_time).release());
|
| std::string serialized_request;
|
| - batched_request.SerializeToString(&serialized_request);
|
| + request_data->SerializeToString(&serialized_request);
|
| return serialized_request;
|
| }
|
|
|
| } // namespace
|
|
|
| DataReductionProxyPingbackClient::DataReductionProxyPingbackClient(
|
| net::URLRequestContextGetter* url_request_context)
|
| : url_request_context_(url_request_context),
|
| pingback_url_(util::AddApiKeyToUrl(params::GetPingbackURL())),
|
| pingback_reporting_fraction_(0.0) {}
|
| @@ -83,63 +97,73 @@ DataReductionProxyPingbackClient::~DataReductionProxyPingbackClient() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| }
|
|
|
| void DataReductionProxyPingbackClient::OnURLFetchComplete(
|
| const net::URLFetcher* source) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(source == current_fetcher_.get());
|
| UMA_HISTOGRAM_BOOLEAN(kHistogramSucceeded, source->GetStatus().is_success());
|
| current_fetcher_.reset();
|
| while (!current_fetcher_ && !data_to_send_.empty()) {
|
| - current_fetcher_ = MaybeCreateFetcherForDataAndStart(data_to_send_.front());
|
| + current_fetcher_ =
|
| + MaybeCreateFetcherForDataAndStart(data_to_send_.front().get());
|
| data_to_send_.pop_front();
|
| }
|
| }
|
|
|
| void DataReductionProxyPingbackClient::SendPingback(
|
| const DataReductionProxyData& request_data,
|
| const DataReductionProxyPageLoadTiming& timing) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - std::string serialized_request = SerializeData(request_data, timing);
|
| + std::unique_ptr<RecordPageloadMetricsRequest>
|
| + record_pageload_metrics_request =
|
| + CreateRecordPageloadMetricsRequest(request_data, timing);
|
| if (current_fetcher_.get()) {
|
| - data_to_send_.push_back(serialized_request);
|
| + data_to_send_.push_back(std::move(record_pageload_metrics_request));
|
| } else {
|
| DCHECK(data_to_send_.empty());
|
| - current_fetcher_ = MaybeCreateFetcherForDataAndStart(serialized_request);
|
| + current_fetcher_ = MaybeCreateFetcherForDataAndStart(
|
| + record_pageload_metrics_request.get());
|
| }
|
| }
|
|
|
| std::unique_ptr<net::URLFetcher>
|
| DataReductionProxyPingbackClient::MaybeCreateFetcherForDataAndStart(
|
| - const std::string& request_data) {
|
| + RecordPageloadMetricsRequest* request_data) {
|
| bool send_pingback = ShouldSendPingback();
|
| UMA_HISTOGRAM_BOOLEAN(kHistogramAttempted, send_pingback);
|
| if (!send_pingback)
|
| return nullptr;
|
| + std::string serialized_request =
|
| + AddTimeAndSerializeRequest(request_data, CurrentTime());
|
| std::unique_ptr<net::URLFetcher> fetcher(
|
| net::URLFetcher::Create(pingback_url_, net::URLFetcher::POST, this));
|
| fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY);
|
| - fetcher->SetUploadData("application/x-protobuf", request_data);
|
| + fetcher->SetUploadData("application/x-protobuf", serialized_request);
|
| fetcher->SetRequestContext(url_request_context_);
|
| // Configure max retries to be at most kMaxRetries times for 5xx errors.
|
| static const int kMaxRetries = 5;
|
| fetcher->SetMaxRetriesOn5xx(kMaxRetries);
|
| fetcher->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries);
|
| fetcher->Start();
|
| return fetcher;
|
| }
|
|
|
| bool DataReductionProxyPingbackClient::ShouldSendPingback() const {
|
| return params::IsForcePingbackEnabledViaFlags() ||
|
| GenerateRandomFloat() < pingback_reporting_fraction_;
|
| }
|
|
|
| +base::Time DataReductionProxyPingbackClient::CurrentTime() const {
|
| + return base::Time::Now();
|
| +}
|
| +
|
| float DataReductionProxyPingbackClient::GenerateRandomFloat() const {
|
| return static_cast<float>(base::RandDouble());
|
| }
|
|
|
| void DataReductionProxyPingbackClient::SetPingbackReportingFraction(
|
| float pingback_reporting_fraction) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK_LE(0.0f, pingback_reporting_fraction);
|
| DCHECK_GE(1.0f, pingback_reporting_fraction);
|
| pingback_reporting_fraction_ = pingback_reporting_fraction;
|
|
|