Commit fc9c7810 authored by David Van Cleve's avatar David Van Cleve Committed by Commit Bot

Add a Trust Tokens argument to Fetch's RequestInit.

This CL expands the Fetch API, when the runtime-enabled feature
"TrustTokens" is enabled, to include a new experimental parameter
`trustTokens` denoting a request to execute a Trust Tokens protocol step
(https://github.com/wicg/trust-token-api) alongside the fetch at hand,
by adding request headers and processing corresponding response
headers.

This is an experimental interface that will be used in an origin trial.
It only needs to support fetches from frames (i.e., it is OK from a
usability perspective for the origin trial if the parameter is not
populated when fetch is called from other settings).

The main parts of the CL are:
- as specified in the linked explainer, expand Fetch's RequestInit
dictionary with a new trustToken parameter, specifying a single Trust
Tokens protocol operation of token issuance, token redemption, or
request signing;
- add this data to blink::ResourceRequest and associated objects, so
that it gets copied to network::ResourceRequest in
blink::PopulateResourceRequest.

Test:
- Adds integration tests in //content to ensure that calling the API
results in the right ResourceRequest members being populated.

Change-Id: I5c5b0c0ed5450eeb80c19be856f62941e50ec0e1
Bug: 1043118
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2036648Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Commit-Queue: David Van Cleve <davidvc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#749622}
parent 14c3f87b
...@@ -167,143 +167,134 @@ void SetRuntimeFeaturesFromChromiumFeatures() { ...@@ -167,143 +167,134 @@ void SetRuntimeFeaturesFromChromiumFeatures() {
// enabler function defined. Otherwise add the entry with string name // enabler function defined. Otherwise add the entry with string name
// in the next list. // in the next list.
const RuntimeFeatureToChromiumFeatureMap<void (*)(bool)> const RuntimeFeatureToChromiumFeatureMap<void (*)(bool)>
blinkFeatureToBaseFeatureMapping[] = { blinkFeatureToBaseFeatureMapping[] =
// TODO(rodneyding): Sort features in alphabetical order {
{wf::EnableWebUsb, features::kWebUsb, kDisableOnly}, // TODO(rodneyding): Sort features in alphabetical order
{wf::EnableBlockingFocusWithoutUserActivation, {wf::EnableWebUsb, features::kWebUsb, kDisableOnly},
blink::features::kBlockingFocusWithoutUserActivation, kEnableOnly}, {wf::EnableBlockingFocusWithoutUserActivation,
{wf::EnableNotificationContentImage, blink::features::kBlockingFocusWithoutUserActivation, kEnableOnly},
features::kNotificationContentImage, kDisableOnly}, {wf::EnableNotificationContentImage, features::kNotificationContentImage,
{wf::EnablePeriodicBackgroundSync, features::kPeriodicBackgroundSync, kDisableOnly},
kEnableOnly}, {wf::EnablePeriodicBackgroundSync, features::kPeriodicBackgroundSync,
{wf::EnableWebXR, features::kWebXr, kUseFeatureState}, kEnableOnly},
{wf::EnableWebXRARModule, features::kWebXrArModule, kUseFeatureState}, {wf::EnableWebXR, features::kWebXr, kUseFeatureState},
{wf::EnableWebXRHitTest, features::kWebXrHitTest, kUseFeatureState}, {wf::EnableWebXRARModule, features::kWebXrArModule, kUseFeatureState},
{wf::EnableWebXRIncubations, features::kWebXrIncubations, {wf::EnableWebXRHitTest, features::kWebXrHitTest, kUseFeatureState},
kEnableOnly}, {wf::EnableWebXRIncubations, features::kWebXrIncubations, kEnableOnly},
{wf::EnableUserActivationPostMessageTransfer, {wf::EnableUserActivationPostMessageTransfer,
features::kUserActivationPostMessageTransfer, kUseFeatureState}, features::kUserActivationPostMessageTransfer, kUseFeatureState},
{wf::EnableUserActivationSameOriginVisibility, {wf::EnableUserActivationSameOriginVisibility,
features::kUserActivationSameOriginVisibility, kUseFeatureState}, features::kUserActivationSameOriginVisibility, kUseFeatureState},
{wf::EnablePassiveDocumentEventListeners, {wf::EnablePassiveDocumentEventListeners,
features::kPassiveDocumentEventListeners, kUseFeatureState}, features::kPassiveDocumentEventListeners, kUseFeatureState},
{wf::EnablePassiveDocumentWheelEventListeners, {wf::EnablePassiveDocumentWheelEventListeners,
features::kPassiveDocumentWheelEventListeners, kUseFeatureState}, features::kPassiveDocumentWheelEventListeners, kUseFeatureState},
{wf::EnableExpensiveBackgroundTimerThrottling, {wf::EnableExpensiveBackgroundTimerThrottling,
features::kExpensiveBackgroundTimerThrottling, kUseFeatureState}, features::kExpensiveBackgroundTimerThrottling, kUseFeatureState},
{wf::EnableTimerThrottlingForHiddenFrames, {wf::EnableTimerThrottlingForHiddenFrames,
features::kTimerThrottlingForHiddenFrames, kUseFeatureState}, features::kTimerThrottlingForHiddenFrames, kUseFeatureState},
{wf::EnableSendBeaconThrowForBlobWithNonSimpleType, {wf::EnableSendBeaconThrowForBlobWithNonSimpleType,
features::kSendBeaconThrowForBlobWithNonSimpleType, kEnableOnly}, features::kSendBeaconThrowForBlobWithNonSimpleType, kEnableOnly},
{wf::EnablePaymentRequest, features::kWebPayments, kUseFeatureState}, {wf::EnablePaymentRequest, features::kWebPayments, kUseFeatureState},
{wf::EnablePaymentHandlerMinimalUI, features::kWebPaymentsMinimalUI, {wf::EnablePaymentHandlerMinimalUI, features::kWebPaymentsMinimalUI,
kEnableOnly}, kEnableOnly},
{wf::EnablePaymentApp, features::kServiceWorkerPaymentApps, {wf::EnablePaymentApp, features::kServiceWorkerPaymentApps, kEnableOnly},
kEnableOnly}, {wf::EnableCompositorTouchAction, features::kCompositorTouchAction,
{wf::EnableCompositorTouchAction, features::kCompositorTouchAction, kEnableOnly},
kEnableOnly}, {wf::EnableGenericSensorExtraClasses, features::kGenericSensorExtraClasses,
{wf::EnableGenericSensorExtraClasses, kEnableOnly},
features::kGenericSensorExtraClasses, kEnableOnly}, {wf::EnableMediaCastOverlayButton, media::kMediaCastOverlayButton,
{wf::EnableMediaCastOverlayButton, media::kMediaCastOverlayButton, kUseFeatureState},
kUseFeatureState}, {wf::EnableBuiltInModuleAll, features::kBuiltInModuleAll, kEnableOnly},
{wf::EnableBuiltInModuleAll, features::kBuiltInModuleAll, {wf::EnableBuiltInModuleInfra, features::kBuiltInModuleInfra, kEnableOnly},
kEnableOnly}, {wf::EnableLazyInitializeMediaControls,
{wf::EnableBuiltInModuleInfra, features::kBuiltInModuleInfra, features::kLazyInitializeMediaControls, kUseFeatureState},
kEnableOnly}, {wf::EnableMediaEngagementBypassAutoplayPolicies,
{wf::EnableLazyInitializeMediaControls, media::kMediaEngagementBypassAutoplayPolicies, kUseFeatureState},
features::kLazyInitializeMediaControls, kUseFeatureState}, {wf::EnableOverflowIconsForMediaControls,
{wf::EnableMediaEngagementBypassAutoplayPolicies, media::kOverflowIconsForMediaControls, kUseFeatureState},
media::kMediaEngagementBypassAutoplayPolicies, kUseFeatureState}, {wf::EnableAllowActivationDelegationAttr,
{wf::EnableOverflowIconsForMediaControls, features::kAllowActivationDelegationAttr, kUseFeatureState},
media::kOverflowIconsForMediaControls, kUseFeatureState}, {wf::EnableScriptStreamingOnPreload, features::kScriptStreamingOnPreload,
{wf::EnableAllowActivationDelegationAttr, kUseFeatureState},
features::kAllowActivationDelegationAttr, kUseFeatureState}, {wf::EnableLazyFrameLoading, features::kLazyFrameLoading, kUseFeatureState},
{wf::EnableScriptStreamingOnPreload, {wf::EnableLazyFrameVisibleLoadTimeMetrics,
features::kScriptStreamingOnPreload, kUseFeatureState}, features::kLazyFrameVisibleLoadTimeMetrics, kUseFeatureState},
{wf::EnableLazyFrameLoading, features::kLazyFrameLoading, {wf::EnableLazyImageLoading, features::kLazyImageLoading, kUseFeatureState},
kUseFeatureState}, {wf::EnableLazyImageVisibleLoadTimeMetrics,
{wf::EnableLazyFrameVisibleLoadTimeMetrics, features::kLazyImageVisibleLoadTimeMetrics, kUseFeatureState},
features::kLazyFrameVisibleLoadTimeMetrics, kUseFeatureState}, {wf::EnablePictureInPicture, media::kPictureInPicture, kUseFeatureState},
{wf::EnableLazyImageLoading, features::kLazyImageLoading, {wf::EnableCacheInlineScriptCode, features::kCacheInlineScriptCode,
kUseFeatureState}, kUseFeatureState},
{wf::EnableLazyImageVisibleLoadTimeMetrics, {wf::EnableExperimentalProductivityFeatures,
features::kLazyImageVisibleLoadTimeMetrics, kUseFeatureState}, features::kExperimentalProductivityFeatures, kEnableOnly},
{wf::EnablePictureInPicture, media::kPictureInPicture, {wf::EnableFeaturePolicyForSandbox, features::kFeaturePolicyForSandbox,
kUseFeatureState}, kEnableOnly},
{wf::EnableCacheInlineScriptCode, features::kCacheInlineScriptCode, {wf::EnableAccessibilityExposeARIAAnnotations,
kUseFeatureState}, features::kEnableAccessibilityExposeARIAAnnotations, kEnableOnly},
{wf::EnableExperimentalProductivityFeatures, {wf::EnableAccessibilityExposeDisplayNone,
features::kExperimentalProductivityFeatures, kEnableOnly}, features::kEnableAccessibilityExposeDisplayNone, kEnableOnly},
{wf::EnableFeaturePolicyForSandbox, {wf::EnableAllowSyncXHRInPageDismissal,
features::kFeaturePolicyForSandbox, kEnableOnly}, blink::features::kAllowSyncXHRInPageDismissal, kEnableOnly},
{wf::EnableAccessibilityExposeARIAAnnotations, {wf::EnableAutoplayIgnoresWebAudio, media::kAutoplayIgnoreWebAudio,
features::kEnableAccessibilityExposeARIAAnnotations, kEnableOnly}, kUseFeatureState},
{wf::EnableAccessibilityExposeDisplayNone, {wf::EnablePortals, blink::features::kPortals, kEnableOnly},
features::kEnableAccessibilityExposeDisplayNone, kEnableOnly}, {wf::EnableImplicitRootScroller, blink::features::kImplicitRootScroller,
{wf::EnableAllowSyncXHRInPageDismissal, kUseFeatureState},
blink::features::kAllowSyncXHRInPageDismissal, kEnableOnly}, {wf::EnableCSSOMViewScrollCoordinates,
{wf::EnableAutoplayIgnoresWebAudio, media::kAutoplayIgnoreWebAudio, blink::features::kCSSOMViewScrollCoordinates, kEnableOnly},
kUseFeatureState}, {wf::EnableTextFragmentAnchor, blink::features::kTextFragmentAnchor,
{wf::EnablePortals, blink::features::kPortals, kEnableOnly}, kUseFeatureState},
{wf::EnableImplicitRootScroller, {wf::EnableBackgroundFetch, features::kBackgroundFetch, kDisableOnly},
blink::features::kImplicitRootScroller, kUseFeatureState}, {wf::EnableForcedColors, features::kForcedColors, kUseFeatureState},
{wf::EnableCSSOMViewScrollCoordinates, {wf::EnableFractionalScrollOffsets, features::kFractionalScrollOffsets,
blink::features::kCSSOMViewScrollCoordinates, kEnableOnly}, kUseFeatureState},
{wf::EnableTextFragmentAnchor, blink::features::kTextFragmentAnchor, {wf::EnableGetDisplayMedia, blink::features::kRTCGetDisplayMedia,
kUseFeatureState}, kUseFeatureState},
{wf::EnableBackgroundFetch, features::kBackgroundFetch, kDisableOnly}, {wf::EnableFallbackCursorMode, features::kFallbackCursorMode,
{wf::EnableForcedColors, features::kForcedColors, kUseFeatureState}, kUseFeatureState},
{wf::EnableFractionalScrollOffsets, {wf::EnableSignedExchangePrefetchCacheForNavigations,
features::kFractionalScrollOffsets, kUseFeatureState}, features::kSignedExchangePrefetchCacheForNavigations, kUseFeatureState},
{wf::EnableGetDisplayMedia, blink::features::kRTCGetDisplayMedia, {wf::EnableSignedExchangeSubresourcePrefetch,
kUseFeatureState}, features::kSignedExchangeSubresourcePrefetch, kUseFeatureState},
{wf::EnableFallbackCursorMode, features::kFallbackCursorMode, {wf::EnableIdleDetection, features::kIdleDetection, kDisableOnly},
kUseFeatureState}, {wf::EnableSkipTouchEventFilter, features::kSkipTouchEventFilter,
{wf::EnableSignedExchangePrefetchCacheForNavigations, kUseFeatureState},
features::kSignedExchangePrefetchCacheForNavigations, {wf::EnableSmsReceiver, features::kSmsReceiver, kDisableOnly},
kUseFeatureState}, {wf::EnableConsolidatedMovementXY, features::kConsolidatedMovementXY,
{wf::EnableSignedExchangeSubresourcePrefetch, kUseFeatureState},
features::kSignedExchangeSubresourcePrefetch, kUseFeatureState}, {wf::EnableCooperativeScheduling, features::kCooperativeScheduling,
{wf::EnableIdleDetection, features::kIdleDetection, kDisableOnly}, kUseFeatureState},
{wf::EnableSkipTouchEventFilter, features::kSkipTouchEventFilter, {wf::EnableMouseSubframeNoImplicitCapture,
kUseFeatureState}, features::kMouseSubframeNoImplicitCapture, kUseFeatureState},
{wf::EnableSmsReceiver, features::kSmsReceiver, kDisableOnly}, {wf::EnableCookieDeprecationMessages, features::kCookieDeprecationMessages,
{wf::EnableConsolidatedMovementXY, features::kConsolidatedMovementXY, kEnableOnly},
kUseFeatureState}, {wf::EnableSameSiteByDefaultCookies,
{wf::EnableCooperativeScheduling, features::kCooperativeScheduling, net::features::kSameSiteByDefaultCookies, kEnableOnly},
kUseFeatureState}, {wf::EnableCookiesWithoutSameSiteMustBeSecure,
{wf::EnableMouseSubframeNoImplicitCapture, net::features::kCookiesWithoutSameSiteMustBeSecure, kEnableOnly},
features::kMouseSubframeNoImplicitCapture, kUseFeatureState}, {wf::EnablePointerLockOptions, features::kPointerLockOptions, kEnableOnly},
{wf::EnableCookieDeprecationMessages, {wf::EnableDocumentPolicy, features::kDocumentPolicy, kUseFeatureState},
features::kCookieDeprecationMessages, kEnableOnly}, {wf::EnableNeverSlowMode, features::kNeverSlowMode, kUseFeatureState},
{wf::EnableSameSiteByDefaultCookies, {wf::EnableShadowDOMV0, blink::features::kWebComponentsV0Enabled,
net::features::kSameSiteByDefaultCookies, kEnableOnly}, kEnableOnly},
{wf::EnableCookiesWithoutSameSiteMustBeSecure, {wf::EnableCustomElementsV0, blink::features::kWebComponentsV0Enabled,
net::features::kCookiesWithoutSameSiteMustBeSecure, kEnableOnly}, kEnableOnly},
{wf::EnablePointerLockOptions, features::kPointerLockOptions, {wf::EnableHTMLImports, blink::features::kWebComponentsV0Enabled,
kEnableOnly}, kEnableOnly},
{wf::EnableDocumentPolicy, features::kDocumentPolicy, {wf::EnableVideoPlaybackQuality, features::kVideoPlaybackQuality,
kUseFeatureState}, kUseFeatureState},
{wf::EnableNeverSlowMode, features::kNeverSlowMode, kUseFeatureState}, {wf::EnableBrowserVerifiedUserActivationKeyboard,
{wf::EnableShadowDOMV0, blink::features::kWebComponentsV0Enabled, features::kBrowserVerifiedUserActivationKeyboard, kEnableOnly},
kEnableOnly}, {wf::EnableBrowserVerifiedUserActivationMouse,
{wf::EnableCustomElementsV0, blink::features::kWebComponentsV0Enabled, features::kBrowserVerifiedUserActivationMouse, kEnableOnly},
kEnableOnly}, {wf::EnablePercentBasedScrolling, features::kPercentBasedScrolling,
{wf::EnableHTMLImports, blink::features::kWebComponentsV0Enabled, kUseFeatureState},
kEnableOnly},
{wf::EnableVideoPlaybackQuality, features::kVideoPlaybackQuality,
kUseFeatureState},
{wf::EnableBrowserVerifiedUserActivationKeyboard,
features::kBrowserVerifiedUserActivationKeyboard, kEnableOnly},
{wf::EnableBrowserVerifiedUserActivationMouse,
features::kBrowserVerifiedUserActivationMouse, kEnableOnly},
{wf::EnablePercentBasedScrolling, features::kPercentBasedScrolling,
kUseFeatureState},
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
{wf::EnableWebNfc, {wf::EnableWebNfc, features::kWebNfc, kDisableOnly},
features::kWebNfc, kDisableOnly},
#endif #endif
}; {wf::EnableTrustTokens, network::features::kTrustTokens, kEnableOnly},
};
for (const auto& mapping : blinkFeatureToBaseFeatureMapping) { for (const auto& mapping : blinkFeatureToBaseFeatureMapping) {
const bool featureEnabled = const bool featureEnabled =
base::FeatureList::IsEnabled(mapping.chromium_feature); base::FeatureList::IsEnabled(mapping.chromium_feature);
......
...@@ -1110,6 +1110,7 @@ test("content_browsertests") { ...@@ -1110,6 +1110,7 @@ test("content_browsertests") {
"../test/browser_test_utils_browsertest.cc", "../test/browser_test_utils_browsertest.cc",
"../test/content_browser_test_test.cc", "../test/content_browser_test_test.cc",
"../test/top_frame_population_browsertest.cc", "../test/top_frame_population_browsertest.cc",
"../test/trust_token_parameters_browsertest.cc",
"../test/url_loader_interceptor_test.cc", "../test/url_loader_interceptor_test.cc",
"../test/webui_resource_browsertest.cc", "../test/webui_resource_browsertest.cc",
] ]
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/json/json_string_value_serializer.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/trust_tokens.mojom-shared.h"
#include "services/network/public/mojom/trust_tokens.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::Field;
using ::testing::Optional;
using ::testing::Property;
// These integration tests verify that calling the Fetch API with Trust Tokens
// parameters results in the parameters' counterparts appearing downstream in
// network::ResourceRequest.
//
// They use URLLoaderInterceptor, as opposed to an embedded test server, in
// order to directly inspect network::ResourceRequest instances.
//
// Separately, Blink layout tests check that the API correctly rejects invalid
// input.
namespace content {
namespace {
const char kTestHeaders[] = "HTTP/1.1 200 OK\nContent-type: text/html\n\n";
std::string TrustTokenEnumToString(
network::mojom::TrustTokenOperationType type) {
switch (type) {
case network::mojom::TrustTokenOperationType::kIssuance:
return "token-request";
case network::mojom::TrustTokenOperationType::kRedemption:
return "srr-token-redemption";
case network::mojom::TrustTokenOperationType::kSigning:
return "send-srr";
}
}
std::string TrustTokenEnumToString(
network::mojom::TrustTokenRefreshPolicy policy) {
switch (policy) {
case network::mojom::TrustTokenRefreshPolicy::kUseCached:
return "none";
case network::mojom::TrustTokenRefreshPolicy::kRefresh:
return "refresh";
}
}
std::string TrustTokenEnumToString(
network::mojom::TrustTokenSignRequestData sign_request_data) {
switch (sign_request_data) {
case network::mojom::TrustTokenSignRequestData::kOmit:
return "omit";
case network::mojom::TrustTokenSignRequestData::kHeadersOnly:
return "headers-only";
case network::mojom::TrustTokenSignRequestData::kInclude:
return "include";
}
}
// The values instantiations of this struct will be serialized and passed to a
// `fetch` call in executed JS.
struct Input {
// Input (nullopt in an optional field will be omitted from the parameter's
// value):
network::mojom::TrustTokenOperationType type;
base::Optional<network::mojom::TrustTokenRefreshPolicy> refresh_policy;
base::Optional<network::mojom::TrustTokenSignRequestData> sign_request_data;
base::Optional<bool> include_timestamp_header;
// Because static initialization of GURLs/Origins isn't allowed in tests, use
// the string representation of the issuer origin and convert it to an Origin
// in the test.
base::Optional<std::string> issuer_spec;
base::Optional<std::vector<std::string>> additional_signed_headers;
};
// For a given test case, creates and returns:
// 1. a serialized JSON dictionary suitable for passing as the value of
// `fetch`'s `trustToken` parameter.
// 2. a network::mojom::TrustTokenParams object that should equal the value
// eventually passed to network::ResourceRequest when a fetch is executed
// with the returned trustToken parameter value.
std::pair<std::string, network::mojom::TrustTokenParams>
SerializeParametersAndConstructExpectation(const Input& input) {
network::mojom::TrustTokenParams expectation;
base::Value parameters(base::Value::Type::DICTIONARY);
parameters.SetStringKey("type", TrustTokenEnumToString(input.type));
expectation.type = input.type;
if (input.refresh_policy.has_value()) {
parameters.SetStringKey("refreshPolicy",
TrustTokenEnumToString(*input.refresh_policy));
expectation.refresh_policy = *input.refresh_policy;
}
if (input.sign_request_data.has_value()) {
parameters.SetStringKey("signRequestData",
TrustTokenEnumToString(*input.sign_request_data));
expectation.sign_request_data = *input.sign_request_data;
}
if (input.include_timestamp_header.has_value()) {
parameters.SetBoolKey("includeTimestampHeader",
*input.include_timestamp_header);
expectation.include_timestamp_header = *input.include_timestamp_header;
}
if (input.issuer_spec.has_value()) {
parameters.SetStringKey("issuer", *input.issuer_spec);
expectation.issuer = url::Origin::Create(GURL(*input.issuer_spec));
}
if (input.additional_signed_headers.has_value()) {
base::Value headers(base::Value::Type::LIST);
for (const std::string& header : *input.additional_signed_headers)
headers.Append(header);
parameters.SetKey("additionalSignedHeaders", std::move(headers));
expectation.additional_signed_headers = *input.additional_signed_headers;
}
std::string serialized_parameters;
JSONStringValueSerializer serializer(&serialized_parameters);
CHECK(serializer.Serialize(parameters));
return std::make_pair(serialized_parameters, expectation);
}
const Input kIssuanceInputs[]{
// For issuance, there are no additional parameters to specify.
{.type = network::mojom::TrustTokenOperationType::kIssuance}};
const Input kRedemptionInputs[]{
// The only free parameter for redemption is refreshPolicy.
{.type = network::mojom::TrustTokenOperationType::kRedemption,
.refresh_policy = network::mojom::TrustTokenRefreshPolicy::kRefresh},
{.type = network::mojom::TrustTokenOperationType::kRedemption,
.refresh_policy = network::mojom::TrustTokenRefreshPolicy::kUseCached},
{.type = network::mojom::TrustTokenOperationType::kRedemption}};
const Input kSigningInputs[]{
// Signing's inputs are issuer, signRequestData, additionalSignedHeaders,
// and includeTimestampHeader; "issuer" has no default and must always be
// a secure origin.
{.type = network::mojom::TrustTokenOperationType::kSigning,
.sign_request_data = network::mojom::TrustTokenSignRequestData::kOmit,
.include_timestamp_header = true,
.issuer_spec = "https://issuer.example",
.additional_signed_headers =
std::vector<std::string>{"one header's name",
"another header's name"}},
{.type = network::mojom::TrustTokenOperationType::kSigning,
.sign_request_data =
network::mojom::TrustTokenSignRequestData::kHeadersOnly,
.include_timestamp_header = false,
.issuer_spec = "https://issuer.example"},
{.type = network::mojom::TrustTokenOperationType::kSigning,
.sign_request_data = network::mojom::TrustTokenSignRequestData::kInclude,
.issuer_spec = "https://issuer.example"},
};
} // namespace
class TrustTokenParametersBrowsertest
: public ::testing::WithParamInterface<Input>,
public ContentBrowserTest {
public:
TrustTokenParametersBrowsertest() {
features_.InitAndEnableFeature(network::features::kTrustTokens);
}
protected:
base::test::ScopedFeatureList features_;
};
INSTANTIATE_TEST_SUITE_P(WithIssuanceParameters,
TrustTokenParametersBrowsertest,
testing::ValuesIn(kIssuanceInputs));
INSTANTIATE_TEST_SUITE_P(WithRedemptionParameters,
TrustTokenParametersBrowsertest,
testing::ValuesIn(kRedemptionInputs));
INSTANTIATE_TEST_SUITE_P(WithSigningParameters,
TrustTokenParametersBrowsertest,
testing::ValuesIn(kSigningInputs));
IN_PROC_BROWSER_TEST_P(TrustTokenParametersBrowsertest,
PopulatesResourceRequest) {
bool attempted_to_load_image = false;
network::mojom::TrustTokenParams expectation;
std::string fetch_trust_token_parameter;
std::tie(fetch_trust_token_parameter, expectation) =
SerializeParametersAndConstructExpectation(GetParam());
URLLoaderInterceptor interceptor(base::BindLambdaForTesting(
[&attempted_to_load_image, &fetch_trust_token_parameter,
&expectation](URLLoaderInterceptor::RequestParams* params) -> bool {
std::string spec = params->url_request.url.spec();
// On the first request, to "main.com", load a landing page from which
// to make the Trust Tokens request.
if (spec.find("main") != std::string::npos) {
URLLoaderInterceptor::WriteResponse(
kTestHeaders,
"<html><script>fetch('https://www.image.com/image.png', "
"{trustToken: " +
fetch_trust_token_parameter + "});</script></html>",
params->client.get());
return true;
}
// On the second request, to a path containing "image", verify that the
// network::ResourceRequest has the correct Trust Tokens parameters.
if (spec.find("image")) {
// Can't ASSERT_TRUE in a non-void-returning method, but we don't want
// to continue to the next line if there's no |trust_token_params|
// field present, because we'd trigger a check failure anyways, when
// dereferencing nullopt.
CHECK(params->url_request.trust_token_params);
EXPECT_TRUE(
params->url_request.trust_token_params->Equals(expectation));
attempted_to_load_image = true;
}
return false;
}));
EXPECT_TRUE(NavigateToURL(shell(), GURL("https://main.com/")));
// As a sanity check, make sure the test did actually try to load the
// subresource.
ASSERT_TRUE(attempted_to_load_image);
}
} // namespace content
...@@ -238,6 +238,8 @@ class WebRuntimeFeatures { ...@@ -238,6 +238,8 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableSurfaceEmbeddingFeatures(bool); BLINK_PLATFORM_EXPORT static void EnableSurfaceEmbeddingFeatures(bool);
BLINK_PLATFORM_EXPORT static void EnableAcceleratedSmallCanvases(bool); BLINK_PLATFORM_EXPORT static void EnableAcceleratedSmallCanvases(bool);
BLINK_PLATFORM_EXPORT static void EnableTrustTokens(bool);
private: private:
WebRuntimeFeatures(); WebRuntimeFeatures();
}; };
......
...@@ -231,6 +231,7 @@ static_idl_files_in_core = get_path_info( ...@@ -231,6 +231,7 @@ static_idl_files_in_core = get_path_info(
"//third_party/blink/renderer/core/fetch/request_init.idl", "//third_party/blink/renderer/core/fetch/request_init.idl",
"//third_party/blink/renderer/core/fetch/response.idl", "//third_party/blink/renderer/core/fetch/response.idl",
"//third_party/blink/renderer/core/fetch/response_init.idl", "//third_party/blink/renderer/core/fetch/response_init.idl",
"//third_party/blink/renderer/core/fetch/trust_token.idl",
"//third_party/blink/renderer/core/fetch/testing/internals_fetch.idl", "//third_party/blink/renderer/core/fetch/testing/internals_fetch.idl",
"//third_party/blink/renderer/core/fetch/testing/worker_internals_fetch.idl", "//third_party/blink/renderer/core/fetch/testing/worker_internals_fetch.idl",
"//third_party/blink/renderer/core/fetch/window_fetch.idl", "//third_party/blink/renderer/core/fetch/window_fetch.idl",
......
...@@ -661,6 +661,7 @@ core_dictionary_idl_files = ...@@ -661,6 +661,7 @@ core_dictionary_idl_files =
"events/wheel_event_init.idl", "events/wheel_event_init.idl",
"fetch/request_init.idl", "fetch/request_init.idl",
"fetch/response_init.idl", "fetch/response_init.idl",
"fetch/trust_token.idl",
"fileapi/blob_property_bag.idl", "fileapi/blob_property_bag.idl",
"fileapi/file_property_bag.idl", "fileapi/file_property_bag.idl",
"frame/navigator_ua_brand_version.idl", "frame/navigator_ua_brand_version.idl",
......
...@@ -711,6 +711,7 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) { ...@@ -711,6 +711,7 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
request.SetRequestDestination(fetch_request_data_->Destination()); request.SetRequestDestination(fetch_request_data_->Destination());
request.SetHttpMethod(fetch_request_data_->Method()); request.SetHttpMethod(fetch_request_data_->Method());
request.SetFetchWindowId(fetch_request_data_->WindowId()); request.SetFetchWindowId(fetch_request_data_->WindowId());
request.SetTrustTokenParams(fetch_request_data_->TrustTokenParams());
switch (fetch_request_data_->Mode()) { switch (fetch_request_data_->Mode()) {
case RequestMode::kSameOrigin: case RequestMode::kSameOrigin:
......
...@@ -152,6 +152,7 @@ FetchRequestData* FetchRequestData::CloneExceptBody() { ...@@ -152,6 +152,7 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
request->keepalive_ = keepalive_; request->keepalive_ = keepalive_;
request->is_history_navigation_ = is_history_navigation_; request->is_history_navigation_ = is_history_navigation_;
request->window_id_ = window_id_; request->window_id_ = window_id_;
request->trust_token_params_ = trust_token_params_;
return request; return request;
} }
......
...@@ -12,8 +12,9 @@ ...@@ -12,8 +12,9 @@
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h" #include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h" #include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "services/network/public/mojom/url_loader_factory.mojom-blink.h" #include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h" #include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
...@@ -124,6 +125,16 @@ class CORE_EXPORT FetchRequestData final ...@@ -124,6 +125,16 @@ class CORE_EXPORT FetchRequestData final
const base::UnguessableToken& WindowId() const { return window_id_; } const base::UnguessableToken& WindowId() const { return window_id_; }
void SetWindowId(const base::UnguessableToken& id) { window_id_ = id; } void SetWindowId(const base::UnguessableToken& id) { window_id_ = id; }
const base::Optional<network::mojom::blink::TrustTokenParams>&
TrustTokenParams() const {
return trust_token_params_;
}
void SetTrustTokenParams(
base::Optional<network::mojom::blink::TrustTokenParams>
trust_token_params) {
trust_token_params_ = std::move(trust_token_params);
}
void Trace(Visitor*); void Trace(Visitor*);
private: private:
...@@ -150,6 +161,7 @@ class CORE_EXPORT FetchRequestData final ...@@ -150,6 +161,7 @@ class CORE_EXPORT FetchRequestData final
mojom::FetchCacheMode cache_mode_; mojom::FetchCacheMode cache_mode_;
network::mojom::RedirectMode redirect_; network::mojom::RedirectMode redirect_;
mojom::FetchImportanceMode importance_; mojom::FetchImportanceMode importance_;
base::Optional<network::mojom::blink::TrustTokenParams> trust_token_params_;
// FIXME: Support m_useURLCredentialsFlag; // FIXME: Support m_useURLCredentialsFlag;
// FIXME: Support m_redirectCount; // FIXME: Support m_redirectCount;
Tainting response_tainting_; Tainting response_tainting_;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/cpp/request_destination.h" #include "services/network/public/cpp/request_destination.h"
#include "services/network/public/cpp/request_mode.h" #include "services/network/public/cpp/request_mode.h"
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "third_party/blink/public/common/blob/blob_utils.h" #include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_url_request.h"
...@@ -28,6 +29,7 @@ ...@@ -28,6 +29,7 @@
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h" #include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/fetch_manager.h" #include "third_party/blink/renderer/core/fetch/fetch_manager.h"
#include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h" #include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/trust_token.h"
#include "third_party/blink/renderer/core/fileapi/blob.h" #include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h" #include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
#include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/frame/web_feature.h"
...@@ -52,6 +54,106 @@ ...@@ -52,6 +54,106 @@
namespace blink { namespace blink {
namespace {
// Converts an IDL trustToken object to its Mojo counterpart.
// The elements of trustToken (and of TrustTokenParams) comprise:
// - an operation type, always populated
// - remaining elements partitioned into groups of parameters used for specific
// operations.
//
// The method sets only |type| and the fields corresponding to the operation
// specified by |type|, namely
// - for issuance, no additional fields;
// - for redemption, |refresh_policy|;
// - for signing: |issuer|, |additional_signed_headers|, |sign_request_data|,
// and |include_timestamp_header|.
//
// Performs some validity checking against inputs:
// - for signing, |issuer| must be provided and must be a valid HTTP(S) URL.
// If this validation fails, throws a TypeError against |exception_state| and
// returns false.
bool ConvertTrustTokenToMojom(const TrustToken& in,
ExceptionState* exception_state,
network::mojom::blink::TrustTokenParams* out) {
DCHECK(in.hasType()); // field is required in IDL
if (in.type() == "token-request") {
out->type = network::mojom::blink::TrustTokenOperationType::kIssuance;
return true;
}
if (in.type() == "srr-token-redemption") {
out->type = network::mojom::blink::TrustTokenOperationType::kRedemption;
CHECK(in.hasRefreshPolicy()); // default is defined
out->include_timestamp_header = in.includeTimestampHeader();
if (in.refreshPolicy() == "none") {
out->refresh_policy =
network::mojom::blink::TrustTokenRefreshPolicy::kUseCached;
} else if (in.refreshPolicy() == "refresh") {
out->refresh_policy =
network::mojom::blink::TrustTokenRefreshPolicy::kRefresh;
}
return true;
}
DCHECK_EQ(in.type(), "send-srr"); // final possible value of the input enum
out->type = network::mojom::blink::TrustTokenOperationType::kSigning;
if (in.hasSignRequestData()) {
if (in.signRequestData() == "omit") {
out->sign_request_data =
network::mojom::blink::TrustTokenSignRequestData::kOmit;
} else if (in.signRequestData() == "include") {
out->sign_request_data =
network::mojom::blink::TrustTokenSignRequestData::kInclude;
} else if (in.signRequestData() == "headers-only") {
out->sign_request_data =
network::mojom::blink::TrustTokenSignRequestData::kHeadersOnly;
}
}
if (in.hasAdditionalSignedHeaders()) {
out->additional_signed_headers = in.additionalSignedHeaders();
}
CHECK(in.hasIncludeTimestampHeader()); // default is defined
out->include_timestamp_header = in.includeTimestampHeader();
if (in.hasIssuer()) {
// Two conditions on the issuer:
// 1. HTTP or HTTPS (because much Trust Tokens protocol state is
// stored keyed by issuer origin, requiring HTTP or HTTPS is a way to ensure
// these origins serialize to unique values);
// 2. potentially trustworthy (a security requirement).
KURL parsed_url = KURL(in.issuer());
if (!parsed_url.ProtocolIsInHTTPFamily()) {
exception_state->ThrowTypeError(
"trustToken: operation type 'send-srr' requires that the 'issuer' "
"field parse to a HTTP(S) origin, but it did not: " +
in.issuer());
return false;
}
out->issuer = blink::SecurityOrigin::Create(parsed_url);
if (!out->issuer->IsPotentiallyTrustworthy()) {
exception_state->ThrowTypeError(
"trustToken: operation type 'send-srr' requires that the 'issuer' "
"field parse to a secure origin, but it did not: " +
in.issuer());
return false;
}
} else {
exception_state->ThrowTypeError(
"trustToken: operation type 'send-srr' requires that the 'issuer' "
"field "
"be present and parse to a secure HTTP(S) URL, but it was missing.");
return false;
}
return true;
}
} // namespace
FetchRequestData* CreateCopyOfFetchRequestDataForFetch( FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
ScriptState* script_state, ScriptState* script_state,
const FetchRequestData* original) { const FetchRequestData* original) {
...@@ -83,6 +185,7 @@ FetchRequestData* CreateCopyOfFetchRequestDataForFetch( ...@@ -83,6 +185,7 @@ FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
request->SetURLLoaderFactory(std::move(factory_clone)); request->SetURLLoaderFactory(std::move(factory_clone));
} }
request->SetWindowId(original->WindowId()); request->SetWindowId(original->WindowId());
request->SetTrustTokenParams(original->TrustTokenParams());
return request; return request;
} }
...@@ -91,7 +194,7 @@ static bool AreAnyMembersPresent(const RequestInit* init) { ...@@ -91,7 +194,7 @@ static bool AreAnyMembersPresent(const RequestInit* init) {
init->hasReferrer() || init->hasReferrerPolicy() || init->hasMode() || init->hasReferrer() || init->hasReferrerPolicy() || init->hasMode() ||
init->hasCredentials() || init->hasCache() || init->hasRedirect() || init->hasCredentials() || init->hasCache() || init->hasRedirect() ||
init->hasIntegrity() || init->hasKeepalive() || init->hasIntegrity() || init->hasKeepalive() ||
init->hasImportance() || init->hasSignal(); init->hasImportance() || init->hasSignal() || init->hasTrustToken();
} }
static BodyStreamBuffer* ExtractBody(ScriptState* script_state, static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
...@@ -495,6 +598,19 @@ Request* Request::CreateRequestWithRequestOrString( ...@@ -495,6 +598,19 @@ Request* Request::CreateRequestWithRequestOrString(
signal = init->signal(); signal = init->signal();
} }
if (init->hasTrustToken()) {
network::mojom::blink::TrustTokenParams params;
if (!ConvertTrustTokenToMojom(*init->trustToken(), &exception_state,
&params)) {
// Whenever parsing the trustToken argument fails, we expect a suitable
// exception to be thrown.
DCHECK(exception_state.HadException());
return nullptr;
}
request->SetTrustTokenParams(std::move(params));
}
// "Let |r| be a new Request object associated with |request| and a new // "Let |r| be a new Request object associated with |request| and a new
// Headers object whose guard is "request"." // Headers object whose guard is "request"."
Request* r = Request::Create(script_state, request); Request* r = Request::Create(script_state, request);
......
...@@ -23,6 +23,7 @@ dictionary RequestInit { ...@@ -23,6 +23,7 @@ dictionary RequestInit {
boolean keepalive; boolean keepalive;
[RuntimeEnabled=PriorityHints] RequestImportance importance; [RuntimeEnabled=PriorityHints] RequestImportance importance;
AbortSignal? signal; AbortSignal? signal;
[RuntimeEnabled=TrustTokens, SecureContext] TrustToken trustToken;
// TODO(domfarolino): add support for RequestInit window member. // TODO(domfarolino): add support for RequestInit window member.
//any window; // can only be set to null //any window; // can only be set to null
}; };
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
enum RefreshPolicy { "none", "refresh" };
enum OperationType { "token-request", "send-srr", "srr-token-redemption" };
enum SignRequestData { "omit", "include", "headers-only" };
// A TrustToken object represents a request to execute a Trust Tokens protocol
// operation (https://github.com/wicg/trust-token-api).
dictionary TrustToken {
// |type| is the only required parameter; all other parameters are necessary
// only for certain operations.
required OperationType type;
// --- Parameters only for token redemption
// The following parameters are ignored unless |type| is
// "srr-token-redemption":
// 1. refreshPolicy
RefreshPolicy refreshPolicy = "none";
// --- Parameters only for request signing
// The following parameters are ignored unless |type| is "send-srr":
// 1. |issuer|
// 2. |additionalSignedHeaders|
// 3. |includeTimestampHeader|
// 4. |signRequestData|
//
// Additionally, |issuer| is required when |type| is "send-srr".
USVString issuer;
sequence<USVString> additionalSignedHeaders;
boolean includeTimestampHeader = false;
SignRequestData signRequestData = "omit";
};
...@@ -667,4 +667,8 @@ void WebRuntimeFeatures::EnableAcceleratedSmallCanvases(bool enable) { ...@@ -667,4 +667,8 @@ void WebRuntimeFeatures::EnableAcceleratedSmallCanvases(bool enable) {
RuntimeEnabledFeatures::SetAcceleratedSmallCanvasesEnabled(enable); RuntimeEnabledFeatures::SetAcceleratedSmallCanvasesEnabled(enable);
} }
void WebRuntimeFeatures::EnableTrustTokens(bool enable) {
RuntimeEnabledFeatures::SetTrustTokensEnabled(enable);
}
} // namespace blink } // namespace blink
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "services/network/public/mojom/cors.mojom-blink-forward.h" #include "services/network/public/mojom/cors.mojom-blink-forward.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h" #include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h" #include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/platform/resource_request_blocked_reason.h" #include "third_party/blink/public/platform/resource_request_blocked_reason.h"
#include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_url_request.h"
...@@ -440,6 +441,15 @@ class PLATFORM_EXPORT ResourceRequestHead { ...@@ -440,6 +441,15 @@ class PLATFORM_EXPORT ResourceRequestHead {
prefetch_maybe_for_top_level_navigation; prefetch_maybe_for_top_level_navigation;
} }
const base::Optional<network::mojom::blink::TrustTokenParams>&
TrustTokenParams() const {
return trust_token_params_;
}
void SetTrustTokenParams(
base::Optional<network::mojom::blink::TrustTokenParams> params) {
trust_token_params_ = std::move(params);
}
// Whether either RequestorOrigin or IsolatedWorldOrigin can display the // Whether either RequestorOrigin or IsolatedWorldOrigin can display the
// |url|, // |url|,
bool CanDisplay(const KURL&) const; bool CanDisplay(const KURL&) const;
...@@ -494,6 +504,7 @@ class PLATFORM_EXPORT ResourceRequestHead { ...@@ -494,6 +504,7 @@ class PLATFORM_EXPORT ResourceRequestHead {
bool is_external_request_; bool is_external_request_;
network::mojom::CorsPreflightPolicy cors_preflight_policy_; network::mojom::CorsPreflightPolicy cors_preflight_policy_;
RedirectStatus redirect_status_; RedirectStatus redirect_status_;
base::Optional<network::mojom::blink::TrustTokenParams> trust_token_params_;
base::Optional<String> suggested_filename_; base::Optional<String> suggested_filename_;
......
...@@ -11,10 +11,13 @@ ...@@ -11,10 +11,13 @@
#include "net/http/http_request_headers.h" #include "net/http/http_request_headers.h"
#include "net/http/http_util.h" #include "net/http/http_util.h"
#include "services/network/public/cpp/constants.h" #include "services/network/public/cpp/constants.h"
#include "services/network/public/cpp/optional_trust_token_params.h"
#include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_request_body.h" #include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/mojom/data_pipe_getter.mojom-blink.h" #include "services/network/public/mojom/data_pipe_getter.mojom-blink.h"
#include "services/network/public/mojom/data_pipe_getter.mojom.h" #include "services/network/public/mojom/data_pipe_getter.mojom.h"
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "services/network/public/mojom/trust_tokens.mojom.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
...@@ -173,6 +176,30 @@ mojom::ResourceType RequestContextToResourceType( ...@@ -173,6 +176,30 @@ mojom::ResourceType RequestContextToResourceType(
} }
} }
// Converts a mojom::blink TrustTokenParams object to its non-Blink counterpart
// by copying all fields.
network::OptionalTrustTokenParams ConvertTrustTokenParams(
const base::Optional<network::mojom::blink::TrustTokenParams>& maybe_in) {
if (!maybe_in)
return base::nullopt;
const network::mojom::blink::TrustTokenParams& in = *maybe_in;
network::mojom::TrustTokenParamsPtr out =
network::mojom::TrustTokenParams::New();
out->type = in.type;
out->refresh_policy = in.refresh_policy;
out->sign_request_data = in.sign_request_data;
out->include_timestamp_header = in.include_timestamp_header;
// Optional value:
if (in.issuer)
out->issuer = in.issuer->ToUrlOrigin();
for (const String& additional_header : in.additional_signed_headers) {
out->additional_signed_headers.push_back(additional_header.Latin1());
}
return network::OptionalTrustTokenParams(std::move(out));
}
} // namespace } // namespace
void PopulateResourceRequestBody(const EncodedFormData& src, void PopulateResourceRequestBody(const EncodedFormData& src,
...@@ -307,6 +334,7 @@ void PopulateResourceRequest(const ResourceRequest& src, ...@@ -307,6 +334,7 @@ void PopulateResourceRequest(const ResourceRequest& src,
// longer used in a network delegate. https://crbug.com/842233 // longer used in a network delegate. https://crbug.com/842233
dest->previews_state = static_cast<int>(src.GetPreviewsState()); dest->previews_state = static_cast<int>(src.GetPreviewsState());
dest->throttling_profile_id = src.GetDevToolsToken(); dest->throttling_profile_id = src.GetDevToolsToken();
dest->trust_token_params = ConvertTrustTokenParams(src.TrustTokenParams());
if (base::UnguessableToken window_id = src.GetFetchWindowId()) if (base::UnguessableToken window_id = src.GetFetchWindowId())
dest->fetch_window_id = base::make_optional(window_id); dest->fetch_window_id = base::make_optional(window_id);
......
...@@ -1700,6 +1700,10 @@ ...@@ -1700,6 +1700,10 @@
name: "TrustedDOMTypes", name: "TrustedDOMTypes",
status: "experimental", status: "experimental",
}, },
{
name: "TrustTokens",
status: "test",
},
{ {
name: "UnclosedFormControlIsInvalid", name: "UnclosedFormControlIsInvalid",
status: "experimental", status: "experimental",
......
<!DOCTYPE html>
<meta charset="utf-8">
<title>JavaScript: the Trust Token API Fetch method correctly validates its parameters</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
'use strict';
test(() => {
assert_throws_js(TypeError, () => {
new Request('https://example.com', {
trustToken: {}
});
});
}, 'Trust Tokens fetches require present `type` values.');
test(() => {
assert_throws_js(TypeError, () => {
new Request('https://example.com', {
trustToken: {
type: "invalid"
}
});
});
}, 'Trust Tokens fetches require valid `type` values.');
test(() => {
assert_throws_js(TypeError, () => {
new Request('https://example.com', {
trustToken: {
type: "token-request",
signRequestData: "not a member of the signRequestData enum"
}
});
});
}, 'Trust Tokens fetches require valid `signRequestData` values, if provided.');
test(() => {
assert_throws_js(TypeError, () => {
new Request('https://example.com', {
trustToken: {
type: "token-request",
refreshPolicy: "not a member of the refreshPolicy enum",
}
});
});
}, 'Trust Tokens fetches require valid `refreshPolicy:` values, if provided.');
test(() => {
assert_throws_js(TypeError, () => {
new Request('https://example.com', {
trustToken: {
type: "send-srr",
issuer: "not a valid URL"
}
});
});
}, 'Trust Tokens fetches require valid issuer URLs, if provided.');
test(() => {
assert_throws_js(TypeError, () => {
new Request('https://example.com', {
trustToken: {
type: "send-srr",
issuer: "http://not-secure.com"
}
});
});
}, 'Trust Tokens fetches require secure issuer URLs, if provided.');
test(() => {
new Request('https://example.com', {
trustToken: {
type: "send-srr",
issuer: "http://localhost"
}
});
}, 'Since localhost URLs are potentially trustworthy, setting an issuer to localhost should succeed.');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment