summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstevet@chromium.org <stevet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-16 22:38:32 +0000
committerstevet@chromium.org <stevet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-16 22:38:32 +0000
commit584233319bf3ab20bfd89c2da6f141213a3f0ac9 (patch)
tree73c0b82f215f1f7471a7a268a5a2c7eccc972000
parent4e5540ac3f8e4ac006d956b3033df9b8415f9df5 (diff)
downloadchromium_src-584233319bf3ab20bfd89c2da6f141213a3f0ac9.zip
chromium_src-584233319bf3ab20bfd89c2da6f141213a3f0ac9.tar.gz
chromium_src-584233319bf3ab20bfd89c2da6f141213a3f0ac9.tar.bz2
Transmit a X-Chrome-UMA-Enabled bit to Google domains from clients that have UMA enabled.
BUG=123609 TEST=With UMA enabled (not Chromium), visit www.google.com and ensure that the request header includes X-Chrome-UMA-Enabled with value "1". Also, ensure that unit_tests GoogleUtilTests all pass. Review URL: http://codereview.chromium.org/10054029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132479 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/google/google_util.cc28
-rw-r--r--chrome/browser/google/google_util.h16
-rw-r--r--chrome/browser/google/google_util_unittest.cc35
-rw-r--r--chrome/browser/metrics/metrics_service.h2
-rw-r--r--chrome/browser/net/chrome_network_delegate.cc26
-rw-r--r--chrome/browser/net/chrome_network_delegate.h5
-rw-r--r--chrome/browser/protector/protector_service.cc7
-rw-r--r--chrome/browser/search_engines/template_url_prepopulate_data.cc4
8 files changed, 106 insertions, 17 deletions
diff --git a/chrome/browser/google/google_util.cc b/chrome/browser/google/google_util.cc
index d95b116..22b17fc 100644
--- a/chrome/browser/google/google_util.cc
+++ b/chrome/browser/google/google_util.cc
@@ -44,13 +44,6 @@ bool HasQueryParameter(const std::string& str) {
return false;
}
-// True if |url| is an HTTP[S] request with host "[www.]google.<TLD>" and no
-// explicit port.
-bool IsGoogleDomainUrl(const GURL& url) {
- return url.is_valid() && (url.SchemeIs("http") || url.SchemeIs("https")) &&
- url.port().empty() && google_util::IsGoogleHostname(url.host());
-}
-
} // anonymous namespace
namespace google_util {
@@ -142,21 +135,32 @@ bool GetReactivationBrand(std::string* brand) {
#endif
-bool IsGoogleHostname(const std::string& host) {
+bool IsGoogleDomainUrl(const std::string& url, SubdomainPermission permission) {
+ GURL original_url(url);
+ return original_url.is_valid() && original_url.port().empty() &&
+ (original_url.SchemeIs("http") || original_url.SchemeIs("https")) &&
+ google_util::IsGoogleHostname(original_url.host(), permission);
+}
+
+bool IsGoogleHostname(const std::string& host,
+ SubdomainPermission permission) {
size_t tld_length =
net::RegistryControlledDomainService::GetRegistryLength(host, false);
if ((tld_length == 0) || (tld_length == std::string::npos))
return false;
std::string host_minus_tld(host, 0, host.length() - tld_length);
- return LowerCaseEqualsASCII(host_minus_tld, "www.google.") ||
- LowerCaseEqualsASCII(host_minus_tld, "google.");
+ if (LowerCaseEqualsASCII(host_minus_tld, "google."))
+ return true;
+ if (permission == ALLOW_SUBDOMAIN)
+ return EndsWith(host_minus_tld, ".google.", false);
+ return LowerCaseEqualsASCII(host_minus_tld, "www.google.");
}
bool IsGoogleHomePageUrl(const std::string& url) {
GURL original_url(url);
// First check to see if this has a Google domain.
- if (!IsGoogleDomainUrl(original_url))
+ if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN))
return false;
// Make sure the path is a known home page path.
@@ -173,7 +177,7 @@ bool IsGoogleSearchUrl(const std::string& url) {
GURL original_url(url);
// First check to see if this has a Google domain.
- if (!IsGoogleDomainUrl(original_url))
+ if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN))
return false;
// Make sure the path is a known search path.
diff --git a/chrome/browser/google/google_util.h b/chrome/browser/google/google_util.h
index 95ae4b9..d44afdc 100644
--- a/chrome/browser/google/google_util.h
+++ b/chrome/browser/google/google_util.h
@@ -46,8 +46,20 @@ bool GetReactivationBrand(std::string* brand);
// need to restrict some behavior to only happen on Google's officially-owned
// domains, use TransportSecurityState::IsGooglePinnedProperty() instead.
-// True if |host| is "[www.]google.<TLD>" with a valid TLD.
-bool IsGoogleHostname(const std::string& host);
+// Designate whether or not a URL checking function also checks for specific
+// subdomains, or only "www" and empty subdomains.
+enum SubdomainPermission {
+ ALLOW_SUBDOMAIN,
+ DISALLOW_SUBDOMAIN,
+};
+
+// True if |url| is an HTTP[S] request with host "[www.]google.<TLD>" and no
+// explicit port. If |allow_subdomain| is true, we check against host
+// "*.google.<TLD>" instead.
+bool IsGoogleDomainUrl(const std::string& url, SubdomainPermission permission);
+// True if |host| is "[www.]google.<TLD>" with a valid TLD. If
+// |allow_subdomain| is true, we check against host "*.google.<TLD>" instead.
+bool IsGoogleHostname(const std::string& host, SubdomainPermission permission);
// True if |url| represents a valid Google home page URL.
bool IsGoogleHomePageUrl(const std::string& url);
// True if |url| represents a valid Google search URL.
diff --git a/chrome/browser/google/google_util_unittest.cc b/chrome/browser/google/google_util_unittest.cc
index f51460c..2c6e746 100644
--- a/chrome/browser/google/google_util_unittest.cc
+++ b/chrome/browser/google/google_util_unittest.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/google/google_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+using google_util::IsGoogleDomainUrl;
using google_util::IsGoogleHomePageUrl;
using google_util::IsGoogleSearchUrl;
@@ -241,3 +242,37 @@ TEST(GoogleUtilTest, BadSearches) {
EXPECT_FALSE(IsGoogleSearchUrl(
"http://www.google.com/WEBHP#q=something"));
}
+
+TEST(GoogleUtilTest, GoogleDomains) {
+ // Test some good Google domains (valid TLDs).
+ EXPECT_TRUE(IsGoogleDomainUrl("http://www.google.com",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_TRUE(IsGoogleDomainUrl("http://google.com",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_TRUE(IsGoogleDomainUrl("http://www.google.ca",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_TRUE(IsGoogleDomainUrl("http://www.google.biz.tj",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_TRUE(IsGoogleDomainUrl("http://www.google.com/search?q=something",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_TRUE(IsGoogleDomainUrl("http://www.google.com/webhp",
+ google_util::ALLOW_SUBDOMAIN));
+
+ // Test some bad Google domains (invalid TLDs).
+ EXPECT_FALSE(IsGoogleDomainUrl("http://www.google.notrealtld",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_FALSE(IsGoogleDomainUrl("http://www.google.faketld/search?q=something",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_FALSE(IsGoogleDomainUrl("http://www.yahoo.com",
+ google_util::ALLOW_SUBDOMAIN));
+
+ // Test subdomain checks.
+ EXPECT_TRUE(IsGoogleDomainUrl("http://images.google.com",
+ google_util::ALLOW_SUBDOMAIN));
+ EXPECT_FALSE(IsGoogleDomainUrl("http://images.google.com",
+ google_util::DISALLOW_SUBDOMAIN));
+ EXPECT_TRUE(IsGoogleDomainUrl("http://google.com",
+ google_util::DISALLOW_SUBDOMAIN));
+ EXPECT_TRUE(IsGoogleDomainUrl("http://www.google.com",
+ google_util::DISALLOW_SUBDOMAIN));
+}
diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h
index ff4df36..510b697 100644
--- a/chrome/browser/metrics/metrics_service.h
+++ b/chrome/browser/metrics/metrics_service.h
@@ -32,6 +32,7 @@
class BookmarkModel;
class BookmarkNode;
+class ChromeNetworkDelegate;
class MetricsReportingScheduler;
class PrefService;
class Profile;
@@ -437,6 +438,7 @@ class MetricsServiceHelper {
friend class InstantFieldTrial;
friend bool prerender::IsOmniboxEnabled(Profile* profile);
friend class extensions::ExtensionDownloader;
+ friend class ChromeNetworkDelegate;
// Returns true if prefs::kMetricsReportingEnabled is set.
static bool IsMetricsReportingEnabled();
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 545d127..e107661 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -14,6 +14,8 @@
#include "chrome/browser/extensions/extension_event_router_forwarder.h"
#include "chrome/browser/extensions/extension_info_map.h"
#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/google/google_util.h"
+#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/prefs/pref_member.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/task_manager/task_manager.h"
@@ -165,6 +167,10 @@ int ChromeNetworkDelegate::OnBeforeSendHeaders(
net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) {
+ // Attach any applicable Chrome metrics headers. This is a best-effort attempt
+ // where failure will not cause OnBeforeSendHeaders to back out.
+ AddChromeMetricsStateHeader(request, headers);
+
return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
profile_, extension_info_map_.get(), request, callback, headers);
}
@@ -304,3 +310,23 @@ bool ChromeNetworkDelegate::CanSetCookie(
return allow;
}
+
+void ChromeNetworkDelegate::AddChromeMetricsStateHeader(
+ net::URLRequest* request,
+ net::HttpRequestHeaders* headers) {
+ // Note our criteria for attaching Chrome experiment headers:
+ // 1. We only transmit to *.google.<TLD> domains. NOTE that this use of
+ // google_util helpers to check this does not guarantee that the URL is
+ // Google-owned, only that it is of the form *.google.<TLD>. In the future
+ // we may choose to reinforce this check.
+ // 2. We must verify that the transmitting profile is not off the record.
+ // 3. For the X-Chrome-UMA-Enabled bit, we only set it if UMA is in fact
+ // enabled for this install of Chrome.
+ Profile* profile_instance = reinterpret_cast<Profile*>(profile_);
+ if (google_util::IsGoogleDomainUrl(request->url().spec(),
+ google_util::ALLOW_SUBDOMAIN) &&
+ profile_instance && !profile_instance->IsOffTheRecord() &&
+ MetricsServiceHelper::IsMetricsReportingEnabled()) {
+ headers->SetHeader("X-Chrome-UMA-Enabled", "1");
+ }
+}
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index a582c38..121256a 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -83,6 +83,11 @@ class ChromeNetworkDelegate : public net::NetworkDelegate {
const std::string& cookie_line,
net::CookieOptions* options) OVERRIDE;
+ // Adds Chrome experiment and metrics state as custom headers to |headers|
+ // based on local state and |request|.
+ void AddChromeMetricsStateHeader(net::URLRequest* request,
+ net::HttpRequestHeaders* headers);
+
scoped_refptr<ExtensionEventRouterForwarder> event_router_;
void* profile_;
scoped_refptr<CookieSettings> cookie_settings_;
diff --git a/chrome/browser/protector/protector_service.cc b/chrome/browser/protector/protector_service.cc
index edc24cc..27f9485 100644
--- a/chrome/browser/protector/protector_service.cc
+++ b/chrome/browser/protector/protector_service.cc
@@ -26,8 +26,11 @@ namespace {
bool CanMerge(const GURL& url1, const GURL& url2) {
VLOG(1) << "Checking if can merge " << url1.spec() << " with " << url2.spec();
// All Google URLs are considered the same one.
- if (google_util::IsGoogleHostname(url1.host()))
- return google_util::IsGoogleHostname(url2.host());
+ if (google_util::IsGoogleHostname(url1.host(),
+ google_util::DISALLOW_SUBDOMAIN)) {
+ return google_util::IsGoogleHostname(url2.host(),
+ google_util::DISALLOW_SUBDOMAIN);
+ }
// Otherwise URLs must have the same domain.
return net::RegistryControlledDomainService::SameDomainOrHost(url1, url2);
}
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.cc b/chrome/browser/search_engines/template_url_prepopulate_data.cc
index 5f785ce..c8cdcc9 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.cc
@@ -3281,8 +3281,10 @@ static const PrepopulatedEngine* GetEngineForURL(const std::string& url) {
// First special-case Google, because the prepopulate URL for it will not
// convert to a GURL and thus won't have an origin. Instead see if the
// incoming URL's host is "[*.]google.<TLD>".
- if (google_util::IsGoogleHostname(as_gurl.host()))
+ if (google_util::IsGoogleHostname(as_gurl.host(),
+ google_util::DISALLOW_SUBDOMAIN)) {
return &google;
+ }
// Now check the rest of the prepopulate data.
GURL origin(as_gurl.GetOrigin());