diff options
-rw-r--r-- | chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc | 57 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 57 | ||||
-rw-r--r-- | net/proxy/proxy_server.cc | 15 | ||||
-rw-r--r-- | net/proxy/proxy_server.h | 8 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 33 | ||||
-rw-r--r-- | net/proxy/proxy_service.h | 29 | ||||
-rw-r--r-- | tools/metrics/histograms/histograms.xml | 38 |
7 files changed, 206 insertions, 31 deletions
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc index 6f71581..aa4416b 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc @@ -50,6 +50,36 @@ enum ProxyStartupState { PROXY_STARTUP_STATE_COUNT, }; +// Key of the UMA DataReductionProxy.ProbeURL histogram. +const char kUMAProxyProbeURL[] = "DataReductionProxy.ProbeURL"; +// Values of the UMA DataReductionProxy.ProbeURL histogram. +// This enum must remain synchronized with DataReductionProxyProbeURLFetchResult +// in metrics/histograms/histograms.xml. +enum ProbeURLFetchResult { + // The probe failed because the internet was disconnected. + INTERNET_DISCONNECTED = 0, + + // The probe failed for any other reason, and as a result, the proxy was + // disabled. + FAILED_PROXY_DISABLED, + + // The probe failed, but the proxy was already disabled. + FAILED_PROXY_ALREADY_DISABLED, + + // THe probe succeeded, and as a result the proxy was enabled. + SUCCEEDED_PROXY_ENABLED, + + // The probe succeeded, but the proxy was already enabled. + SUCCEEDED_PROXY_ALREADY_ENABLED, + + // This must always be last. + FETCH_RESULT_COUNT +}; + +void RecordProbeURLFetchResult(ProbeURLFetchResult result) { + UMA_HISTOGRAM_ENUMERATION(kUMAProxyProbeURL, result, FETCH_RESULT_COUNT); +} + const char kEnabled[] = "Enabled"; // TODO(marq): Factor this string out into a constant here and in @@ -320,6 +350,7 @@ void DataReductionProxySettings::OnURLFetchComplete( net::URLRequestStatus status = source->GetStatus(); if (status.status() == net::URLRequestStatus::FAILED && status.error() == net::ERR_INTERNET_DISCONNECTED) { + RecordProbeURLFetchResult(INTERNET_DISCONNECTED); return; } @@ -329,20 +360,30 @@ void DataReductionProxySettings::OnURLFetchComplete( if ("OK" == response.substr(0, 2)) { DVLOG(1) << "The data reduction proxy is not blocked."; - if (enabled_by_user_ && disabled_by_carrier_) { - // The user enabled the proxy, but sometime previously in the session, - // the network operator had blocked the proxy. Now that the network - // operator is unblocking it, configure it to the user's desires. - SetProxyConfigs(true, false); + if (enabled_by_user_) { + if (disabled_by_carrier_) { + // The user enabled the proxy, but sometime previously in the session, + // the network operator had blocked the proxy. Now that the network + // operator is unblocking it, configure it to the user's desires. + SetProxyConfigs(true, false); + RecordProbeURLFetchResult(SUCCEEDED_PROXY_ENABLED); + } else { + RecordProbeURLFetchResult(SUCCEEDED_PROXY_ALREADY_ENABLED); + } } disabled_by_carrier_ = false; return; } DVLOG(1) << "The data reduction proxy is blocked."; - if (enabled_by_user_ && !disabled_by_carrier_) { - // Disable the proxy. - SetProxyConfigs(false, false); + if (enabled_by_user_) { + if (!disabled_by_carrier_) { + // Disable the proxy. + SetProxyConfigs(false, false); + RecordProbeURLFetchResult(FAILED_PROXY_DISABLED); + } else { + RecordProbeURLFetchResult(FAILED_PROXY_ALREADY_DISABLED); + } } disabled_by_carrier_ = true; } diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index fcad53a..ff94e30 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -929,36 +929,47 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { #if defined(SPDY_PROXY_AUTH_ORIGIN) // Server-induced fallback; see: http://crbug.com/143712 if (response_.was_fetched_via_proxy && response_.headers.get() != NULL) { + ProxyService::DataReductionProxyBypassEventType proxy_bypass_event = + ProxyService::BYPASS_EVENT_TYPE_MAX; base::TimeDelta bypass_duration; bool chrome_proxy_used = - proxy_info_.proxy_server().host_port_pair().Equals( - HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN))); + proxy_info_.proxy_server().isDataReductionProxy(); + bool chrome_fallback_proxy_used = false; #if defined(DATA_REDUCTION_FALLBACK_HOST) if (!chrome_proxy_used) { - chrome_proxy_used = - proxy_info_.proxy_server().host_port_pair().Equals( - HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST))); + chrome_fallback_proxy_used = + proxy_info_.proxy_server().isDataReductionProxyFallback(); } #endif - bool should_fallback = chrome_proxy_used && - response_.headers->GetChromeProxyInfo(&bypass_duration); - // Additionally, fallback if a 500 is returned via the data reduction proxy. - // This is conservative, as the 500 might have been generated by the origin, - // and not the proxy. - if (!should_fallback) { - should_fallback = chrome_proxy_used && - response_.headers->response_code() == HTTP_INTERNAL_SERVER_ERROR; - } - if (should_fallback) { - ProxyService* proxy_service = session_->proxy_service(); - if (proxy_service->MarkProxyAsBad(proxy_info_, bypass_duration, - net_log_)) { - // Only retry in the case of GETs. We don't want to resubmit a POST - // if the proxy took some action. - if (request_->method == "GET") { - ResetConnectionAndRequestForResend(); - return OK; + if (chrome_proxy_used || chrome_fallback_proxy_used) { + if (response_.headers->GetChromeProxyInfo(&bypass_duration)) { + proxy_bypass_event = + (bypass_duration < base::TimeDelta::FromMinutes(30) ? + ProxyService::SHORT_BYPASS : + ProxyService::LONG_BYPASS); + } else { + // Additionally, fallback if a 500 is returned via the data reduction + // proxy. This is conservative, as the 500 might have been generated by + // the origin, and not the proxy. + if (response_.headers->response_code() == HTTP_INTERNAL_SERVER_ERROR) + proxy_bypass_event = ProxyService::INTERNAL_SERVER_ERROR_BYPASS; + } + + if (proxy_bypass_event < ProxyService::BYPASS_EVENT_TYPE_MAX) { + ProxyService* proxy_service = session_->proxy_service(); + + proxy_service->RecordDataReductionProxyBypassInfo( + chrome_proxy_used, proxy_info_.proxy_server(), proxy_bypass_event); + + if (proxy_service->MarkProxyAsBad(proxy_info_, bypass_duration, + net_log_)) { + // Only retry in the case of GETs. We don't want to resubmit a POST + // if the proxy took some action. + if (request_->method == "GET") { + ResetConnectionAndRequestForResend(); + return OK; + } } } } diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc index 6875b4a..3b8bd03 100644 --- a/net/proxy/proxy_server.cc +++ b/net/proxy/proxy_server.cc @@ -208,6 +208,21 @@ ProxyServer::Scheme ProxyServer::GetSchemeFromURI(const std::string& scheme) { return GetSchemeFromURIInternal(scheme.begin(), scheme.end()); } +#if defined(SPDY_PROXY_AUTH_ORIGIN) + bool ProxyServer::isDataReductionProxy() const { + return host_port_pair_.Equals( + HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN))); + } + + bool ProxyServer::isDataReductionProxyFallback() const { +#if defined(DATA_REDUCTION_FALLBACK_HOST) + return host_port_pair_.Equals( + HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST))); +#endif // defined(DATA_REDUCTION_FALLBACK_HOST) + return false; + } +#endif // defined(SPDY_PROXY_AUTH_ORIGIN) + // static ProxyServer ProxyServer::FromSchemeHostAndPort( Scheme scheme, diff --git a/net/proxy/proxy_server.h b/net/proxy/proxy_server.h index 00cc9fd..08a20c0 100644 --- a/net/proxy/proxy_server.h +++ b/net/proxy/proxy_server.h @@ -146,6 +146,14 @@ class NET_EXPORT ProxyServer { return host_port_pair_ < other.host_port_pair_; } +#if defined(SPDY_PROXY_AUTH_ORIGIN) + // Returns true if this proxy server is the data reduction proxy or its + // fallback, respectively, as configured in gyp. These functions will return + // false for data reduction proxy servers specified on the command line. + bool isDataReductionProxy() const; + bool isDataReductionProxyFallback() const; +#endif // defined(SPDY_PROXY_AUTH_ORIGIN) + private: // Creates a ProxyServer given a scheme, and host/port string. If parsing the // host/port string fails, the returned instance will be invalid. diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index 4f9c8be..b18b47b 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -45,6 +45,10 @@ #include "net/proxy/proxy_config_service_android.h" #endif +#if defined(SPDY_PROXY_AUTH_ORIGIN) +#include "base/metrics/histogram.h" +#endif + using base::TimeDelta; using base::TimeTicks; @@ -1169,6 +1173,16 @@ int ProxyService::ReconsiderProxyAfterError(const GURL& url, return ResolveProxy(url, result, callback, pac_request, net_log); } +#if defined(SPDY_PROXY_AUTH_ORIGIN) + if (result->proxy_server().isDataReductionProxy()) { + RecordDataReductionProxyBypassInfo( + true, result->proxy_server(), ERROR_BYPASS); + } else if (result->proxy_server().isDataReductionProxyFallback()) { + RecordDataReductionProxyBypassInfo( + false, result->proxy_server(), ERROR_BYPASS); + } +#endif + // We don't have new proxy settings to try, try to fallback to the next proxy // in the list. bool did_fallback = result->Fallback(net_log); @@ -1393,6 +1407,25 @@ scoped_ptr<ProxyService::PacPollPolicy> return scoped_ptr<PacPollPolicy>(new DefaultPollPolicy()); } +#if defined(SPDY_PROXY_AUTH_ORIGIN) +void ProxyService::RecordDataReductionProxyBypassInfo( + bool is_primary, + const ProxyServer& proxy_server, + DataReductionProxyBypassEventType bypass_type) const { + // Only record UMA if the proxy isn't already on the retry list. + if (proxy_retry_info_.find(proxy_server.ToURI()) != proxy_retry_info_.end()) + return; + + if (is_primary) { + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassInfoPrimary", + bypass_type, BYPASS_EVENT_TYPE_MAX); + } else { + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassInfoFallback", + bypass_type, BYPASS_EVENT_TYPE_MAX); + } +} +#endif // defined(SPDY_PROXY_AUTH_ORIGIN) + void ProxyService::OnProxyConfigChanged( const ProxyConfig& config, ProxyConfigService::ConfigAvailability availability) { diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h index 7e4e306..3573711 100644 --- a/net/proxy/proxy_service.h +++ b/net/proxy/proxy_service.h @@ -261,6 +261,35 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver, // of the default internal PacPollPolicy used by ProxyService. static scoped_ptr<PacPollPolicy> CreateDefaultPacPollPolicy(); +#if defined(SPDY_PROXY_AUTH_ORIGIN) + // Values of the UMA DataReductionProxy.BypassInfo{Primary|Fallback} + // histograms. This enum must remain synchronized with the enum of the same + // name in metrics/histograms/histograms.xml. + enum DataReductionProxyBypassEventType { + // Bypass the proxy for less than 30 minutes. + SHORT_BYPASS = 0, + + // Bypass the proxy for 30 minutes or more. + LONG_BYPASS, + + // Bypass the proxy because of an internal server error. + INTERNAL_SERVER_ERROR_BYPASS, + + // Bypass the proxy because of any other error. + ERROR_BYPASS, + + // This must always be last. + BYPASS_EVENT_TYPE_MAX + }; + + // Records a |DataReductionProxyBypassEventType| for either the data reduction + // proxy (|is_primary| is true) or the data reduction proxy fallback. + void RecordDataReductionProxyBypassInfo( + bool is_primary, + const ProxyServer& proxy_server, + DataReductionProxyBypassEventType bypass_type) const; +#endif + private: FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigAfterFailedAutodetect); FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigFromPACToDirect); diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 08753cc..46c463c 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -1610,6 +1610,29 @@ other types of suffix sets. </summary> </histogram> +<histogram name="DataReductionProxy.BypassInfoFallback" + enum="DataReductionProxyBypassEventType"> + <summary> + Counts various events that trigger Chrome to bypass the fallback + configuration of the data reduction proxy. + </summary> +</histogram> + +<histogram name="DataReductionProxy.BypassInfoPrimary" + enum="DataReductionProxyBypassEventType"> + <summary> + Counts various events that trigger Chrome to bypass the primary + configuration of the data reduction proxy. + </summary> +</histogram> + +<histogram name="DataReductionProxy.ProbeURL" + enum="DataReductionProxyProbeURLFetchResult"> + <summary> + Counts various outcomes of requesting the data reduction proxy's probe URL. + </summary> +</histogram> + <histogram name="DataReductionProxy.PromoAction" enum="DataReductionProxyPromoAction"> <summary> @@ -21051,6 +21074,21 @@ other types of suffix sets. <int value="8" label="PlayMusic"/> </enum> +<enum name="DataReductionProxyBypassEventType" type="int"> + <int value="0" label="Short bypass"/> + <int value="1" label="Long bypass"/> + <int value="2" label="Bypass due to internal server error"/> + <int value="3" label="Bypass due to otehr error"/> +</enum> + +<enum name="DataReductionProxyProbeURLFetchResult" type="int"> + <int value="0" label="Internet disconnected"/> + <int value="1" label="Probe failed, proxy disabled"/> + <int value="2" label="Probe failed, proxy already disabled"/> + <int value="3" label="Probe succeeded, proxy enabled"/> + <int value="4" label="Probe succeeded, proxy already enabled"/> +</enum> + <enum name="DataReductionProxyPromoAction" type="int"> <int value="0" label="Dismissed from first screen"/> <int value="1" label="Dismissed from second screen"/> |