0

Enable Persistent Origin Trial for content/shell

This introduces the Persistent Origin Trial functionality to the
content_shell application.

To facilitate web tests of the persistent origin trial feature, this
CL also adds a new header to the content_shell app when running in
web-test mode, which sets a |X-Web-Test-Enabled-Origin-Trials| request
header with the names of enabled persistent origin trials.

This CL is part of the persistent origin trials implementation.
Full implementation plan here:
https://docs.google.com/document/d/1v4cwALXi33VgYrdqFCldDT0N0BuwiXzESt7NIJIiOTs/edit?usp=sharing

LOW_COVERAGE_REASON=web_test_content_browser_client.cc is being tested
     by the web tests. Coverage does not pick up on this though.

Bug: 1257579
Change-Id: Iefdd82547d3f9ba0d1809ab795f33eef13ee923f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3792108
Reviewed-by: Peter Beverloo <peter@chromium.org>
Auto-Submit: Peter Pakkenberg <pbirk@chromium.org>
Commit-Queue: Peter Pakkenberg <pbirk@chromium.org>
Reviewed-by: Finnur Thorarinsson <finnur@chromium.org>
Reviewed-by: Dominic Farolino <dom@chromium.org>
Commit-Queue: Finnur Thorarinsson <finnur@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1072781}
This commit is contained in:
Peter Birk Pakkenberg
2022-11-17 14:30:42 +00:00
committed by Chromium LUCI CQ
parent e6c7fdf6e5
commit d927c9421e
40 changed files with 358 additions and 0 deletions
content
extensions/shell
third_party/blink/web_tests
VirtualTestSuites
flag-specific
disable-layout-ng
http
virtual
enable-persistent-origin-trials
disable-site-isolation-trials
virtual
enable-persistent-origin-trials
http
platform
generic
http
virtual
enable-persistent-origin-trials
linux
http
virtual
enable-persistent-origin-trials
mac
http
virtual
enable-persistent-origin-trials
win10
http
virtual
enable-persistent-origin-trials
virtual
enable-persistent-origin-trials

@ -249,6 +249,8 @@ static_library("content_shell_lib") {
"//components/network_hints/browser:browser",
"//components/network_hints/renderer",
"//components/network_session_configurator/common",
"//components/origin_trials:browser",
"//components/origin_trials:common",
"//components/performance_manager",
"//components/permissions",
"//components/prefs",

@ -6,6 +6,7 @@ include_rules = [
"+components/network_hints/browser",
"+components/network_session_configurator/common",
"+components/prefs",
"+components/origin_trials",
"+components/variations",
"+services/device/public/cpp",
"+services/network/public",

@ -20,8 +20,12 @@
#include "components/keyed_service/core/simple_factory_key.h"
#include "components/keyed_service/core/simple_key_map.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/origin_trials/browser/leveldb_persistence_provider.h"
#include "components/origin_trials/browser/origin_trials.h"
#include "components/origin_trials/common/features.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/origin_trials_controller_delegate.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_switches.h"
#include "content/shell/browser/shell_content_browser_client.h"
@ -33,6 +37,7 @@
#include "content/shell/common/shell_switches.h"
#include "content/test/mock_background_sync_controller.h"
#include "content/test/mock_reduce_accept_language_controller_delegate.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
namespace content {
@ -230,4 +235,20 @@ ShellBrowserContext::GetReduceAcceptLanguageControllerDelegate() {
return reduce_accept_lang_controller_delegate_.get();
}
OriginTrialsControllerDelegate*
ShellBrowserContext::GetOriginTrialsControllerDelegate() {
if (!origin_trials::features::IsPersistentOriginTrialsEnabled())
return nullptr;
if (!origin_trials_controller_delegate_) {
origin_trials_controller_delegate_ =
std::make_unique<origin_trials::OriginTrials>(
std::make_unique<origin_trials::LevelDbPersistenceProvider>(
GetPath(),
GetDefaultStoragePartition()->GetProtoDatabaseProvider()),
std::make_unique<blink::TrialTokenValidator>());
}
return origin_trials_controller_delegate_.get();
}
} // namespace content

@ -21,6 +21,7 @@ class BackgroundSyncController;
class ContentIndexProvider;
class ClientHintsControllerDelegate;
class DownloadManagerDelegate;
class OriginTrialsControllerDelegate;
class PermissionControllerDelegate;
class ReduceAcceptLanguageControllerDelegate;
class ShellDownloadManagerDelegate;
@ -71,6 +72,7 @@ class ShellBrowserContext : public BrowserContext {
GetFederatedIdentityActiveSessionPermissionContext() override;
ReduceAcceptLanguageControllerDelegate*
GetReduceAcceptLanguageControllerDelegate() override;
OriginTrialsControllerDelegate* GetOriginTrialsControllerDelegate() override;
protected:
// Contains URLRequestContextGetter required for resource loading.
@ -95,6 +97,8 @@ class ShellBrowserContext : public BrowserContext {
federated_permission_context_;
std::unique_ptr<ReduceAcceptLanguageControllerDelegate>
reduce_accept_lang_controller_delegate_;
std::unique_ptr<OriginTrialsControllerDelegate>
origin_trials_controller_delegate_;
private:
// Performs initialization of the ShellBrowserContext while IO is still

@ -142,6 +142,11 @@ int ShellBrowserMainParts::PreEarlyInitialization() {
void ShellBrowserMainParts::InitializeBrowserContexts() {
set_browser_context(new ShellBrowserContext(false));
set_off_the_record_browser_context(new ShellBrowserContext(true));
// Persistent Origin Trials needs to be instantiated as soon as possible
// during browser startup, to ensure data is available prior to the first
// request.
browser_context_->GetOriginTrialsControllerDelegate();
off_the_record_browser_context_->GetOriginTrialsControllerDelegate();
}
void ShellBrowserMainParts::InitializeMessageLoopContext() {

@ -128,6 +128,8 @@ static_library("web_test_browser") {
"browser/web_test_first_device_bluetooth_chooser.h",
"browser/web_test_javascript_dialog_manager.cc",
"browser/web_test_javascript_dialog_manager.h",
"browser/web_test_origin_trial_throttle.cc",
"browser/web_test_origin_trial_throttle.h",
"browser/web_test_permission_manager.cc",
"browser/web_test_permission_manager.h",
"browser/web_test_push_messaging_service.cc",
@ -169,6 +171,7 @@ static_library("web_test_browser") {
"//components/download/public/background_service:public",
"//components/download/public/common:public",
"//components/network_session_configurator/common",
"//components/origin_trials:common",
"//components/proxy_config",
"//content/browser:for_content_tests", # For non-component builds.
"//content/public/browser", # For component builds.

@ -3,6 +3,7 @@ include_rules = [
"+components/download",
"+components/keyed_service/core",
"+components/network_session_configurator/common",
"+components/origin_trials",
"+components/viz/common",
"+content/public/browser",
"+content/public/common",

@ -20,6 +20,7 @@
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "components/origin_trials/common/features.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
@ -27,10 +28,12 @@
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/client_hints_controller_delegate.h"
#include "content/public/browser/login_delegate.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/overlay_window.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_content_browser_client.h"
@ -49,6 +52,7 @@
#include "content/web_test/browser/web_test_browser_main_parts.h"
#include "content/web_test/browser/web_test_control_host.h"
#include "content/web_test/browser/web_test_cookie_manager.h"
#include "content/web_test/browser/web_test_origin_trial_throttle.h"
#include "content/web_test/browser/web_test_permission_manager.h"
#include "content/web_test/browser/web_test_storage_access_manager.h"
#include "content/web_test/browser/web_test_tts_platform.h"
@ -377,6 +381,21 @@ void WebTestContentBrowserClient::OverrideWebkitPrefs(
WebTestControlHost::Get()->OverrideWebkitPrefs(prefs);
}
std::vector<std::unique_ptr<content::NavigationThrottle>>
WebTestContentBrowserClient::CreateThrottlesForNavigation(
content::NavigationHandle* navigation_handle) {
std::vector<std::unique_ptr<content::NavigationThrottle>> throttles =
ShellContentBrowserClient::CreateThrottlesForNavigation(
navigation_handle);
if (origin_trials::features::IsPersistentOriginTrialsEnabled()) {
throttles.push_back(std::make_unique<WebTestOriginTrialThrottle>(
navigation_handle, navigation_handle->GetWebContents()
->GetBrowserContext()
->GetOriginTrialsControllerDelegate()));
}
return throttles;
}
void WebTestContentBrowserClient::AppendExtraCommandLineSwitches(
base::CommandLine* command_line,
int child_process_id) {

@ -64,6 +64,9 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
RenderProcessHost* render_process_host) override;
void OverrideWebkitPrefs(WebContents* web_contents,
blink::web_pref::WebPreferences* prefs) override;
std::vector<std::unique_ptr<content::NavigationThrottle>>
CreateThrottlesForNavigation(
content::NavigationHandle* navigation_handle) override;
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
int child_process_id) override;
std::unique_ptr<BrowserMainParts> CreateBrowserMainParts(

@ -0,0 +1,65 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/web_test/browser/web_test_origin_trial_throttle.h"
#include <string>
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/origin_trials_controller_delegate.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace content {
namespace {
const char kThrottleName[] = "WebTestOriginTrialThrottle";
const char kWebTestOriginTrialHeaderName[] = "X-Web-Test-Enabled-Origin-Trials";
} // namespace
WebTestOriginTrialThrottle::WebTestOriginTrialThrottle(
NavigationHandle* navigation_handle,
OriginTrialsControllerDelegate* delegate)
: NavigationThrottle(navigation_handle),
origin_trials_controller_delegate_(delegate) {}
NavigationThrottle::ThrottleCheckResult
WebTestOriginTrialThrottle::WillStartRequest() {
SetHeaderForRequest();
return NavigationThrottle::ThrottleAction::PROCEED;
}
NavigationThrottle::ThrottleCheckResult
WebTestOriginTrialThrottle::WillRedirectRequest() {
SetHeaderForRequest();
return NavigationThrottle::ThrottleAction::PROCEED;
}
void WebTestOriginTrialThrottle::SetHeaderForRequest() {
GURL request_url = navigation_handle()->GetURL();
url::Origin origin = url::Origin::CreateFromNormalizedTuple(
request_url.scheme(), request_url.host(), request_url.EffectiveIntPort());
base::flat_set<std::string> trials;
if (!origin.opaque()) {
trials = origin_trials_controller_delegate_->GetPersistedTrialsForOrigin(
origin, base::Time::Now());
}
std::string header_value = base::JoinString(
base::span<std::string>(trials.begin(), trials.end()), ", ");
navigation_handle()->SetRequestHeader(kWebTestOriginTrialHeaderName,
header_value);
}
const char* WebTestOriginTrialThrottle::GetNameForLogging() {
return kThrottleName;
}
} // namespace content

@ -0,0 +1,40 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_WEB_TEST_BROWSER_WEB_TEST_ORIGIN_TRIAL_THROTTLE_H_
#define CONTENT_WEB_TEST_BROWSER_WEB_TEST_ORIGIN_TRIAL_THROTTLE_H_
#include "base/memory/raw_ptr.h"
#include "content/public/browser/navigation_throttle.h"
namespace content {
class OriginTrialsControllerDelegate;
// NavigationThrottle that sets a header for testing with the names of all
// enabled persistent origin trials.
// This exists to support the tests in
// third_party/blink/web_tests/http/tests/persistent-origin-trial
// by providing an observable effect of setting a persistent origin trial.
class WebTestOriginTrialThrottle : public NavigationThrottle {
public:
WebTestOriginTrialThrottle(NavigationHandle* navigation_handle,
OriginTrialsControllerDelegate* delegate);
~WebTestOriginTrialThrottle() override = default;
// NavigationThrottle implementation
ThrottleCheckResult WillStartRequest() override;
ThrottleCheckResult WillRedirectRequest() override;
const char* GetNameForLogging() override;
private:
// Helper function that set the X-Web-Test-Enabled-Origin-Trials header
void SetHeaderForRequest();
base::raw_ptr<OriginTrialsControllerDelegate>
origin_trials_controller_delegate_;
};
} // namespace content
#endif // CONTENT_WEB_TEST_BROWSER_WEB_TEST_ORIGIN_TRIAL_THROTTLE_H_

@ -47,6 +47,8 @@ source_set("app_shell_lib") {
"//components/keyed_service/content:content",
"//components/nacl/common:buildflags",
"//components/network_session_configurator/common",
"//components/origin_trials:browser",
"//components/origin_trials:common",
"//components/pref_registry",
"//components/prefs",
"//components/services/app_service/public/mojom",

@ -6,6 +6,7 @@ include_rules = [
"+components/nacl/browser",
"+components/nacl/common",
"+components/network_session_configurator/common",
"+components/origin_trials",
"+components/pref_registry",
"+components/sessions",
"+components/update_client",

@ -1492,5 +1492,11 @@
"external/wpt/mediacapture-streams/parallel-capture-requests.https.html"
],
"args": ["--enable-features=SplitUserMediaQueues"]
},
{
"prefix": "enable-persistent-origin-trials",
"platforms": ["Linux", "Mac", "Win"],
"bases": [ "http/tests/persistent-origin-trials/" ],
"args": ["--enable-features=PersistentOriginTrials"]
}
]

@ -0,0 +1,4 @@
This is a testharness.js-based test.
FAIL PersistentOriginTrial using Critical header assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
FAIL PersistentInChild assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
PASS PersistentOriginTrial using Critical header
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
PASS PersistentInChild
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
PASS PersistentOriginTrial using Critical header
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
PASS PersistentInChild
Harness: the test ran to completion.

@ -0,0 +1,21 @@
<?php
// Token for FrobulatePersistent
$ORIGIN_TRIAL_TOKEN = "A7eQahvlWGVqTPZ/Rpyq3p+Lw+CZaKPs8POfJ7SURAykNb7kG6+xv4I3O4E03VALwnxZJy4aB83PX5q5yseoSQEAAABceyJvcmlnaW4iOiAiaHR0cHM6Ly8xMjcuMC4wLjE6ODQ0MyIsICJmZWF0dXJlIjogIkZyb2J1bGF0ZVBlcnNpc3RlbnQiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=";
header("Origin-Trial: ". $ORIGIN_TRIAL_TOKEN);
header("Critical-Origin-Trial: FrobulatePersistent");
$headers = getallheaders();
$trials = $headers['X-Web-Test-Enabled-Origin-Trials'];
?>
<!DOCTYPE html>
<title>Test that the Critical-Origin-Trial header enables the request header</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
test(function(){
assert_equals("<?php echo($trials)?>", "FrobulatePersistent");
this.add_cleanup(function() {
window.open("support/cleanup.https.html");
});
}, "PersistentOriginTrial using Critical header");
</script>

@ -0,0 +1,5 @@
<!DOCTYPE html>
<!--
This file exists to allow for a navigation to the test origin
without setting any Origin-Trial headers.
-->

@ -0,0 +1,51 @@
<?php
// Token for FrobulatePersistent
$ORIGIN_TRIAL_TOKEN = "A7eQahvlWGVqTPZ/Rpyq3p+Lw+CZaKPs8POfJ7SURAykNb7kG6+xv4I3O4E03VALwnxZJy4aB83PX5q5yseoSQEAAABceyJvcmlnaW4iOiAiaHR0cHM6Ly8xMjcuMC4wLjE6ODQ0MyIsICJmZWF0dXJlIjogIkZyb2J1bGF0ZVBlcnNpc3RlbnQiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=";
header("Origin-Trial: ". $ORIGIN_TRIAL_TOKEN);
$headers = getallheaders();
$trials = $headers['X-Web-Test-Enabled-Origin-Trials'];
$child = $_REQUEST['child'] == "true";
if (!$child) {
// Main page
?>
<!DOCTYPE html>
<title>Test that navigations in a new window enables persistent origin trials</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
test(
() => {
// Ensure that the test state is reset, by checking that the first
// load does not have an enabled persistent trial.
assert_equals("<?php echo($trials)?>", "");
}, "TestPrimaryPageHasNoTrial");
// Navigate to the same domain, and check that the trial header is set
var child_window = window.open("window-origin-trial.https.php?child=true");
fetch_tests_from_window(child_window);
</script>
<?php
// End main page
} else {
// Child page
?>
<!DOCTYPE html>
<title>Test that navigations in a new window enables persistent origin trials</title>
<script src="/resources/testharness.js"></script>
<body>
<script>
test(function() {
// In the child, assert that the header is now applied without any
// redirects
assert_equals("<?php echo($trials)?>", "FrobulatePersistent");
this.add_cleanup(function() {
window.open("support/cleanup.https.html");
});
}, "PersistentInChild");
</script>
<?php
// End child page
}

@ -0,0 +1,4 @@
This is a testharness.js-based test.
FAIL PersistentOriginTrial using Critical header assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
FAIL PersistentInChild assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
PASS PersistentOriginTrial using Critical header
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
PASS PersistentInChild
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
FAIL PersistentOriginTrial using Critical header assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
FAIL PersistentInChild assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
PASS PersistentOriginTrial using Critical header
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
PASS PersistentInChild
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
FAIL PersistentOriginTrial using Critical header assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
FAIL PersistentInChild assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
PASS PersistentOriginTrial using Critical header
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
PASS PersistentInChild
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
FAIL PersistentOriginTrial using Critical header assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
FAIL PersistentInChild assert_equals: expected "FrobulatePersistent" but got ""
Harness: the test ran to completion.

@ -0,0 +1,4 @@
This is a testharness.js-based test.
PASS PersistentOriginTrial using Critical header
Harness: the test ran to completion.

@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS TestPrimaryPageHasNoTrial
PASS PersistentInChild
Harness: the test ran to completion.

@ -0,0 +1,9 @@
This directory contains a test suite for an expansion of the Origin Trials
framework to include persistent trials, which is currently undergoing Finch
roll-out in M109.
Since the `PersistentOriginTrials` flag is disabled by default for now, this
virtual test suite exist to run tests with the flag enabled.
This virtual test suite will be removed once the `PersistentOriginTrials` flag
is enabled by default.