Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_ping back_client.h" | 5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_ping back_client.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/optional.h" | 8 #include "base/optional.h" |
| 9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
| 10 #include "base/time/time.h" | |
| 10 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data .h" | 11 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data .h" |
| 11 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_ load_timing.h" | 12 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_ load_timing.h" |
| 12 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_param s.h" | 13 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_param s.h" |
| 13 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util. h" | 14 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util. h" |
| 14 #include "components/data_reduction_proxy/proto/client_config.pb.h" | 15 #include "components/data_reduction_proxy/proto/client_config.pb.h" |
| 15 #include "components/data_reduction_proxy/proto/pageload_metrics.pb.h" | 16 #include "components/data_reduction_proxy/proto/pageload_metrics.pb.h" |
| 16 #include "net/base/load_flags.h" | 17 #include "net/base/load_flags.h" |
| 17 #include "net/url_request/url_fetcher.h" | 18 #include "net/url_request/url_fetcher.h" |
| 18 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
| 19 #include "net/url_request/url_request_status.h" | 20 #include "net/url_request/url_request_status.h" |
| 20 #include "url/gurl.h" | 21 #include "url/gurl.h" |
| 21 | 22 |
| 22 namespace data_reduction_proxy { | 23 namespace data_reduction_proxy { |
| 23 | 24 |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| 26 static const char kHistogramSucceeded[] = | 27 static const char kHistogramSucceeded[] = |
| 27 "DataReductionProxy.Pingback.Succeeded"; | 28 "DataReductionProxy.Pingback.Succeeded"; |
| 28 static const char kHistogramAttempted[] = | 29 static const char kHistogramAttempted[] = |
| 29 "DataReductionProxy.Pingback.Attempted"; | 30 "DataReductionProxy.Pingback.Attempted"; |
| 30 | 31 |
| 31 // Creates a PageloadMetrics protobuf for this page load and serializes to a | 32 // Creates a RecordPageloadMetrics protobuf for this page load based on page |
| 32 // string. | 33 // timing and data reduction proxy state. |
| 33 std::string SerializeData(const DataReductionProxyData& request_data, | 34 std::unique_ptr<RecordPageloadMetricsRequest> |
| 34 const DataReductionProxyPageLoadTiming& timing) { | 35 CreateRecordPageloadMetricsRequest( |
| 35 RecordPageloadMetricsRequest batched_request; | 36 const DataReductionProxyData& request_data, |
| 36 PageloadMetrics* request = batched_request.add_pageloads(); | 37 const DataReductionProxyPageLoadTiming& timing) { |
| 38 std::unique_ptr<RecordPageloadMetricsRequest> batched_request( | |
| 39 new RecordPageloadMetricsRequest()); | |
| 40 PageloadMetrics* request = batched_request->add_pageloads(); | |
| 37 request->set_session_key(request_data.session_key()); | 41 request->set_session_key(request_data.session_key()); |
| 38 // For the timing events, any of them could be zero. Fill the message as a | 42 // For the timing events, any of them could be zero. Fill the message as a |
| 39 // best effort. | 43 // best effort. |
| 40 request->set_allocated_first_request_time( | 44 request->set_allocated_first_request_time( |
| 41 protobuf_parser::CreateTimestampFromTime(timing.navigation_start) | 45 protobuf_parser::CreateTimestampFromTime(timing.navigation_start) |
| 42 .release()); | 46 .release()); |
| 43 if (request_data.original_request_url().is_valid()) | 47 if (request_data.original_request_url().is_valid()) |
| 44 request->set_first_request_url(request_data.original_request_url().spec()); | 48 request->set_first_request_url(request_data.original_request_url().spec()); |
| 45 if (timing.first_contentful_paint) { | 49 if (timing.first_contentful_paint) { |
| 46 request->set_allocated_time_to_first_contentful_paint( | 50 request->set_allocated_time_to_first_contentful_paint( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 59 protobuf_parser::CreateDurationFromTimeDelta( | 63 protobuf_parser::CreateDurationFromTimeDelta( |
| 60 timing.response_start.value()) | 64 timing.response_start.value()) |
| 61 .release()); | 65 .release()); |
| 62 } | 66 } |
| 63 if (timing.load_event_start) { | 67 if (timing.load_event_start) { |
| 64 request->set_allocated_page_load_time( | 68 request->set_allocated_page_load_time( |
| 65 protobuf_parser::CreateDurationFromTimeDelta( | 69 protobuf_parser::CreateDurationFromTimeDelta( |
| 66 timing.load_event_start.value()) | 70 timing.load_event_start.value()) |
| 67 .release()); | 71 .release()); |
| 68 } | 72 } |
| 73 return batched_request; | |
|
tbansal1
2016/07/15 17:44:04
return std::move(batched_request);
e.g., https://c
RyanSturm
2016/07/15 18:16:03
Acknowledged.
| |
| 74 } | |
| 75 | |
| 76 // Adds |current_time| as the metrics sent time to |request_data|, and returns | |
| 77 // the serialized request. | |
| 78 std::string AddTimeAndSerializeRequest( | |
| 79 RecordPageloadMetricsRequest* request_data, | |
| 80 base::Time current_time) { | |
| 81 request_data->set_allocated_metrics_sent_time( | |
| 82 protobuf_parser::CreateTimestampFromTime(current_time).release()); | |
| 69 std::string serialized_request; | 83 std::string serialized_request; |
| 70 batched_request.SerializeToString(&serialized_request); | 84 request_data->SerializeToString(&serialized_request); |
| 71 return serialized_request; | 85 return serialized_request; |
| 72 } | 86 } |
| 73 | 87 |
| 74 } // namespace | 88 } // namespace |
| 75 | 89 |
| 76 DataReductionProxyPingbackClient::DataReductionProxyPingbackClient( | 90 DataReductionProxyPingbackClient::DataReductionProxyPingbackClient( |
| 77 net::URLRequestContextGetter* url_request_context) | 91 net::URLRequestContextGetter* url_request_context) |
| 78 : url_request_context_(url_request_context), | 92 : url_request_context_(url_request_context), |
| 79 pingback_url_(util::AddApiKeyToUrl(params::GetPingbackURL())), | 93 pingback_url_(util::AddApiKeyToUrl(params::GetPingbackURL())), |
| 80 pingback_reporting_fraction_(0.0) {} | 94 pingback_reporting_fraction_(0.0) {} |
| 81 | 95 |
| 82 DataReductionProxyPingbackClient::~DataReductionProxyPingbackClient() { | 96 DataReductionProxyPingbackClient::~DataReductionProxyPingbackClient() { |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); | 97 DCHECK(thread_checker_.CalledOnValidThread()); |
| 84 } | 98 } |
| 85 | 99 |
| 86 void DataReductionProxyPingbackClient::OnURLFetchComplete( | 100 void DataReductionProxyPingbackClient::OnURLFetchComplete( |
| 87 const net::URLFetcher* source) { | 101 const net::URLFetcher* source) { |
| 88 DCHECK(thread_checker_.CalledOnValidThread()); | 102 DCHECK(thread_checker_.CalledOnValidThread()); |
| 89 DCHECK(source == current_fetcher_.get()); | 103 DCHECK(source == current_fetcher_.get()); |
| 90 UMA_HISTOGRAM_BOOLEAN(kHistogramSucceeded, source->GetStatus().is_success()); | 104 UMA_HISTOGRAM_BOOLEAN(kHistogramSucceeded, source->GetStatus().is_success()); |
| 91 current_fetcher_.reset(); | 105 current_fetcher_.reset(); |
| 92 while (!current_fetcher_ && !data_to_send_.empty()) { | 106 while (!current_fetcher_ && !data_to_send_.empty()) { |
| 93 current_fetcher_ = MaybeCreateFetcherForDataAndStart(data_to_send_.front()); | 107 current_fetcher_ = |
| 108 MaybeCreateFetcherForDataAndStart(data_to_send_.front().get()); | |
| 94 data_to_send_.pop_front(); | 109 data_to_send_.pop_front(); |
| 95 } | 110 } |
| 96 } | 111 } |
| 97 | 112 |
| 98 void DataReductionProxyPingbackClient::SendPingback( | 113 void DataReductionProxyPingbackClient::SendPingback( |
| 99 const DataReductionProxyData& request_data, | 114 const DataReductionProxyData& request_data, |
| 100 const DataReductionProxyPageLoadTiming& timing) { | 115 const DataReductionProxyPageLoadTiming& timing) { |
| 101 DCHECK(thread_checker_.CalledOnValidThread()); | 116 DCHECK(thread_checker_.CalledOnValidThread()); |
| 102 std::string serialized_request = SerializeData(request_data, timing); | 117 std::unique_ptr<RecordPageloadMetricsRequest> |
| 118 record_pageload_metrics_request = | |
| 119 CreateRecordPageloadMetricsRequest(request_data, timing); | |
| 103 if (current_fetcher_.get()) { | 120 if (current_fetcher_.get()) { |
| 104 data_to_send_.push_back(serialized_request); | 121 data_to_send_.push_back(std::move(record_pageload_metrics_request)); |
| 105 } else { | 122 } else { |
| 106 DCHECK(data_to_send_.empty()); | 123 DCHECK(data_to_send_.empty()); |
| 107 current_fetcher_ = MaybeCreateFetcherForDataAndStart(serialized_request); | 124 current_fetcher_ = MaybeCreateFetcherForDataAndStart( |
| 125 record_pageload_metrics_request.get()); | |
| 108 } | 126 } |
| 109 } | 127 } |
| 110 | 128 |
| 111 std::unique_ptr<net::URLFetcher> | 129 std::unique_ptr<net::URLFetcher> |
| 112 DataReductionProxyPingbackClient::MaybeCreateFetcherForDataAndStart( | 130 DataReductionProxyPingbackClient::MaybeCreateFetcherForDataAndStart( |
| 113 const std::string& request_data) { | 131 RecordPageloadMetricsRequest* request_data) { |
| 114 bool send_pingback = ShouldSendPingback(); | 132 bool send_pingback = ShouldSendPingback(); |
| 115 UMA_HISTOGRAM_BOOLEAN(kHistogramAttempted, send_pingback); | 133 UMA_HISTOGRAM_BOOLEAN(kHistogramAttempted, send_pingback); |
| 116 if (!send_pingback) | 134 if (!send_pingback) |
| 117 return nullptr; | 135 return nullptr; |
| 136 std::string serialized_request = | |
| 137 AddTimeAndSerializeRequest(request_data, CurrentTime()); | |
| 118 std::unique_ptr<net::URLFetcher> fetcher( | 138 std::unique_ptr<net::URLFetcher> fetcher( |
| 119 net::URLFetcher::Create(pingback_url_, net::URLFetcher::POST, this)); | 139 net::URLFetcher::Create(pingback_url_, net::URLFetcher::POST, this)); |
| 120 fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY); | 140 fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY); |
| 121 fetcher->SetUploadData("application/x-protobuf", request_data); | 141 fetcher->SetUploadData("application/x-protobuf", serialized_request); |
| 122 fetcher->SetRequestContext(url_request_context_); | 142 fetcher->SetRequestContext(url_request_context_); |
| 123 // Configure max retries to be at most kMaxRetries times for 5xx errors. | 143 // Configure max retries to be at most kMaxRetries times for 5xx errors. |
| 124 static const int kMaxRetries = 5; | 144 static const int kMaxRetries = 5; |
| 125 fetcher->SetMaxRetriesOn5xx(kMaxRetries); | 145 fetcher->SetMaxRetriesOn5xx(kMaxRetries); |
| 126 fetcher->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries); | 146 fetcher->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries); |
| 127 fetcher->Start(); | 147 fetcher->Start(); |
| 128 return fetcher; | 148 return fetcher; |
| 129 } | 149 } |
| 130 | 150 |
| 131 bool DataReductionProxyPingbackClient::ShouldSendPingback() const { | 151 bool DataReductionProxyPingbackClient::ShouldSendPingback() const { |
| 132 return params::IsForcePingbackEnabledViaFlags() || | 152 return params::IsForcePingbackEnabledViaFlags() || |
| 133 GenerateRandomFloat() < pingback_reporting_fraction_; | 153 GenerateRandomFloat() < pingback_reporting_fraction_; |
| 134 } | 154 } |
| 135 | 155 |
| 156 base::Time DataReductionProxyPingbackClient::CurrentTime() const { | |
| 157 return base::Time::Now(); | |
| 158 } | |
| 159 | |
| 136 float DataReductionProxyPingbackClient::GenerateRandomFloat() const { | 160 float DataReductionProxyPingbackClient::GenerateRandomFloat() const { |
| 137 return static_cast<float>(base::RandDouble()); | 161 return static_cast<float>(base::RandDouble()); |
| 138 } | 162 } |
| 139 | 163 |
| 140 void DataReductionProxyPingbackClient::SetPingbackReportingFraction( | 164 void DataReductionProxyPingbackClient::SetPingbackReportingFraction( |
| 141 float pingback_reporting_fraction) { | 165 float pingback_reporting_fraction) { |
| 142 DCHECK(thread_checker_.CalledOnValidThread()); | 166 DCHECK(thread_checker_.CalledOnValidThread()); |
| 143 DCHECK_LE(0.0f, pingback_reporting_fraction); | 167 DCHECK_LE(0.0f, pingback_reporting_fraction); |
| 144 DCHECK_GE(1.0f, pingback_reporting_fraction); | 168 DCHECK_GE(1.0f, pingback_reporting_fraction); |
| 145 pingback_reporting_fraction_ = pingback_reporting_fraction; | 169 pingback_reporting_fraction_ = pingback_reporting_fraction; |
| 146 } | 170 } |
| 147 | 171 |
| 148 } // namespace data_reduction_proxy | 172 } // namespace data_reduction_proxy |
| OLD | NEW |