OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/browser/data_reduction_proxy_usage_sta
ts.h" | 5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_sta
ts.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/metrics/sparse_histogram.h" | 11 #include "base/metrics/sparse_histogram.h" |
| 12 #include "base/prefs/pref_member.h" |
12 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h" | 13 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h" |
13 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/http/http_response_headers.h" |
| 16 #include "net/http/http_status_code.h" |
14 #include "net/proxy/proxy_retry_info.h" | 17 #include "net/proxy/proxy_retry_info.h" |
15 #include "net/proxy/proxy_server.h" | 18 #include "net/proxy/proxy_server.h" |
16 #include "net/proxy/proxy_service.h" | 19 #include "net/proxy/proxy_service.h" |
17 #include "net/url_request/url_request.h" | 20 #include "net/url_request/url_request.h" |
18 #include "net/url_request/url_request_context.h" | 21 #include "net/url_request/url_request_context.h" |
19 | 22 |
20 using base::MessageLoopProxy; | 23 using base::MessageLoopProxy; |
21 using net::HostPortPair; | 24 using net::HostPortPair; |
22 using net::ProxyServer; | 25 using net::ProxyServer; |
23 using net::ProxyService; | 26 using net::ProxyService; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 if (is_primary) { | 72 if (is_primary) { |
70 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypePrimary", | 73 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypePrimary", |
71 bypass_type, BYPASS_EVENT_TYPE_MAX); | 74 bypass_type, BYPASS_EVENT_TYPE_MAX); |
72 } else { | 75 } else { |
73 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypeFallback", | 76 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypeFallback", |
74 bypass_type, BYPASS_EVENT_TYPE_MAX); | 77 bypass_type, BYPASS_EVENT_TYPE_MAX); |
75 } | 78 } |
76 } | 79 } |
77 } | 80 } |
78 | 81 |
| 82 // static |
| 83 void DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode( |
| 84 bool is_primary, |
| 85 const net::HttpResponseHeaders* headers) { |
| 86 if (HasDataReductionProxyViaHeader(headers, NULL)) { |
| 87 // The data reduction proxy via header is present, so don't record anything. |
| 88 return; |
| 89 } |
| 90 |
| 91 if (is_primary) { |
| 92 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 93 "DataReductionProxy.MissingViaHeader.ResponseCode.Primary", |
| 94 headers->response_code()); |
| 95 } else { |
| 96 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 97 "DataReductionProxy.MissingViaHeader.ResponseCode.Fallback", |
| 98 headers->response_code()); |
| 99 } |
| 100 } |
| 101 |
79 DataReductionProxyUsageStats::DataReductionProxyUsageStats( | 102 DataReductionProxyUsageStats::DataReductionProxyUsageStats( |
80 DataReductionProxyParams* params, | 103 DataReductionProxyParams* params, |
81 const scoped_refptr<MessageLoopProxy>& ui_thread_proxy) | 104 const scoped_refptr<MessageLoopProxy>& ui_thread_proxy) |
82 : data_reduction_proxy_params_(params), | 105 : data_reduction_proxy_params_(params), |
83 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), | 106 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), |
84 triggering_request_(true), | 107 triggering_request_(true), |
85 ui_thread_proxy_(ui_thread_proxy), | 108 ui_thread_proxy_(ui_thread_proxy), |
86 successful_requests_through_proxy_count_(0), | 109 successful_requests_through_proxy_count_(0), |
87 proxy_net_errors_count_(0), | 110 proxy_net_errors_count_(0), |
88 unavailable_(false) { | 111 unavailable_(false) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 if (!unavailable_callback_.is_null()) | 161 if (!unavailable_callback_.is_null()) |
139 unavailable_callback_.Run(unavailable); | 162 unavailable_callback_.Run(unavailable); |
140 } | 163 } |
141 | 164 |
142 void DataReductionProxyUsageStats::SetBypassType( | 165 void DataReductionProxyUsageStats::SetBypassType( |
143 DataReductionProxyBypassType type) { | 166 DataReductionProxyBypassType type) { |
144 last_bypass_type_ = type; | 167 last_bypass_type_ = type; |
145 triggering_request_ = true; | 168 triggering_request_ = true; |
146 } | 169 } |
147 | 170 |
148 void DataReductionProxyUsageStats::RecordBypassedBytesHistograms( | 171 void DataReductionProxyUsageStats::RecordBytesHistograms( |
149 net::URLRequest& request, | 172 net::URLRequest* request, |
150 const BooleanPrefMember& data_reduction_proxy_enabled, | 173 const BooleanPrefMember& data_reduction_proxy_enabled, |
151 const net::ProxyConfig& data_reduction_proxy_config) { | 174 const net::ProxyConfig& data_reduction_proxy_config) { |
152 int64 content_length = request.received_response_content_length(); | 175 RecordBypassedBytesHistograms(request, data_reduction_proxy_enabled, |
| 176 data_reduction_proxy_config); |
| 177 RecordMissingViaHeaderBytes(request); |
| 178 } |
| 179 |
| 180 void DataReductionProxyUsageStats::RecordBypassedBytesHistograms( |
| 181 net::URLRequest* request, |
| 182 const BooleanPrefMember& data_reduction_proxy_enabled, |
| 183 const net::ProxyConfig& data_reduction_proxy_config) { |
| 184 int64 content_length = request->received_response_content_length(); |
153 | 185 |
154 if (data_reduction_proxy_enabled.GetValue() && | 186 if (data_reduction_proxy_enabled.GetValue() && |
155 !data_reduction_proxy_config.Equals( | 187 !data_reduction_proxy_config.Equals( |
156 request.context()->proxy_service()->config())) { | 188 request->context()->proxy_service()->config())) { |
157 RecordBypassedBytes(last_bypass_type_, | 189 RecordBypassedBytes(last_bypass_type_, |
158 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, | 190 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, |
159 content_length); | 191 content_length); |
160 return; | 192 return; |
161 } | 193 } |
162 | 194 |
163 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(&request, NULL)) { | 195 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(request, NULL)) { |
164 RecordBypassedBytes(last_bypass_type_, | 196 RecordBypassedBytes(last_bypass_type_, |
165 DataReductionProxyUsageStats::NOT_BYPASSED, | 197 DataReductionProxyUsageStats::NOT_BYPASSED, |
166 content_length); | 198 content_length); |
167 return; | 199 return; |
168 } | 200 } |
169 | 201 |
170 if (data_reduction_proxy_enabled.GetValue() && | 202 if (data_reduction_proxy_enabled.GetValue() && |
171 request.url().SchemeIs(url::kHttpsScheme)) { | 203 request->url().SchemeIs(url::kHttpsScheme)) { |
172 RecordBypassedBytes(last_bypass_type_, | 204 RecordBypassedBytes(last_bypass_type_, |
173 DataReductionProxyUsageStats::SSL, | 205 DataReductionProxyUsageStats::SSL, |
174 content_length); | 206 content_length); |
175 return; | 207 return; |
176 } | 208 } |
177 | 209 |
178 if (data_reduction_proxy_enabled.GetValue() && | 210 if (data_reduction_proxy_enabled.GetValue() && |
179 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( | 211 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( |
180 request, data_reduction_proxy_config)) { | 212 *request, data_reduction_proxy_config)) { |
181 RecordBypassedBytes(last_bypass_type_, | 213 RecordBypassedBytes(last_bypass_type_, |
182 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, | 214 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, |
183 content_length); | 215 content_length); |
184 return; | 216 return; |
185 } | 217 } |
186 | 218 |
187 // Only record separate triggering request UMA for short, medium, and long | 219 // Only record separate triggering request UMA for short, medium, and long |
188 // bypass events. | 220 // bypass events. |
189 if (triggering_request_ && | 221 if (triggering_request_ && |
190 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || | 222 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || |
191 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || | 223 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || |
192 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { | 224 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { |
193 std::string mime_type; | 225 std::string mime_type; |
194 request.GetMimeType(&mime_type); | 226 request->GetMimeType(&mime_type); |
195 // MIME types are named by <media-type>/<subtype>. Check to see if the | 227 // MIME types are named by <media-type>/<subtype>. Check to see if the |
196 // media type is audio or video. Only record when triggered by short bypass, | 228 // media type is audio or video. Only record when triggered by short bypass, |
197 // there isn't an audio or video bucket for medium or long bypasses. | 229 // there isn't an audio or video bucket for medium or long bypasses. |
198 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && | 230 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && |
199 (mime_type.compare(0, 6, "audio/") == 0 || | 231 (mime_type.compare(0, 6, "audio/") == 0 || |
200 mime_type.compare(0, 6, "video/") == 0)) { | 232 mime_type.compare(0, 6, "video/") == 0)) { |
201 RecordBypassedBytes(last_bypass_type_, | 233 RecordBypassedBytes(last_bypass_type_, |
202 DataReductionProxyUsageStats::AUDIO_VIDEO, | 234 DataReductionProxyUsageStats::AUDIO_VIDEO, |
203 content_length); | 235 content_length); |
204 return; | 236 return; |
205 } | 237 } |
206 | 238 |
207 RecordBypassedBytes(last_bypass_type_, | 239 RecordBypassedBytes(last_bypass_type_, |
208 DataReductionProxyUsageStats::TRIGGERING_REQUEST, | 240 DataReductionProxyUsageStats::TRIGGERING_REQUEST, |
209 content_length); | 241 content_length); |
210 triggering_request_ = false; | 242 triggering_request_ = false; |
211 return; | 243 return; |
212 } | 244 } |
213 | 245 |
214 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { | 246 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { |
215 RecordBypassedBytes(last_bypass_type_, | 247 RecordBypassedBytes(last_bypass_type_, |
216 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, | 248 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, |
217 content_length); | 249 content_length); |
218 return; | 250 return; |
219 } | 251 } |
220 | 252 |
221 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(request, | 253 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(*request, |
222 NULL)) { | 254 NULL)) { |
223 RecordBypassedBytes(last_bypass_type_, | 255 RecordBypassedBytes(last_bypass_type_, |
224 DataReductionProxyUsageStats::NETWORK_ERROR, | 256 DataReductionProxyUsageStats::NETWORK_ERROR, |
225 content_length); | 257 content_length); |
226 } | 258 } |
227 } | 259 } |
228 | 260 |
229 void DataReductionProxyUsageStats::OnProxyFallback( | 261 void DataReductionProxyUsageStats::OnProxyFallback( |
230 const net::ProxyServer& bypassed_proxy, | 262 const net::ProxyServer& bypassed_proxy, |
231 int net_error) { | 263 int net_error) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 "Status503HttpServiceUnavailable", | 403 "Status503HttpServiceUnavailable", |
372 content_length); | 404 content_length); |
373 break; | 405 break; |
374 default: | 406 default: |
375 break; | 407 break; |
376 } | 408 } |
377 break; | 409 break; |
378 } | 410 } |
379 } | 411 } |
380 | 412 |
| 413 void DataReductionProxyUsageStats::RecordMissingViaHeaderBytes( |
| 414 URLRequest* request) { |
| 415 // Responses that were served from cache should have been filtered out |
| 416 // already. |
| 417 DCHECK(!request->was_cached()); |
| 418 |
| 419 if (!data_reduction_proxy_params_->WasDataReductionProxyUsed(request, NULL) || |
| 420 HasDataReductionProxyViaHeader(request->response_headers(), NULL)) { |
| 421 // Only track requests that used the data reduction proxy and had responses |
| 422 // that were missing the data reduction proxy via header. |
| 423 return; |
| 424 } |
| 425 |
| 426 if (request->GetResponseCode() >= net::HTTP_BAD_REQUEST && |
| 427 request->GetResponseCode() < net::HTTP_INTERNAL_SERVER_ERROR) { |
| 428 // Track 4xx responses that are missing via headers separately. |
| 429 UMA_HISTOGRAM_COUNTS("DataReductionProxy.MissingViaHeader.Bytes.4xx", |
| 430 request->received_response_content_length()); |
| 431 } else { |
| 432 UMA_HISTOGRAM_COUNTS("DataReductionProxy.MissingViaHeader.Bytes.Other", |
| 433 request->received_response_content_length()); |
| 434 } |
| 435 } |
| 436 |
381 } // namespace data_reduction_proxy | 437 } // namespace data_reduction_proxy |
382 | 438 |
383 | 439 |
OLD | NEW |