summaryrefslogtreecommitdiff
path: root/chromium/components/variations/net
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/variations/net
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/variations/net')
-rw-r--r--chromium/components/variations/net/variations_command_line_unittest.cc3
-rw-r--r--chromium/components/variations/net/variations_http_headers.cc169
-rw-r--r--chromium/components/variations/net/variations_http_headers.h4
-rw-r--r--chromium/components/variations/net/variations_http_headers_unittest.cc137
-rw-r--r--chromium/components/variations/net/variations_url_loader_throttle.cc2
5 files changed, 279 insertions, 36 deletions
diff --git a/chromium/components/variations/net/variations_command_line_unittest.cc b/chromium/components/variations/net/variations_command_line_unittest.cc
index 1a7ef70e90e..2ca4a019a86 100644
--- a/chromium/components/variations/net/variations_command_line_unittest.cc
+++ b/chromium/components/variations/net/variations_command_line_unittest.cc
@@ -22,8 +22,7 @@ TEST(VariationsCommandLineTest, TestGetVariationsCommandLine) {
std::string disable_feature_list = "feature2<trial2";
AssociateParamsFromString(param_list);
- base::FieldTrialList::CreateTrialsFromString(trial_list,
- std::set<std::string>());
+ base::FieldTrialList::CreateTrialsFromString(trial_list);
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitFromCommandLine(enable_feature_list,
disable_feature_list);
diff --git a/chromium/components/variations/net/variations_http_headers.cc b/chromium/components/variations/net/variations_http_headers.cc
index c4f4f56d837..6f733ee3fc1 100644
--- a/chromium/components/variations/net/variations_http_headers.cc
+++ b/chromium/components/variations/net/variations_http_headers.cc
@@ -4,20 +4,20 @@
#include "components/variations/net/variations_http_headers.h"
-#include <stddef.h>
-
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/macros.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "components/google/core/common/google_util.h"
#include "components/variations/net/omnibox_http_headers.h"
#include "components/variations/variations_http_header_provider.h"
+#include "net/base/isolation_info.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request.h"
@@ -33,44 +33,147 @@ const char kClientDataHeader[] = "X-Client-Data";
namespace {
-// The result of checking if a URL should have variations headers appended.
+// The result of checking whether a request to a URL should have variations
+// headers appended to it.
+//
// This enum is used to record UMA histogram values, and should not be
// reordered.
-enum URLValidationResult {
- INVALID_URL,
- NOT_HTTPS,
- NOT_GOOGLE_DOMAIN,
- SHOULD_APPEND,
- NEITHER_HTTP_HTTPS,
- IS_GOOGLE_NOT_HTTPS,
- URL_VALIDATION_RESULT_SIZE,
+enum class URLValidationResult {
+ kNotValidInvalidUrl = 0,
+ // kNotValidNotHttps = 1, // Deprecated.
+ kNotValidNotGoogleDomain = 2,
+ kShouldAppend = 3,
+ kNotValidNeitherHttpHttps = 4,
+ kNotValidIsGoogleNotHttps = 5,
+ kMaxValue = kNotValidIsGoogleNotHttps,
+};
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum RequestContextCategory {
+ // First-party contexts.
+ kBrowserInitiated = 0,
+ kInternalChromePageInitiated = 1,
+ kGooglePageInitiated = 2,
+ kGoogleSubFrameOnGooglePageInitiated = 3,
+ // Third-party contexts.
+ kNonGooglePageInitiatedFromRequestInitiator = 4,
+ kNoTrustedParams = 5,
+ kNoIsolationInfo = 6,
+ kGoogleSubFrameOnNonGooglePageInitiated = 7,
+ kNonGooglePageInitiatedFromFrameOrigin = 8,
+ kMaxValue = kNonGooglePageInitiatedFromFrameOrigin,
};
-void LogUrlValidationHistogram(URLValidationResult result) {
- UMA_HISTOGRAM_ENUMERATION("Variations.Headers.URLValidationResult", result,
- URL_VALIDATION_RESULT_SIZE);
+void LogRequestContextHistogram(RequestContextCategory result) {
+ base::UmaHistogramEnumeration("Variations.Headers.RequestContextCategory",
+ result);
+}
+
+// Returns a URLValidationResult for |url|. A valid URL for headers has the
+// following qualities: (i) it is well-formed, (ii) its scheme is HTTPS, and
+// (iii) it has a Google-associated domain.
+URLValidationResult GetUrlValidationResult(const GURL& url) {
+ if (!url.is_valid())
+ return URLValidationResult::kNotValidInvalidUrl;
+
+ if (!url.SchemeIsHTTPOrHTTPS())
+ return URLValidationResult::kNotValidNeitherHttpHttps;
+
+ if (!google_util::IsGoogleAssociatedDomainUrl(url))
+ return URLValidationResult::kNotValidNotGoogleDomain;
+
+ // HTTPS is checked here, rather than before the IsGoogleAssociatedDomainUrl()
+ // check, to know how many Google domains are rejected by the change to append
+ // headers to only HTTPS requests.
+ if (!url.SchemeIs(url::kHttpsScheme))
+ return URLValidationResult::kNotValidIsGoogleNotHttps;
+
+ return URLValidationResult::kShouldAppend;
+}
+
+// Returns true if the request to |url| should include a variations header.
+// Also, logs the result of validating |url| in histograms, one of which ends in
+// |suffix|.
+bool ShouldAppendVariationsHeader(const GURL& url, const std::string& suffix) {
+ URLValidationResult result = GetUrlValidationResult(url);
+ base::UmaHistogramEnumeration(
+ "Variations.Headers.URLValidationResult." + suffix, result);
+ return result == URLValidationResult::kShouldAppend;
}
-bool ShouldAppendVariationsHeader(const GURL& url) {
- if (!url.is_valid()) {
- LogUrlValidationHistogram(INVALID_URL);
+// Returns true if the request is sent from a Google-associated property, i.e.
+// from a first-party context. This determination is made using the request
+// context derived from |resource_request|.
+bool IsFirstPartyContext(const network::ResourceRequest& resource_request) {
+ if (!resource_request.request_initiator) {
+ // The absence of |request_initiator| means that the request was initiated
+ // by the browser, e.g. a request from the browser to Autofill upon form
+ // detection.
+ LogRequestContextHistogram(RequestContextCategory::kBrowserInitiated);
+ return true;
+ }
+
+ const GURL request_initiator_url =
+ resource_request.request_initiator->GetURL();
+ if (request_initiator_url.SchemeIs("chrome-search") ||
+ request_initiator_url.SchemeIs("chrome")) {
+ // A scheme matching the above patterns means that the request was
+ // initiated by an internal page, e.g. a request from
+ // chrome-search://local-ntp/ for App Launcher resources.
+ LogRequestContextHistogram(kInternalChromePageInitiated);
+ return true;
+ }
+ if (GetUrlValidationResult(request_initiator_url) !=
+ URLValidationResult::kShouldAppend) {
+ // The request was initiated by a non-Google-associated page, e.g. a request
+ // from https://www.bbc.com/.
+ LogRequestContextHistogram(kNonGooglePageInitiatedFromRequestInitiator);
return false;
}
- if (!url.SchemeIsHTTPOrHTTPS()) {
- LogUrlValidationHistogram(NEITHER_HTTP_HTTPS);
+ if (resource_request.is_main_frame) {
+ // The request is from a Google-associated page--not a sub-frame--e.g. a
+ // request from https://calendar.google.com/.
+ LogRequestContextHistogram(kGooglePageInitiated);
+ return true;
+ }
+ if (!resource_request.trusted_params) {
+ LogRequestContextHistogram(kNoTrustedParams);
+ // Without TrustedParams, we cannot be certain that the request is from a
+ // first-party context.
return false;
}
- if (!google_util::IsGoogleAssociatedDomainUrl(url)) {
- LogUrlValidationHistogram(NOT_GOOGLE_DOMAIN);
+
+ const net::IsolationInfo* isolation_info =
+ &resource_request.trusted_params->isolation_info;
+ if (isolation_info->IsEmpty()) {
+ LogRequestContextHistogram(kNoIsolationInfo);
+ // Without IsolationInfo, we cannot be certain that the request is from a
+ // first-party context.
return false;
}
- // We check https here, rather than before the IsGoogleDomain() check, to know
- // how many Google domains are being rejected by the change to https only.
- if (!url.SchemeIs(url::kHttpsScheme)) {
- LogUrlValidationHistogram(IS_GOOGLE_NOT_HTTPS);
+ if (GetUrlValidationResult(isolation_info->top_frame_origin()->GetURL()) !=
+ URLValidationResult::kShouldAppend) {
+ // The request is from a Google-associated sub-frame on a
+ // non-Google-associated page, e.g. a request to DoubleClick from an ad's
+ // sub-frame on https://www.lexico.com/.
+ LogRequestContextHistogram(kGoogleSubFrameOnNonGooglePageInitiated);
return false;
}
- LogUrlValidationHistogram(SHOULD_APPEND);
+ if (GetUrlValidationResult(isolation_info->frame_origin()->GetURL()) !=
+ URLValidationResult::kShouldAppend) {
+ // The request was initiated by a non-Google-associated page, e.g. a request
+ // from https://www.bbc.com/.
+ //
+ // TODO(crbug/1094303): This case should be covered by checking the request
+ // initiator's URL. Maybe deprecate kNonGooglePageInitiatedFromFrameOrigin
+ // if this bucket is never used.
+ LogRequestContextHistogram(kNonGooglePageInitiatedFromFrameOrigin);
+ return false;
+ }
+ // The request is from a Google-associated sub-frame on a Google-associated
+ // page, e.g. a request from a Docs sub-frame on https://drive.google.com/.
+ LogRequestContextHistogram(kGoogleSubFrameOnGooglePageInitiated);
return true;
}
@@ -100,9 +203,13 @@ class VariationsHeaderHelper {
// international TLD domains *.google.<TLD> or *.youtube.<TLD>.
// 2. Only transmit for non-Incognito profiles.
// 3. For the X-Client-Data header, only include non-empty variation IDs.
- if ((incognito == InIncognito::kYes) || !ShouldAppendVariationsHeader(url))
+ if ((incognito == InIncognito::kYes) ||
+ !ShouldAppendVariationsHeader(url, "Append"))
return false;
+ // TODO(crbug/1094303): Use the result to determine which IDs to include.
+ IsFirstPartyContext(*resource_request_);
+
if (variations_header_.empty())
return false;
@@ -153,7 +260,7 @@ void RemoveVariationsHeaderIfNeeded(
const net::RedirectInfo& redirect_info,
const network::mojom::URLResponseHead& response_head,
std::vector<std::string>* to_be_removed_headers) {
- if (!ShouldAppendVariationsHeader(redirect_info.new_url))
+ if (!ShouldAppendVariationsHeader(redirect_info.new_url, "Remove"))
to_be_removed_headers->push_back(kClientDataHeader);
}
@@ -194,8 +301,10 @@ bool HasVariationsHeader(const network::ResourceRequest& request) {
return request.cors_exempt_headers.HasHeader(kClientDataHeader);
}
-bool ShouldAppendVariationsHeaderForTesting(const GURL& url) {
- return ShouldAppendVariationsHeader(url);
+bool ShouldAppendVariationsHeaderForTesting(
+ const GURL& url,
+ const std::string& histogram_suffix) {
+ return ShouldAppendVariationsHeader(url, histogram_suffix);
}
void UpdateCorsExemptHeaderForVariations(
diff --git a/chromium/components/variations/net/variations_http_headers.h b/chromium/components/variations/net/variations_http_headers.h
index 29506e0f81f..6e30fdd9d14 100644
--- a/chromium/components/variations/net/variations_http_headers.h
+++ b/chromium/components/variations/net/variations_http_headers.h
@@ -100,7 +100,9 @@ bool IsVariationsHeader(const std::string& header_name);
bool HasVariationsHeader(const network::ResourceRequest& request);
// Calls the internal ShouldAppendVariationsHeader() for testing.
-bool ShouldAppendVariationsHeaderForTesting(const GURL& url);
+bool ShouldAppendVariationsHeaderForTesting(
+ const GURL& url,
+ const std::string& histogram_suffix);
// Updates |cors_exempt_header_list| field of the given |param| to register the
// variation headers.
diff --git a/chromium/components/variations/net/variations_http_headers_unittest.cc b/chromium/components/variations/net/variations_http_headers_unittest.cc
index a07883107ad..79ab8b3dd3f 100644
--- a/chromium/components/variations/net/variations_http_headers_unittest.cc
+++ b/chromium/components/variations/net/variations_http_headers_unittest.cc
@@ -4,12 +4,18 @@
#include "components/variations/net/variations_http_headers.h"
-#include <stddef.h>
+#include <string>
#include "base/macros.h"
#include "base/stl_util.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "net/base/isolation_info.h"
+#include "net/cookies/site_for_cookies.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+#include "url/origin.h"
namespace variations {
@@ -155,9 +161,136 @@ TEST(VariationsHttpHeadersTest, ShouldAppendVariationsHeader) {
for (size_t i = 0; i < base::size(cases); ++i) {
const GURL url(cases[i].url);
EXPECT_EQ(cases[i].should_append_headers,
- ShouldAppendVariationsHeaderForTesting(url))
+ ShouldAppendVariationsHeaderForTesting(url, "Append"))
<< url;
}
}
+struct PopulateRequestContextHistogramData {
+ const char* request_initiator_url;
+ bool is_main_frame;
+ bool has_trusted_params;
+ const char* isolation_info_top_frame_origin_url;
+ const char* isolation_info_frame_origin_url;
+ int bucket;
+ const char* name;
+};
+
+class PopulateRequestContextHistogramTest
+ : public testing::TestWithParam<PopulateRequestContextHistogramData> {
+ public:
+ static const PopulateRequestContextHistogramData kCases[];
+};
+
+const PopulateRequestContextHistogramData
+ PopulateRequestContextHistogramTest::kCases[] = {
+ {"", false, false, "", "", 0, "kBrowserInitiated"},
+ {"chrome-search://local-ntp/", false, false, "", "", 1,
+ "kInternalChromePageInitiated"},
+ {"https://www.youtube.com/", true, false, "", "", 2,
+ "kGooglePageInitiated"},
+ {"https://docs.google.com/", false, true, "https://drive.google.com/",
+ "https://docs.google.com/", 3, "kGoogleSubFrameOnGooglePageInitiated"},
+ {"https://www.un.org/", false, false, "", "", 4,
+ "kNonGooglePageInitiatedFromRequestInitiator"},
+ {"https://foo.client-channel.google.com/", false, false, "", "", 5,
+ "kNoTrustedParams"},
+ {"https://foo.google.com/", false, true, "", "", 6, "kNoIsolationInfo"},
+ {"https://123acb.safeframe.googlesyndication.com/", false, true,
+ "https://www.lexico.com/", "", 7,
+ "kGoogleSubFrameOnNonGooglePageInitiated"},
+ {"https://foo.google.com/", false, true, "https://foo.google.com/",
+ "https://www.reddit.com/", 8,
+ "kNonGooglePageInitiatedFromFrameOrigin"},
+};
+
+TEST(VariationsHttpHeadersTest, PopulateUrlValidationResultHistograms) {
+ const GURL invalid_url("invalid");
+ const GURL not_google("https://heavnlydonuts.com/");
+ const GURL should_append("https://youtube.com");
+ const GURL wrong_scheme("ftp://foo.com/");
+ const GURL google_not_https("http://google.com/");
+
+ const std::string append = "Append";
+ const std::string remove = "Remove";
+ base::HistogramTester tester;
+
+ ASSERT_FALSE(ShouldAppendVariationsHeaderForTesting(invalid_url, append));
+ ASSERT_FALSE(ShouldAppendVariationsHeaderForTesting(not_google, append));
+ ASSERT_TRUE(ShouldAppendVariationsHeaderForTesting(should_append, append));
+
+ ASSERT_FALSE(ShouldAppendVariationsHeaderForTesting(wrong_scheme, remove));
+ ASSERT_FALSE(
+ ShouldAppendVariationsHeaderForTesting(google_not_https, remove));
+
+ // Verify that the Append suffixed histogram has a sample corresponding to
+ // the validation result for the three URLs validated for appending.
+ const std::string append_histogram =
+ "Variations.Headers.URLValidationResult.Append";
+ tester.ExpectTotalCount(append_histogram, 3);
+ EXPECT_THAT(tester.GetAllSamples(append_histogram),
+ testing::ElementsAre(base::Bucket(0, 1), base::Bucket(2, 1),
+ base::Bucket(3, 1)));
+
+ // Verify that the Remove suffixed histogram has a sample corresponding to
+ // the validation result for the two URLs validated for removal.
+ const std::string remove_histogram =
+ "Variations.Headers.URLValidationResult.Remove";
+ tester.ExpectTotalCount(remove_histogram, 2);
+ EXPECT_THAT(tester.GetAllSamples(remove_histogram),
+ testing::ElementsAre(base::Bucket(4, 1), base::Bucket(5, 1)));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ VariationsHttpHeadersTest,
+ PopulateRequestContextHistogramTest,
+ testing::ValuesIn(PopulateRequestContextHistogramTest::kCases));
+
+// Returns a ResourceRequest created from the given values.
+network::ResourceRequest CreateResourceRequest(
+ const std::string& request_initiator_url,
+ bool is_main_frame,
+ bool has_trusted_params,
+ const std::string& isolation_info_top_frame_origin_url,
+ const std::string& isolation_info_frame_origin_url) {
+ network::ResourceRequest request;
+ if (request_initiator_url.empty())
+ return request;
+
+ request.request_initiator = url::Origin::Create(GURL(request_initiator_url));
+ request.is_main_frame = is_main_frame;
+ if (!has_trusted_params)
+ return request;
+
+ request.trusted_params = network::ResourceRequest::TrustedParams();
+ if (isolation_info_top_frame_origin_url.empty())
+ return request;
+
+ request.trusted_params->isolation_info = net::IsolationInfo::Create(
+ net::IsolationInfo::RedirectMode::kUpdateNothing,
+ url::Origin::Create(GURL(isolation_info_top_frame_origin_url)),
+ url::Origin::Create(GURL(isolation_info_frame_origin_url)),
+ net::SiteForCookies());
+ return request;
+}
+
+TEST_P(PopulateRequestContextHistogramTest, PopulateRequestContextHistogram) {
+ PopulateRequestContextHistogramData data = GetParam();
+ SCOPED_TRACE(data.name);
+
+ network::ResourceRequest request = CreateResourceRequest(
+ data.request_initiator_url, data.is_main_frame, data.has_trusted_params,
+ data.isolation_info_top_frame_origin_url,
+ data.isolation_info_frame_origin_url);
+
+ base::HistogramTester tester;
+ AppendVariationsHeaderUnknownSignedIn(GURL("https://foo.google.com"),
+ variations::InIncognito::kNo, &request);
+
+ // Verify that the histogram has a single sample corresponding to the request
+ // context category.
+ const std::string histogram = "Variations.Headers.RequestContextCategory";
+ tester.ExpectUniqueSample(histogram, data.bucket, 1);
+}
+
} // namespace variations
diff --git a/chromium/components/variations/net/variations_url_loader_throttle.cc b/chromium/components/variations/net/variations_url_loader_throttle.cc
index 2f1aed783c6..d0fd43ff595 100644
--- a/chromium/components/variations/net/variations_url_loader_throttle.cc
+++ b/chromium/components/variations/net/variations_url_loader_throttle.cc
@@ -21,7 +21,7 @@ VariationsURLLoaderThrottle::~VariationsURLLoaderThrottle() = default;
void VariationsURLLoaderThrottle::AppendThrottleIfNeeded(
const variations::VariationsClient* variations_client,
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>* throttles) {
- if (!variations_client || variations_client->IsIncognito())
+ if (!variations_client || variations_client->IsOffTheRecord())
return;
throttles->push_back(std::make_unique<VariationsURLLoaderThrottle>(