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; |
| 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 |