Fenced frame: Set referrer header for all event-level beacons.
A previous CL set the "Referer" header for reportEvent() beacons to the frame's origin. This CL sets that header for automatic beacons as well, and puts the change behind a new feature flag. Automatic beacons from component ads will not have their "Referer" header set to the frames origin for privacy reasons, and instead will be set to the root ad frame's origin. To track this, ad component configs will now store the origin of the root ad frame's config on the browser side. This CL also updates WPTs and other tests to account for the changes. Previous CL: https://chromium-review.googlesource.com/c/chromium/src/+/5551871 Design Doc: https://docs.google.com/document/d/1gKRZ9g_X5HCZbW__GinViwcC8iWEai_kBXsiJCXrt80/edit?usp=sharing Change-Id: Idfaeee92ad5bf471b34002a6a701290d1ae31cf1 Bug: 341884774 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5544804 Commit-Queue: Liam Brady <lbrady@google.com> Reviewed-by: Garrett Tanzer <gtanzer@chromium.org> Reviewed-by: Alex Moshchuk <alexmos@chromium.org> Cr-Commit-Position: refs/heads/main@{#1310677}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
424ce61433
commit
27da6a274b
content
browser
fenced_frame
fenced_frame_browsertest.ccfenced_frame_reporter.ccfenced_frame_reporter.hfenced_frame_reporter_unittest.cc
renderer_host
public
testing/variations
third_party/blink
common
public
common
web_tests
VirtualTestSuites
external
wpt
fenced-frame
automatic-beacon-anchor-click-handler.https.htmlautomatic-beacon-click-handler.https.htmlautomatic-beacon-component-ad.https.htmlautomatic-beacon-cross-origin-false.https.htmlautomatic-beacon-cross-origin-no-data.https.htmlautomatic-beacon-cross-origin-no-opt-in.https.htmlautomatic-beacon-no-destination.https.htmlautomatic-beacon-no-opt-in.https.htmlautomatic-beacon-shared-storage.https.htmlautomatic-beacon-two-events-clear.https.htmlautomatic-beacon-two-events-persist.https.htmlfence-report-event-cross-origin-no-embedder-opt-in.https.htmlfence-report-event-cross-origin-no-subframe-opt-in.https.htmlfence-report-event-cross-origin-urn-iframe-no-embedder-opt-in.https.htmlfence-report-event-cross-origin-urn-iframe-no-subframe-opt-in.https.htmlfence-report-event-cross-origin.sub.https.htmlfence-report-event-sub-fencedframe.https.htmlreport-event.https.html
resources
http
tests
inspector-protocol
fenced-frame
wpt_internal
fenced_frame
@ -2248,7 +2248,8 @@ class FencedFrameParameterizedBrowserTest : public FencedFrameBrowserTestBase {
|
||||
{blink::features::kFencedFramesLocalUnpartitionedDataAccess, {}},
|
||||
{blink::features::
|
||||
kFencedFramesCrossOriginEventReportingUnlabeledTraffic,
|
||||
{}}},
|
||||
{}},
|
||||
{blink::features::kFencedFramesReportEventHeaderChanges, {}}},
|
||||
{/* disabled_features */});
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,8 @@ bool FencedFrameReporter::SendReport(
|
||||
std::string& error_message,
|
||||
blink::mojom::ConsoleMessageLevel& console_message_level,
|
||||
int initiator_frame_tree_node_id,
|
||||
std::optional<int64_t> navigation_id) {
|
||||
std::optional<int64_t> navigation_id,
|
||||
std::optional<url::Origin> ad_root_origin) {
|
||||
DCHECK(request_initiator_frame);
|
||||
|
||||
if (reporting_destination ==
|
||||
@ -444,9 +445,20 @@ bool FencedFrameReporter::SendReport(
|
||||
}
|
||||
}
|
||||
|
||||
const url::Origin& request_initiator =
|
||||
url::Origin request_initiator =
|
||||
request_initiator_frame->GetLastCommittedOrigin();
|
||||
|
||||
// |ad_root_origin| is only set for ad components. Automatic beacons sent from
|
||||
// ad components should not have the ad component's origin present in the
|
||||
// beacon, as that is additional information that should not be made available
|
||||
// to the reporting server. Set it to the root ad frame's origin instead.
|
||||
if (base::FeatureList::IsEnabled(
|
||||
blink::features::kFencedFramesReportEventHeaderChanges) &&
|
||||
ad_root_origin.has_value()) {
|
||||
CHECK(absl::holds_alternative<AutomaticBeaconEvent>(event_variant));
|
||||
request_initiator = ad_root_origin.value();
|
||||
}
|
||||
|
||||
// If the reporting URL map is pending, queue the event.
|
||||
NotifyIsBeaconQueued(
|
||||
event_variant,
|
||||
@ -678,10 +690,13 @@ bool FencedFrameReporter::SendReportInternal(
|
||||
} else {
|
||||
request->method = net::HttpRequestHeaders::kPostMethod;
|
||||
}
|
||||
if (absl::holds_alternative<DestinationEnumEvent>(event_variant) ||
|
||||
absl::holds_alternative<DestinationURLEvent>(event_variant)) {
|
||||
request->referrer = request_initiator.GetURL();
|
||||
if (base::FeatureList::IsEnabled(
|
||||
blink::features::kFencedFramesReportEventHeaderChanges)) {
|
||||
// For automatic beacons initiating from component ad frames, the
|
||||
// request_initiator will have already been set to the root ad frame's
|
||||
// origin by this point.
|
||||
request->referrer_policy = net::ReferrerPolicy::ORIGIN;
|
||||
request->referrer = request_initiator.GetURL();
|
||||
}
|
||||
request->trusted_params = network::ResourceRequest::TrustedParams();
|
||||
request->trusted_params->isolation_info =
|
||||
|
@ -250,6 +250,8 @@ class CONTENT_EXPORT FencedFrameReporter
|
||||
// will be set to the ID of the navigation request initiated from the fenced
|
||||
// frame and targeting the new top-level frame. In all other cases (including
|
||||
// the fence.reportEvent() case), the navigation id will be null.
|
||||
// Note: `ad_root_origin` will only be set for automatic beacons originating
|
||||
// from ad components.
|
||||
bool SendReport(
|
||||
const DestinationVariant& event_variant,
|
||||
blink::FencedFrame::ReportingDestination reporting_destination,
|
||||
@ -259,7 +261,8 @@ class CONTENT_EXPORT FencedFrameReporter
|
||||
std::string& error_message,
|
||||
blink::mojom::ConsoleMessageLevel& console_message_level,
|
||||
int initiator_frame_tree_node_id = RenderFrameHost::kNoFrameTreeNodeId,
|
||||
std::optional<int64_t> navigation_id = std::nullopt);
|
||||
std::optional<int64_t> navigation_id = std::nullopt,
|
||||
std::optional<url::Origin> ad_root_origin = std::nullopt);
|
||||
|
||||
// Called when a mapping for private aggregation requests of non-reserved
|
||||
// event types is received. Currently it is only called inside
|
||||
|
@ -104,8 +104,9 @@ class FencedFrameReporterTest : public RenderViewHostTestHarness {
|
||||
public:
|
||||
FencedFrameReporterTest() {
|
||||
scoped_feature_list_.InitWithFeatures(
|
||||
/*enabled_features=*/{blink::features::
|
||||
kFencedFramesAutomaticBeaconCredentials},
|
||||
/*enabled_features=*/
|
||||
{blink::features::kFencedFramesAutomaticBeaconCredentials,
|
||||
blink::features::kFencedFramesReportEventHeaderChanges},
|
||||
/*disabled_features=*/{});
|
||||
}
|
||||
|
||||
@ -131,21 +132,14 @@ class FencedFrameReporterTest : public RenderViewHostTestHarness {
|
||||
|
||||
void ValidateRequest(const network::ResourceRequest& request,
|
||||
const GURL& expected_url,
|
||||
const std::optional<std::string>& event_data,
|
||||
bool should_have_referrer = true) {
|
||||
const std::optional<std::string>& event_data) {
|
||||
EXPECT_EQ(request.url, expected_url);
|
||||
EXPECT_EQ(request.mode, network::mojom::RequestMode::kCors);
|
||||
EXPECT_EQ(request.credentials_mode, network::mojom::CredentialsMode::kOmit);
|
||||
EXPECT_TRUE(request.trusted_params->isolation_info.network_isolation_key()
|
||||
.IsTransient());
|
||||
|
||||
if (should_have_referrer) {
|
||||
EXPECT_EQ(request.referrer, main_frame_origin_.GetURL());
|
||||
EXPECT_EQ(request.referrer_policy, net::ReferrerPolicy::ORIGIN);
|
||||
} else {
|
||||
EXPECT_EQ(request.referrer, GURL());
|
||||
EXPECT_EQ(request.referrer_policy, net::ReferrerPolicy::NEVER_CLEAR);
|
||||
}
|
||||
EXPECT_EQ(request.referrer, main_frame_origin_.GetURL());
|
||||
EXPECT_EQ(request.referrer_policy, net::ReferrerPolicy::ORIGIN);
|
||||
|
||||
// Checks specific to DestinationURL events.
|
||||
if (!event_data.has_value()) {
|
||||
@ -1576,7 +1570,7 @@ TEST_F(FencedFrameReporterTest, SendReportsRecordHistogramsAutomaticBeacon) {
|
||||
console_message_level));
|
||||
EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
|
||||
ValidateRequest((*test_url_loader_factory_.pending_requests())[0].request,
|
||||
report_destination3_, "event_data3", false);
|
||||
report_destination3_, "event_data3");
|
||||
|
||||
test_url_loader_factory_.SimulateResponseForPendingRequest(
|
||||
report_destination3_.spec(), "");
|
||||
@ -1598,7 +1592,7 @@ TEST_F(FencedFrameReporterTest, SendReportsRecordHistogramsAutomaticBeacon) {
|
||||
console_message_level));
|
||||
EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
|
||||
ValidateRequest((*test_url_loader_factory_.pending_requests())[0].request,
|
||||
report_destination3_, "event_data3", false);
|
||||
report_destination3_, "event_data3");
|
||||
|
||||
test_url_loader_factory_.SimulateResponseForPendingRequest(
|
||||
report_destination3_.spec(), "", net::HTTP_NOT_FOUND);
|
||||
|
@ -996,6 +996,18 @@ bool FrameTreeNode::IsInFencedFrameTree() const {
|
||||
return fenced_frame_status_ != FencedFrameStatus::kNotNestedInFencedFrame;
|
||||
}
|
||||
|
||||
FrameTreeNode* FrameTreeNode::GetClosestAncestorWithFencedFrameProperties() {
|
||||
FrameTreeNode* node = this;
|
||||
while (node) {
|
||||
if (node->fenced_frame_properties_.has_value()) {
|
||||
return node;
|
||||
}
|
||||
node = node->parent() ? node->parent()->frame_tree_node() : nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::optional<FencedFrameProperties>& FrameTreeNode::GetFencedFrameProperties(
|
||||
FencedFramePropertiesNodeSource node_source) {
|
||||
if (node_source == FencedFramePropertiesNodeSource::kFrameTreeRoot) {
|
||||
@ -1006,15 +1018,9 @@ std::optional<FencedFrameProperties>& FrameTreeNode::GetFencedFrameProperties(
|
||||
// properties are obtained by a bottom-up traversal.
|
||||
CHECK_EQ(node_source, FencedFramePropertiesNodeSource::kClosestAncestor);
|
||||
|
||||
FrameTreeNode* node = this;
|
||||
while (node) {
|
||||
if (node->fenced_frame_properties_.has_value()) {
|
||||
return node->fenced_frame_properties_;
|
||||
}
|
||||
node = node->parent() ? node->parent()->frame_tree_node() : nullptr;
|
||||
}
|
||||
FrameTreeNode* node = GetClosestAncestorWithFencedFrameProperties();
|
||||
|
||||
return fenced_frame_properties_;
|
||||
return node ? node->fenced_frame_properties_ : fenced_frame_properties_;
|
||||
}
|
||||
|
||||
void FrameTreeNode::MaybeResetFencedFrameAutomaticBeaconReportEventData(
|
||||
|
@ -598,6 +598,11 @@ class CONTENT_EXPORT FrameTreeNode : public RenderFrameHostOwner {
|
||||
FencedFramePropertiesNodeSource node_source =
|
||||
FencedFramePropertiesNodeSource::kClosestAncestor);
|
||||
|
||||
// Helper function for getting the FrameTreeNode that houses the relevant
|
||||
// FencedFrameProperties when GetFencedFrameProperties() is called with
|
||||
// kClosestAncestor.
|
||||
FrameTreeNode* GetClosestAncestorWithFencedFrameProperties();
|
||||
|
||||
bool HasFencedFrameProperties() const {
|
||||
return fenced_frame_properties_.has_value();
|
||||
}
|
||||
|
@ -9263,12 +9263,27 @@ void RenderFrameHostImpl::SendFencedFrameReportingBeaconInternal(
|
||||
return;
|
||||
}
|
||||
|
||||
// Automatic beacons that originate from component ads shouldn't expose the ad
|
||||
// component's origin in the beacon. Instead, use the origin of the ad frame
|
||||
// root.
|
||||
std::optional<url::Origin> ad_root_origin = std::nullopt;
|
||||
if (frame_tree_node_->GetFencedFrameProperties()->is_ad_component()) {
|
||||
FrameTreeNode* ad_component_root =
|
||||
frame_tree_node_->GetClosestAncestorWithFencedFrameProperties();
|
||||
FrameTreeNode* ad_root =
|
||||
ad_component_root->GetParentOrOuterDocument()
|
||||
->frame_tree_node()
|
||||
->GetClosestAncestorWithFencedFrameProperties();
|
||||
ad_root_origin = ad_root->current_frame_host()->GetLastCommittedOrigin();
|
||||
}
|
||||
|
||||
if (!frame_tree_node_->GetFencedFrameProperties()
|
||||
->fenced_frame_reporter()
|
||||
->SendReport(
|
||||
event_variant, destination, /*request_initiator_frame=*/this,
|
||||
fenced_frame_data->features(), error_message,
|
||||
console_message_level, GetFrameTreeNodeId(), navigation_id)) {
|
||||
->SendReport(event_variant, destination,
|
||||
/*request_initiator_frame=*/this,
|
||||
fenced_frame_data->features(), error_message,
|
||||
console_message_level, GetFrameTreeNodeId(),
|
||||
navigation_id, ad_root_origin)) {
|
||||
AddMessageToConsole(console_message_level, error_message);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ FencedFrameTestHelper::FencedFrameTestHelper() {
|
||||
{blink::features::kFencedFramesM120FeaturesPart2, {}},
|
||||
{blink::features::kFencedFramesLocalUnpartitionedDataAccess, {}},
|
||||
{blink::features::kFencedFramesCrossOriginEventReportingUnlabeledTraffic,
|
||||
{}}},
|
||||
{}},
|
||||
{blink::features::kFencedFramesReportEventHeaderChanges, {}}},
|
||||
{/* disabled_features */});
|
||||
}
|
||||
|
||||
|
@ -8905,6 +8905,26 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"FencedFramesEnableReportEventHeaderChanges": [
|
||||
{
|
||||
"platforms": [
|
||||
"android",
|
||||
"chromeos",
|
||||
"chromeos_lacros",
|
||||
"linux",
|
||||
"mac",
|
||||
"windows"
|
||||
],
|
||||
"experiments": [
|
||||
{
|
||||
"name": "Enabled",
|
||||
"enable_features": [
|
||||
"FencedFramesReportEventHeaderChanges"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"FenderAutoPreconnectLcpOrigins": [
|
||||
{
|
||||
"platforms": [
|
||||
|
4
third_party/blink/common/features.cc
vendored
4
third_party/blink/common/features.cc
vendored
@ -903,6 +903,10 @@ BASE_FEATURE(kFencedFramesLocalUnpartitionedDataAccess,
|
||||
"FencedFramesLocalUnpartitionedDataAccess",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
BASE_FEATURE(kFencedFramesReportEventHeaderChanges,
|
||||
"FencedFramesReportEventHeaderChanges",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
// Controls access to an API to exempt certain URLs from fenced frame
|
||||
// network revocation to facilitate testing.
|
||||
BASE_FEATURE(kExemptUrlFromNetworkRevocationForTesting,
|
||||
|
1
third_party/blink/public/common/features.h
vendored
1
third_party/blink/public/common/features.h
vendored
@ -464,6 +464,7 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(
|
||||
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(
|
||||
kFencedFramesLocalUnpartitionedDataAccess);
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kFencedFramesReportEventHeaderChanges);
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(
|
||||
kExemptUrlFromNetworkRevocationForTesting);
|
||||
|
||||
|
@ -1811,7 +1811,7 @@
|
||||
"external/wpt/shared-storage",
|
||||
"http/tests/inspector-protocol/shared-storage"
|
||||
],
|
||||
"args": ["--enable-features=SharedStorageAPI,FencedFrames:implementation_type/mparch,PrivacySandboxAdsAPIsOverride,FencedFramesAPIChanges,FencedFramesDefaultMode,SharedStorageAPIM118,SharedStorageAPIM125,SharedStorageAPIEnableWALForDatabase,FencedFramesEnforceFocus",
|
||||
"args": ["--enable-features=SharedStorageAPI,FencedFrames:implementation_type/mparch,PrivacySandboxAdsAPIsOverride,FencedFramesAPIChanges,FencedFramesDefaultMode,SharedStorageAPIM118,SharedStorageAPIM125,SharedStorageAPIEnableWALForDatabase,FencedFramesEnforceFocus,FencedFramesReportEventHeaderChanges",
|
||||
"--disable-threaded-compositing", "--disable-threaded-animation"],
|
||||
"expires": "Jul 31, 2024"
|
||||
},
|
||||
@ -1858,7 +1858,7 @@
|
||||
"external/wpt/fetch/private-network-access/fenced-frame.tentative.https.window.js",
|
||||
"external/wpt/fetch/private-network-access/fenced-frame-no-preflight-required.tentative.https.window.js"
|
||||
],
|
||||
"args": ["--enable-features=PrivacySandboxAdsAPIsOverride,Fledge,AdInterestGroupAPI,FencedFramesEnforceFocus,FencedFramesLocalUnpartitionedDataAccess,ExemptUrlFromNetworkRevocationForTesting,FencedFramesCrossOriginEventReportingAllTraffic",
|
||||
"args": ["--enable-features=PrivacySandboxAdsAPIsOverride,Fledge,AdInterestGroupAPI,FencedFramesEnforceFocus,FencedFramesLocalUnpartitionedDataAccess,ExemptUrlFromNetworkRevocationForTesting,FencedFramesCrossOriginEventReportingAllTraffic,FencedFramesReportEventHeaderChanges",
|
||||
"--enable-blink-features=FencedFramesDefaultMode",
|
||||
"--disable-threaded-compositing", "--disable-threaded-animation"],
|
||||
"expires": "May 1, 2025"
|
||||
|
@ -52,7 +52,8 @@ promise_test(async(t) => {
|
||||
.pointerUp()
|
||||
.send();
|
||||
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData);
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
|
||||
// Leaving this fenced frame around for subsequent tests can lead to
|
||||
// flakiness.
|
||||
|
6
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-click-handler.https.html
vendored
6
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-click-handler.https.html
vendored
@ -49,8 +49,10 @@ promise_test(async(t) => {
|
||||
.pointerUp()
|
||||
.send();
|
||||
|
||||
await verifyBeaconData(start_event.eventType, start_event.eventData);
|
||||
await verifyBeaconData(commit_event.eventType, commit_event.eventData);
|
||||
await verifyBeaconData(start_event.eventType, start_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
await verifyBeaconData(commit_event.eventType, commit_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
|
||||
// Leaving this fenced frame around for subsequent tests can lead to
|
||||
// flakiness.
|
||||
|
2
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-component-ad.https.html
vendored
2
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-component-ad.https.html
vendored
@ -18,6 +18,7 @@ promise_test(async(t) => {
|
||||
const fencedframe = await attachFencedFrameContext({
|
||||
generator_api: 'fledge',
|
||||
register_beacon: true,
|
||||
component_origin: get_host_info().HTTPS_REMOTE_ORIGIN,
|
||||
num_components: 1,
|
||||
// These headers will also be given to the component ad.
|
||||
headers: [["Allow-Fenced-Frame-Automatic-Beacons", "true"]]
|
||||
@ -49,6 +50,7 @@ promise_test(async(t) => {
|
||||
.send();
|
||||
|
||||
// The component frame should not use the data set in its parent.
|
||||
// The referrer header should be set to the root ad frame's origin.
|
||||
await verifyBeaconData(beacon_event.eventType, "<No data>");
|
||||
}, 'Automatic beacon in an ad component should send without data with a ' +
|
||||
'header opt-in.');
|
||||
|
3
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-cross-origin-false.https.html
vendored
3
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-cross-origin-false.https.html
vendored
@ -35,7 +35,8 @@ promise_test(async(t) => {
|
||||
.pointerUp()
|
||||
.send();
|
||||
|
||||
await verifyBeaconData(beacon_event.eventType, "<No data>");
|
||||
await verifyBeaconData(beacon_event.eventType, "<No data>",
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
}, 'Automatic beacon in a cross-origin subframe should send without data ' +
|
||||
'when crossOrigin=false.');
|
||||
</script>
|
||||
|
@ -40,8 +40,10 @@ promise_test(async(t) => {
|
||||
.pointerUp()
|
||||
.send();
|
||||
|
||||
await verifyBeaconData("reserved.top_navigation_start", "<No data>");
|
||||
await verifyBeaconData("reserved.top_navigation_commit", "<No data>");
|
||||
await verifyBeaconData("reserved.top_navigation_start", "<No data>",
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
await verifyBeaconData("reserved.top_navigation_commit", "<No data>",
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
}, 'Automatic beacon in a cross-origin subframe with no beacon data set');
|
||||
</script>
|
||||
</body>
|
||||
|
@ -37,8 +37,8 @@ promise_test(async(t) => {
|
||||
.pointerUp()
|
||||
.send();
|
||||
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData, false,
|
||||
t);
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN, false, t);
|
||||
}, 'Automatic beacon in a cross-origin subframe with no opt-in header should ' +
|
||||
'not send.');
|
||||
</script>
|
||||
|
3
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-no-destination.https.html
vendored
3
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-no-destination.https.html
vendored
@ -37,7 +37,8 @@ promise_test(async (t) => {
|
||||
// An automatic beacon should be sent out, but no data should be sent as part
|
||||
// of the beacon because the "buyer" destination was not specified in
|
||||
// setReportEventDataForAutomaticBeacons().
|
||||
await verifyBeaconData(beacon_event.eventType, "<No data>");
|
||||
await verifyBeaconData(beacon_event.eventType, "<No data>",
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
}, "Set and trigger an automatic beacon with no destination specified");
|
||||
|
||||
</script>
|
||||
|
4
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-no-opt-in.https.html
vendored
4
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-no-opt-in.https.html
vendored
@ -40,8 +40,8 @@ promise_test(async (t) => {
|
||||
.pointerDown()
|
||||
.pointerUp()
|
||||
.send();
|
||||
await verifyBeaconData("reserved.top_navigation_start", "<No data>", false,
|
||||
t);
|
||||
await verifyBeaconData("reserved.top_navigation_start", "<No data>", null,
|
||||
false, t);
|
||||
}, "Automatic beacons will not send if the document does not opt in.");
|
||||
|
||||
</script>
|
||||
|
6
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-shared-storage.https.html
vendored
6
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-shared-storage.https.html
vendored
@ -37,8 +37,10 @@ promise_test(async(t) => {
|
||||
.pointerUp()
|
||||
.send();
|
||||
|
||||
await verifyBeaconData(start_event.eventType, start_event.eventData);
|
||||
await verifyBeaconData(commit_event.eventType, commit_event.eventData);
|
||||
await verifyBeaconData(start_event.eventType, start_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
await verifyBeaconData(commit_event.eventType, commit_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
}, 'Set and trigger an automatic beacon in a click handler for SharedStorage');
|
||||
|
||||
</script>
|
||||
|
7
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-two-events-clear.https.html
vendored
7
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-two-events-clear.https.html
vendored
@ -34,7 +34,8 @@ promise_test(async(t) => {
|
||||
.pointerDown()
|
||||
.pointerUp()
|
||||
.send();
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData);
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
|
||||
// The second click should not have any associated automatic beacon info, so
|
||||
// no beacon should be sent.
|
||||
@ -44,8 +45,8 @@ promise_test(async(t) => {
|
||||
.pointerDown()
|
||||
.pointerUp()
|
||||
.send();
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData, false,
|
||||
t);
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN, false, t);
|
||||
}, 'Set expiring automatic beacon but trigger two events in a click handler');
|
||||
|
||||
</script>
|
||||
|
6
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-two-events-persist.https.html
vendored
6
third_party/blink/web_tests/external/wpt/fenced-frame/automatic-beacon-two-events-persist.https.html
vendored
@ -33,7 +33,8 @@ promise_test(async(t) => {
|
||||
.pointerDown()
|
||||
.pointerUp()
|
||||
.send();
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData);
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
|
||||
// The second click should still have associated automatic beacon data, and a
|
||||
// beacon should be sent.
|
||||
@ -41,7 +42,8 @@ promise_test(async(t) => {
|
||||
.pointerDown()
|
||||
.pointerUp()
|
||||
.send();
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData);
|
||||
await verifyBeaconData(beacon_event.eventType, beacon_event.eventData,
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN);
|
||||
}, 'Set persisting automatic beacon but trigger two events in a click handler');
|
||||
|
||||
</script>
|
||||
|
@ -43,8 +43,8 @@ promise_test(async(t) => {
|
||||
}
|
||||
window.fence.reportEvent(destination_url_event);
|
||||
});
|
||||
await verifyBeaconData("click", "enum", false, t);
|
||||
await verifyBeaconData("url", "<No data>", false, t);
|
||||
await verifyBeaconData("click", "enum", null, false, t);
|
||||
await verifyBeaconData("url", "<No data>", null, false, t);
|
||||
}, 'Cross-origin window.fence.reportEvent without embedder opt-in');
|
||||
</script>
|
||||
</body>
|
||||
|
@ -39,8 +39,8 @@ promise_test(async(t) => {
|
||||
});
|
||||
// Check that both the destination enum and destination URL events were
|
||||
// reported.
|
||||
await verifyBeaconData("click", "enum", false, t);
|
||||
await verifyBeaconData("url", "<No data>", false, t);
|
||||
await verifyBeaconData("click", "enum", null, false, t);
|
||||
await verifyBeaconData("url", "<No data>", null, false, t);
|
||||
}, 'Cross-origin window.fence.reportEvent without subframe opt-in');
|
||||
</script>
|
||||
</body>
|
||||
|
@ -43,8 +43,8 @@ promise_test(async(t) => {
|
||||
}
|
||||
window.fence.reportEvent(destination_url_event);
|
||||
});
|
||||
await verifyBeaconData("click", "enum", false, t);
|
||||
await verifyBeaconData("url", "<No data>", false, t);
|
||||
await verifyBeaconData("click", "enum", null, false, t);
|
||||
await verifyBeaconData("url", "<No data>", null, false, t);
|
||||
}, 'Cross-origin window.fence.reportEvent without embedder opt-in');
|
||||
</script>
|
||||
</body>
|
||||
|
@ -39,8 +39,8 @@ promise_test(async(t) => {
|
||||
});
|
||||
// Check that both the destination enum and destination URL events were
|
||||
// reported.
|
||||
await verifyBeaconData("click", "enum", false, t);
|
||||
await verifyBeaconData("url", "<No data>", false, t);
|
||||
await verifyBeaconData("click", "enum", null, false, t);
|
||||
await verifyBeaconData("url", "<No data>", null, false, t);
|
||||
}, 'Cross-origin window.fence.reportEvent without subframe opt-in');
|
||||
</script>
|
||||
</body>
|
||||
|
@ -16,11 +16,12 @@ promise_test(async(t) => {
|
||||
headers: [[
|
||||
'Allow-Cross-Origin-Event-Reporting', '?1'
|
||||
]],
|
||||
register_beacon: true
|
||||
register_beacon: true,
|
||||
origin: 'https://{{hosts[alt][]}}:{{ports[https][0]}}',
|
||||
});
|
||||
await fencedframe.execute(async () => {
|
||||
const iframe = await attachIFrameContext({
|
||||
origin: get_host_info().HTTPS_REMOTE_ORIGIN,
|
||||
origin: 'https://{{hosts[alt][]}}:{{ports[https][1]}}'
|
||||
});
|
||||
await iframe.execute(() => {
|
||||
const destination_url = new URL(BEACON_URL + "?type=url",
|
||||
@ -39,8 +40,24 @@ promise_test(async(t) => {
|
||||
});
|
||||
// Check that both the destination enum and destination URL events were
|
||||
// reported.
|
||||
await nextBeacon("click", "enum");
|
||||
await nextBeacon("url", "<No data>");
|
||||
const [enum_origin, enum_referrer] = await nextBeacon("click", "enum")
|
||||
.then(data => data.split(','));
|
||||
const [url_origin, url_referrer] = await nextBeacon("url", "<No data>")
|
||||
.then(data => data.split(','));
|
||||
|
||||
// Check the "Origin" headers are set to the origin that supplied the
|
||||
// reporting URL. For destination enum events, that's the origin of the
|
||||
// worklet. For destination URL events, that's the origin of the iframe.
|
||||
assert_equals(enum_origin, get_host_info().HTTPS_ORIGIN,
|
||||
'The enum origin should be correctly set.');
|
||||
assert_equals(url_origin, 'https://{{hosts[alt][]}}:{{ports[https][1]}}',
|
||||
'The url origin should be correctly set.');
|
||||
|
||||
assert_equals(enum_referrer,
|
||||
'https://{{hosts[alt][]}}:{{ports[https][1]}}/',
|
||||
'The enum referrer should be correctly set.');
|
||||
assert_equals(url_referrer, 'https://{{hosts[alt][]}}:{{ports[https][1]}}/',
|
||||
'The url referrer should be correctly set.');
|
||||
}, 'window.fence.reportEvent from a cross-origin subframe');
|
||||
</script>
|
||||
</body>
|
4
third_party/blink/web_tests/external/wpt/fenced-frame/fence-report-event-sub-fencedframe.https.html
vendored
4
third_party/blink/web_tests/external/wpt/fenced-frame/fence-report-event-sub-fencedframe.https.html
vendored
@ -39,8 +39,8 @@ promise_test(async(t) => {
|
||||
});
|
||||
// Check that both the destination enum and destination URL events were
|
||||
// reported.
|
||||
await verifyBeaconData("click", "enum", false, t);
|
||||
await verifyBeaconData("url", "<No data>", false, t);
|
||||
await verifyBeaconData("click", "enum", null, false, t);
|
||||
await verifyBeaconData("url", "<No data>", null, false, t);
|
||||
}, 'window.fence.reportEvent should not work in a nested fenced frame');
|
||||
</script>
|
||||
</body>
|
||||
|
@ -31,12 +31,22 @@
|
||||
window.fence.reportEvent(destination_url_event);
|
||||
});
|
||||
|
||||
let enum_data = await nextBeacon('click', 'enum');
|
||||
assert_equals(enum_data, location.origin);
|
||||
const [enum_origin, enum_referrer] = await nextBeacon("click", "enum")
|
||||
.then(data => data.split(','));
|
||||
const [url_origin, url_referrer] = await nextBeacon("url", "<No data>")
|
||||
.then(data => data.split(','));
|
||||
|
||||
let url_data = await nextBeacon('url', '<No data>');
|
||||
assert_equals(url_data, '<No data>');
|
||||
assert_equals(enum_origin, location.origin,
|
||||
'The enum origin should be correctly set.');
|
||||
// GET requests do not set an 'Origin' header if same-origin to the request's
|
||||
// destination.
|
||||
assert_equals(url_origin, '<No data>',
|
||||
'The url origin should be correctly set.');
|
||||
|
||||
assert_equals(enum_referrer, location.origin + "/",
|
||||
'The enum referrer should be correctly set.');
|
||||
assert_equals(url_referrer, location.origin + "/",
|
||||
'The url referrer should be correctly set.');
|
||||
}, 'Test that window.fence.reportEvent() succeeds in a fenced frame.');
|
||||
</script>
|
||||
</body>
|
27
third_party/blink/web_tests/external/wpt/fenced-frame/resources/automatic-beacon-helper.js
vendored
27
third_party/blink/web_tests/external/wpt/fenced-frame/resources/automatic-beacon-helper.js
vendored
@ -84,20 +84,31 @@ async function setupAutomaticBeacon(
|
||||
|
||||
// Checks if an automatic beacon of type `event_type` with contents `event_data`
|
||||
// was sent out or not.
|
||||
// event_type: The automatic beacon type to check.
|
||||
// event_data: The automatic beacon data to check.
|
||||
// expected_success: Whether we expect the automatic beacon to be sent.
|
||||
// t: The WPT's test object. Only required if
|
||||
// event_type: The automatic beacon type to check.
|
||||
// event_data: The automatic beacon data to check.
|
||||
// expected_referrer: The expected referrer header, if different from origin.
|
||||
// expected_success: Whether we expect the automatic beacon to be sent.
|
||||
// t: The WPT's test object. Only required if
|
||||
// expected_success = false.
|
||||
async function verifyBeaconData(
|
||||
event_type, event_data, expected_success = true, t) {
|
||||
event_type, event_data, expected_referrer = null, expected_success = true,
|
||||
t) {
|
||||
if (expected_success) {
|
||||
const beacon_initiator_origin = await nextBeacon(event_type, event_data);
|
||||
assert_equals(beacon_initiator_origin, get_host_info().HTTPS_ORIGIN);
|
||||
const data = await nextBeacon(event_type, event_data);
|
||||
const [beacon_initiator_origin, beacon_referrer] =
|
||||
data.split(",");
|
||||
assert_equals(beacon_initiator_origin, get_host_info().HTTPS_ORIGIN,
|
||||
"The initiator origin should be set as expected.");
|
||||
// The Referer header has a trailing '/' appended to the URL.
|
||||
assert_equals(beacon_referrer,
|
||||
(expected_referrer ? expected_referrer :
|
||||
get_host_info().HTTPS_ORIGIN) + "/",
|
||||
"The beacon referrer should be set as expected.");
|
||||
} else {
|
||||
const timeout = new Promise(r => t.step_timeout(r, 1000));
|
||||
const result =
|
||||
await Promise.race([nextBeacon(event_type, event_data), timeout]);
|
||||
assert_true(typeof result === 'undefined');
|
||||
assert_true(typeof result === 'undefined',
|
||||
"The beacon should not have sent.");
|
||||
}
|
||||
}
|
||||
|
3
third_party/blink/web_tests/external/wpt/fenced-frame/resources/automatic-beacon-unfenced-page.html
vendored
3
third_party/blink/web_tests/external/wpt/fenced-frame/resources/automatic-beacon-unfenced-page.html
vendored
@ -15,7 +15,8 @@
|
||||
const beacon_data = "This is the beacon data!";
|
||||
const beacon_initiator_origin = await nextBeacon(
|
||||
"reserved.top_navigation_commit", beacon_data);
|
||||
assert_equals(beacon_initiator_origin, get_host_info().HTTPS_ORIGIN);
|
||||
assert_equals(beacon_initiator_origin, get_host_info().HTTPS_ORIGIN + "," +
|
||||
get_host_info().HTTPS_REMOTE_ORIGIN + "/");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
@ -43,14 +43,18 @@ def main(request, response):
|
||||
# (either through reportEvent() or through an automatic beacon).
|
||||
if request.method == "POST" and event_type:
|
||||
request_body = request.body or NO_DATA_STRING
|
||||
request_headers = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_origin = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_referrer = request.headers.get("Referer") or NO_DATA_STRING
|
||||
stash.put(string_to_uuid(event_type + request_body),
|
||||
request_headers)
|
||||
(request_origin + b"," + request_referrer))
|
||||
return (200, [], b"")
|
||||
# GET requests without an 'expected_body' parameter imply they were sent
|
||||
# as a destination URL reporting beacon.
|
||||
if request.method == "GET" and event_type:
|
||||
stash.put(string_to_uuid(event_type + NO_DATA_STRING), NO_DATA_STRING)
|
||||
request_origin = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_referrer = request.headers.get("Referer") or NO_DATA_STRING
|
||||
stash.put(string_to_uuid(event_type + NO_DATA_STRING),
|
||||
(request_origin + b"," + request_referrer))
|
||||
return (200, [], b"")
|
||||
|
||||
return (400, [], u"")
|
||||
|
@ -283,13 +283,13 @@ function attachContext(object_constructor, html, headers, origin) {
|
||||
async function attachOpaqueContext(
|
||||
generator_api, resolve_to_config, ad_with_size, requested_size,
|
||||
register_beacon, object_constructor, html, headers, origin,
|
||||
num_components) {
|
||||
component_origin, num_components) {
|
||||
const [uuid, url] = generateRemoteContextURL(headers, origin);
|
||||
|
||||
let components_list = [];
|
||||
for (let i = 0; i < num_components; i++) {
|
||||
let [component_uuid, component_url] =
|
||||
generateRemoteContextURL(headers, origin);
|
||||
generateRemoteContextURL(headers, component_origin);
|
||||
// This field will be read by attachComponentFrameContext() in order to
|
||||
// know what uuid to point to when building the remote context.
|
||||
html += '<input type=\'hidden\' id=\'component_uuid_' + i + '\' value=\'' +
|
||||
@ -309,13 +309,14 @@ async function attachOpaqueContext(
|
||||
|
||||
function attachPotentiallyOpaqueContext(
|
||||
generator_api, resolve_to_config, ad_with_size, requested_size,
|
||||
register_beacon, frame_constructor, html, headers, origin, num_components) {
|
||||
register_beacon, frame_constructor, html, headers, origin,
|
||||
component_origin, num_components) {
|
||||
generator_api = generator_api.toLowerCase();
|
||||
if (generator_api == 'fledge' || generator_api == 'sharedstorage') {
|
||||
return attachOpaqueContext(
|
||||
generator_api, resolve_to_config, ad_with_size, requested_size,
|
||||
register_beacon, frame_constructor, html, headers, origin,
|
||||
num_components);
|
||||
component_origin, num_components);
|
||||
} else {
|
||||
return attachContext(frame_constructor, html, headers, origin);
|
||||
}
|
||||
@ -324,7 +325,7 @@ function attachPotentiallyOpaqueContext(
|
||||
function attachFrameContext(
|
||||
element_name, generator_api, resolve_to_config, ad_with_size,
|
||||
requested_size, register_beacon, html, headers, attributes, origin,
|
||||
num_components) {
|
||||
component_origin, num_components) {
|
||||
frame_constructor = (id) => {
|
||||
frame = document.createElement(element_name);
|
||||
attributes.forEach(attribute => {
|
||||
@ -344,7 +345,7 @@ function attachFrameContext(
|
||||
return attachPotentiallyOpaqueContext(
|
||||
generator_api, resolve_to_config, ad_with_size, requested_size,
|
||||
register_beacon, frame_constructor, html, headers, origin,
|
||||
num_components);
|
||||
component_origin, num_components);
|
||||
}
|
||||
|
||||
// Performs a content-initiated navigation of a frame proxy. This navigated page
|
||||
@ -420,12 +421,13 @@ function attachFencedFrameContext({
|
||||
headers = [],
|
||||
attributes = [],
|
||||
origin = '',
|
||||
component_origin = '',
|
||||
num_components = 0
|
||||
} = {}) {
|
||||
return attachFrameContext(
|
||||
'fencedframe', generator_api, resolve_to_config, ad_with_size,
|
||||
requested_size, register_beacon, html, headers, attributes, origin,
|
||||
num_components);
|
||||
component_origin, num_components);
|
||||
}
|
||||
|
||||
// Attach an iframe that waits for scripts to execute.
|
||||
@ -437,12 +439,13 @@ function attachIFrameContext({
|
||||
headers = [],
|
||||
attributes = [],
|
||||
origin = '',
|
||||
component_origin = '',
|
||||
num_components = 0
|
||||
} = {}) {
|
||||
return attachFrameContext(
|
||||
'iframe', generator_api, resolve_to_config = false, ad_with_size = false,
|
||||
requested_size = null, register_beacon, html, headers, attributes, origin,
|
||||
num_components);
|
||||
component_origin, num_components);
|
||||
}
|
||||
|
||||
// Open a window that waits for scripts to execute.
|
||||
|
@ -4,6 +4,7 @@ request headers: undefined
|
||||
request data: dummy
|
||||
requestExtraInfo has same requestId: true
|
||||
requestExtraInfo has headers: true
|
||||
requestExtraInfo referer: https://127.0.0.1:8443/
|
||||
responseReceived has same requestId: true
|
||||
responseReceived status: 200
|
||||
loadingFinished has same requestId: true
|
||||
|
2
third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/reporting-beacon.https.js
vendored
2
third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/reporting-beacon.https.js
vendored
@ -72,6 +72,8 @@
|
||||
+ (request.requestId === requestExtraInfo.requestId));
|
||||
testRunner.log('requestExtraInfo has headers: '
|
||||
+ (Object.keys(requestExtraInfo.params.headers).length > 0));
|
||||
testRunner.log('requestExtraInfo referer: '
|
||||
+ requestExtraInfo.params.headers.Referer);
|
||||
|
||||
// The request should succeed with a 200 status code.
|
||||
testRunner.log('responseReceived has same requestId: '
|
||||
|
11
third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/resources/beacon-store.py
vendored
11
third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/resources/beacon-store.py
vendored
@ -19,14 +19,12 @@ import hashlib
|
||||
NO_DATA_STRING = b"<No data>"
|
||||
NOT_SET_STRING = b"<Not set>"
|
||||
|
||||
|
||||
# The server stash requires a uuid to store data. Use a hash of the automatic
|
||||
# beacon data as the uuid to store and retrieve the data.
|
||||
def string_to_uuid(input):
|
||||
hash_value = hashlib.md5(str(input).encode("UTF-8")).hexdigest()
|
||||
return str(uuid.UUID(hex=hash_value))
|
||||
|
||||
|
||||
def main(request, response):
|
||||
stash = request.server.stash
|
||||
event_type = request.GET.first(b"type", NO_DATA_STRING)
|
||||
@ -46,15 +44,18 @@ def main(request, response):
|
||||
# (either through reportEvent() or through an automatic beacon).
|
||||
if request.method == "POST" and event_type:
|
||||
request_body = request.body or NO_DATA_STRING
|
||||
request_headers = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_origin = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_referrer = request.headers.get("Referer") or NO_DATA_STRING
|
||||
stash.put(string_to_uuid(event_type + request_body),
|
||||
request_headers)
|
||||
(request_origin + b"," + request_referrer))
|
||||
return (200, [], b"")
|
||||
# GET requests without an 'expected_body' parameter imply they were sent
|
||||
# as a destination URL reporting beacon.
|
||||
if request.method == "GET" and event_type:
|
||||
request_origin = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_referrer = request.headers.get("Referer") or NO_DATA_STRING
|
||||
stash.put(string_to_uuid(event_type + NO_DATA_STRING),
|
||||
NO_DATA_STRING)
|
||||
(request_origin + b"," + request_referrer))
|
||||
return (200, [], b"")
|
||||
|
||||
return (400, [], u"")
|
||||
|
12
third_party/blink/web_tests/wpt_internal/fenced_frame/automatic-beacon-ctrl-click.https.html
vendored
12
third_party/blink/web_tests/wpt_internal/fenced_frame/automatic-beacon-ctrl-click.https.html
vendored
@ -48,18 +48,22 @@ promise_test(async(t) => {
|
||||
eventSender.mouseUp(0, [isMac ? 'metaKey' : 'ctrlKey']);
|
||||
}, [new_url, beacon_data, beacon_type]);
|
||||
|
||||
const received_beacon_origin =
|
||||
await nextBeacon(beacon_type, beacon_data);
|
||||
const [received_beacon_origin, received_beacon_referrer] =
|
||||
await nextBeacon(beacon_type, beacon_data).then(data => data.split(","));
|
||||
assert_equals(received_beacon_origin, location.origin);
|
||||
assert_equals(received_beacon_referrer, location.origin + "/");
|
||||
|
||||
// Also test automatic beacons with middle clicks
|
||||
await fencedframe.execute(() => {
|
||||
eventSender.mouseDown(1);
|
||||
eventSender.mouseUp(1);
|
||||
}, []);
|
||||
const middle_click_nav_received_beacon_origin = await
|
||||
nextBeacon(beacon_type, beacon_data);
|
||||
const [middle_click_nav_received_beacon_origin,
|
||||
middle_click_nav_received_beacon_referrer] = await
|
||||
nextBeacon(beacon_type, beacon_data).then(data => data.split(","));
|
||||
assert_equals(middle_click_nav_received_beacon_origin, location.origin);
|
||||
assert_equals(middle_click_nav_received_beacon_referrer,
|
||||
location.origin + "/");
|
||||
}, 'Trigger an automatic beacon from ctrl+clicking a link.');
|
||||
|
||||
</script>
|
||||
|
@ -19,14 +19,12 @@ import hashlib
|
||||
NO_DATA_STRING = b"<No data>"
|
||||
NOT_SET_STRING = b"<Not set>"
|
||||
|
||||
|
||||
# The server stash requires a uuid to store data. Use a hash of the automatic
|
||||
# beacon data as the uuid to store and retrieve the data.
|
||||
def string_to_uuid(input):
|
||||
hash_value = hashlib.md5(str(input).encode("UTF-8")).hexdigest()
|
||||
return str(uuid.UUID(hex=hash_value))
|
||||
|
||||
|
||||
def main(request, response):
|
||||
stash = request.server.stash
|
||||
event_type = request.GET.first(b"type", NO_DATA_STRING)
|
||||
@ -46,15 +44,18 @@ def main(request, response):
|
||||
# (either through reportEvent() or through an automatic beacon).
|
||||
if request.method == "POST" and event_type:
|
||||
request_body = request.body or NO_DATA_STRING
|
||||
request_headers = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_origin = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_referrer = request.headers.get("Referer") or NO_DATA_STRING
|
||||
stash.put(string_to_uuid(event_type + request_body),
|
||||
request_headers)
|
||||
(request_origin + b"," + request_referrer))
|
||||
return (200, [], b"")
|
||||
# GET requests without an 'expected_body' parameter imply they were sent
|
||||
# as a destination URL reporting beacon.
|
||||
if request.method == "GET" and event_type:
|
||||
request_origin = request.headers.get("Origin") or NO_DATA_STRING
|
||||
request_referrer = request.headers.get("Referer") or NO_DATA_STRING
|
||||
stash.put(string_to_uuid(event_type + NO_DATA_STRING),
|
||||
NO_DATA_STRING)
|
||||
(request_origin + b"," + request_referrer))
|
||||
return (200, [], b"")
|
||||
|
||||
return (400, [], u"")
|
||||
|
Reference in New Issue
Block a user