| 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" | |
| 13 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h" | 12 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h" |
| 14 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 15 #include "net/http/http_response_headers.h" | |
| 16 #include "net/http/http_status_code.h" | |
| 17 #include "net/proxy/proxy_retry_info.h" | 14 #include "net/proxy/proxy_retry_info.h" |
| 18 #include "net/proxy/proxy_server.h" | 15 #include "net/proxy/proxy_server.h" |
| 19 #include "net/proxy/proxy_service.h" | 16 #include "net/proxy/proxy_service.h" |
| 20 #include "net/url_request/url_request.h" | 17 #include "net/url_request/url_request.h" |
| 21 #include "net/url_request/url_request_context.h" | 18 #include "net/url_request/url_request_context.h" |
| 22 | 19 |
| 23 using base::MessageLoopProxy; | 20 using base::MessageLoopProxy; |
| 24 using net::HostPortPair; | 21 using net::HostPortPair; |
| 25 using net::ProxyServer; | 22 using net::ProxyServer; |
| 26 using net::ProxyService; | 23 using net::ProxyService; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 if (is_primary) { | 69 if (is_primary) { |
| 73 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypePrimary", | 70 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypePrimary", |
| 74 bypass_type, BYPASS_EVENT_TYPE_MAX); | 71 bypass_type, BYPASS_EVENT_TYPE_MAX); |
| 75 } else { | 72 } else { |
| 76 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypeFallback", | 73 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypeFallback", |
| 77 bypass_type, BYPASS_EVENT_TYPE_MAX); | 74 bypass_type, BYPASS_EVENT_TYPE_MAX); |
| 78 } | 75 } |
| 79 } | 76 } |
| 80 } | 77 } |
| 81 | 78 |
| 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 | |
| 102 DataReductionProxyUsageStats::DataReductionProxyUsageStats( | 79 DataReductionProxyUsageStats::DataReductionProxyUsageStats( |
| 103 DataReductionProxyParams* params, | 80 DataReductionProxyParams* params, |
| 104 const scoped_refptr<MessageLoopProxy>& ui_thread_proxy) | 81 const scoped_refptr<MessageLoopProxy>& ui_thread_proxy) |
| 105 : data_reduction_proxy_params_(params), | 82 : data_reduction_proxy_params_(params), |
| 106 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), | 83 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), |
| 107 triggering_request_(true), | 84 triggering_request_(true), |
| 108 ui_thread_proxy_(ui_thread_proxy), | 85 ui_thread_proxy_(ui_thread_proxy), |
| 109 successful_requests_through_proxy_count_(0), | 86 successful_requests_through_proxy_count_(0), |
| 110 proxy_net_errors_count_(0), | 87 proxy_net_errors_count_(0), |
| 111 unavailable_(false) { | 88 unavailable_(false) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 if (!unavailable_callback_.is_null()) | 138 if (!unavailable_callback_.is_null()) |
| 162 unavailable_callback_.Run(unavailable); | 139 unavailable_callback_.Run(unavailable); |
| 163 } | 140 } |
| 164 | 141 |
| 165 void DataReductionProxyUsageStats::SetBypassType( | 142 void DataReductionProxyUsageStats::SetBypassType( |
| 166 DataReductionProxyBypassType type) { | 143 DataReductionProxyBypassType type) { |
| 167 last_bypass_type_ = type; | 144 last_bypass_type_ = type; |
| 168 triggering_request_ = true; | 145 triggering_request_ = true; |
| 169 } | 146 } |
| 170 | 147 |
| 171 void DataReductionProxyUsageStats::RecordBytesHistograms( | 148 void DataReductionProxyUsageStats::RecordBypassedBytesHistograms( |
| 172 net::URLRequest* request, | 149 net::URLRequest& request, |
| 173 const BooleanPrefMember& data_reduction_proxy_enabled, | 150 const BooleanPrefMember& data_reduction_proxy_enabled, |
| 174 const net::ProxyConfig& data_reduction_proxy_config) { | 151 const net::ProxyConfig& data_reduction_proxy_config) { |
| 175 RecordBypassedBytesHistograms(request, data_reduction_proxy_enabled, | 152 int64 content_length = request.received_response_content_length(); |
| 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(); | |
| 185 | 153 |
| 186 if (data_reduction_proxy_enabled.GetValue() && | 154 if (data_reduction_proxy_enabled.GetValue() && |
| 187 !data_reduction_proxy_config.Equals( | 155 !data_reduction_proxy_config.Equals( |
| 188 request->context()->proxy_service()->config())) { | 156 request.context()->proxy_service()->config())) { |
| 189 RecordBypassedBytes(last_bypass_type_, | 157 RecordBypassedBytes(last_bypass_type_, |
| 190 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, | 158 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, |
| 191 content_length); | 159 content_length); |
| 192 return; | 160 return; |
| 193 } | 161 } |
| 194 | 162 |
| 195 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(request, NULL)) { | 163 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(&request, NULL)) { |
| 196 RecordBypassedBytes(last_bypass_type_, | 164 RecordBypassedBytes(last_bypass_type_, |
| 197 DataReductionProxyUsageStats::NOT_BYPASSED, | 165 DataReductionProxyUsageStats::NOT_BYPASSED, |
| 198 content_length); | 166 content_length); |
| 199 return; | 167 return; |
| 200 } | 168 } |
| 201 | 169 |
| 202 if (data_reduction_proxy_enabled.GetValue() && | 170 if (data_reduction_proxy_enabled.GetValue() && |
| 203 request->url().SchemeIs(url::kHttpsScheme)) { | 171 request.url().SchemeIs(url::kHttpsScheme)) { |
| 204 RecordBypassedBytes(last_bypass_type_, | 172 RecordBypassedBytes(last_bypass_type_, |
| 205 DataReductionProxyUsageStats::SSL, | 173 DataReductionProxyUsageStats::SSL, |
| 206 content_length); | 174 content_length); |
| 207 return; | 175 return; |
| 208 } | 176 } |
| 209 | 177 |
| 210 if (data_reduction_proxy_enabled.GetValue() && | 178 if (data_reduction_proxy_enabled.GetValue() && |
| 211 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( | 179 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( |
| 212 *request, data_reduction_proxy_config)) { | 180 request, data_reduction_proxy_config)) { |
| 213 RecordBypassedBytes(last_bypass_type_, | 181 RecordBypassedBytes(last_bypass_type_, |
| 214 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, | 182 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, |
| 215 content_length); | 183 content_length); |
| 216 return; | 184 return; |
| 217 } | 185 } |
| 218 | 186 |
| 219 // Only record separate triggering request UMA for short, medium, and long | 187 // Only record separate triggering request UMA for short, medium, and long |
| 220 // bypass events. | 188 // bypass events. |
| 221 if (triggering_request_ && | 189 if (triggering_request_ && |
| 222 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || | 190 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || |
| 223 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || | 191 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || |
| 224 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { | 192 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { |
| 225 std::string mime_type; | 193 std::string mime_type; |
| 226 request->GetMimeType(&mime_type); | 194 request.GetMimeType(&mime_type); |
| 227 // MIME types are named by <media-type>/<subtype>. Check to see if the | 195 // MIME types are named by <media-type>/<subtype>. Check to see if the |
| 228 // media type is audio or video. Only record when triggered by short bypass, | 196 // media type is audio or video. Only record when triggered by short bypass, |
| 229 // there isn't an audio or video bucket for medium or long bypasses. | 197 // there isn't an audio or video bucket for medium or long bypasses. |
| 230 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && | 198 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && |
| 231 (mime_type.compare(0, 6, "audio/") == 0 || | 199 (mime_type.compare(0, 6, "audio/") == 0 || |
| 232 mime_type.compare(0, 6, "video/") == 0)) { | 200 mime_type.compare(0, 6, "video/") == 0)) { |
| 233 RecordBypassedBytes(last_bypass_type_, | 201 RecordBypassedBytes(last_bypass_type_, |
| 234 DataReductionProxyUsageStats::AUDIO_VIDEO, | 202 DataReductionProxyUsageStats::AUDIO_VIDEO, |
| 235 content_length); | 203 content_length); |
| 236 return; | 204 return; |
| 237 } | 205 } |
| 238 | 206 |
| 239 RecordBypassedBytes(last_bypass_type_, | 207 RecordBypassedBytes(last_bypass_type_, |
| 240 DataReductionProxyUsageStats::TRIGGERING_REQUEST, | 208 DataReductionProxyUsageStats::TRIGGERING_REQUEST, |
| 241 content_length); | 209 content_length); |
| 242 triggering_request_ = false; | 210 triggering_request_ = false; |
| 243 return; | 211 return; |
| 244 } | 212 } |
| 245 | 213 |
| 246 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { | 214 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { |
| 247 RecordBypassedBytes(last_bypass_type_, | 215 RecordBypassedBytes(last_bypass_type_, |
| 248 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, | 216 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, |
| 249 content_length); | 217 content_length); |
| 250 return; | 218 return; |
| 251 } | 219 } |
| 252 | 220 |
| 253 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(*request, | 221 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(request, |
| 254 NULL)) { | 222 NULL)) { |
| 255 RecordBypassedBytes(last_bypass_type_, | 223 RecordBypassedBytes(last_bypass_type_, |
| 256 DataReductionProxyUsageStats::NETWORK_ERROR, | 224 DataReductionProxyUsageStats::NETWORK_ERROR, |
| 257 content_length); | 225 content_length); |
| 258 } | 226 } |
| 259 } | 227 } |
| 260 | 228 |
| 261 void DataReductionProxyUsageStats::OnProxyFallback( | 229 void DataReductionProxyUsageStats::OnProxyFallback( |
| 262 const net::ProxyServer& bypassed_proxy, | 230 const net::ProxyServer& bypassed_proxy, |
| 263 int net_error) { | 231 int net_error) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 "Status503HttpServiceUnavailable", | 371 "Status503HttpServiceUnavailable", |
| 404 content_length); | 372 content_length); |
| 405 break; | 373 break; |
| 406 default: | 374 default: |
| 407 break; | 375 break; |
| 408 } | 376 } |
| 409 break; | 377 break; |
| 410 } | 378 } |
| 411 } | 379 } |
| 412 | 380 |
| 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 | |
| 437 } // namespace data_reduction_proxy | 381 } // namespace data_reduction_proxy |
| 438 | 382 |
| 439 | 383 |
| OLD | NEW |