Commit e8c7efa7 authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Commit Bot

[Periodic Background Sync] Require main frame host for registration.

Only allow Periodic Background Sync registration if the requesting
origin has a main frame host present.

Add browsertests to verify this behavior.

Corresponding PR against the spec: https://github.com/WICG/BackgroundSync/pull/160

Bug: 1029712
Change-Id: I1142578edbde62f3f27ae95b9ca602855df3543b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1942433
Commit-Queue: Mugdha Lakhani <nator@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720483}
parent 69503031
...@@ -29,6 +29,8 @@ const char kDefaultTestURL[] = "/background_sync/test.html"; ...@@ -29,6 +29,8 @@ const char kDefaultTestURL[] = "/background_sync/test.html";
const char kEmptyURL[] = "/background_sync/empty.html"; const char kEmptyURL[] = "/background_sync/empty.html";
const char kRegisterSyncFromIFrameURL[] = const char kRegisterSyncFromIFrameURL[] =
"/background_sync/register_sync_from_iframe.html"; "/background_sync/register_sync_from_iframe.html";
const char kRegisterPeriodicSyncFromIFrameURL[] =
"/background_sync/register_periodicsync_from_iframe.html";
const char kRegisterSyncFromSWURL[] = const char kRegisterSyncFromSWURL[] =
"/background_sync/register_sync_from_sw.html"; "/background_sync/register_sync_from_sw.html";
const char kSuccessfulOperationPrefix[] = "ok - "; const char kSuccessfulOperationPrefix[] = "ok - ";
......
...@@ -402,32 +402,16 @@ void BackgroundSyncManager::Register( ...@@ -402,32 +402,16 @@ void BackgroundSyncManager::Register(
DCHECK(options.min_interval >= 0 || DCHECK(options.min_interval >= 0 ||
options.min_interval == kMinIntervalForOneShotSync); options.min_interval == kMinIntervalForOneShotSync);
if (GetBackgroundSyncType(options) == BackgroundSyncType::ONE_SHOT) { auto id = op_scheduler_.CreateId();
auto id = op_scheduler_.CreateId(); op_scheduler_.ScheduleOperation(
op_scheduler_.ScheduleOperation( id, CacheStorageSchedulerMode::kExclusive,
id, CacheStorageSchedulerMode::kExclusive, CacheStorageSchedulerOp::kBackgroundSync,
CacheStorageSchedulerOp::kBackgroundSync, CacheStorageSchedulerPriority::kNormal,
CacheStorageSchedulerPriority::kNormal, base::BindOnce(
base::BindOnce( &BackgroundSyncManager::RegisterCheckIfHasMainFrame,
&BackgroundSyncManager::RegisterCheckIfHasMainFrame, weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
weak_ptr_factory_.GetWeakPtr(), sw_registration_id, std::move(options),
std::move(options), op_scheduler_.WrapCallbackToRunNext(id, std::move(callback))));
op_scheduler_.WrapCallbackToRunNext(id, std::move(callback))));
} else {
// Periodic Background Sync events already have a pre-defined cadence which
// the user agent decides. Don't block registration if there's no top level
// frame at the time of registration.
auto id = op_scheduler_.CreateId();
op_scheduler_.ScheduleOperation(
id, CacheStorageSchedulerMode::kExclusive,
CacheStorageSchedulerOp::kBackgroundSync,
CacheStorageSchedulerPriority::kNormal,
base::BindOnce(
&BackgroundSyncManager::RegisterImpl,
weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
std::move(options),
op_scheduler_.WrapCallbackToRunNext(id, std::move(callback))));
}
} }
void BackgroundSyncManager::UnregisterPeriodicSync( void BackgroundSyncManager::UnregisterPeriodicSync(
......
...@@ -24,8 +24,11 @@ class PeriodicBackgroundSyncBrowserTest : public BackgroundSyncBaseBrowserTest { ...@@ -24,8 +24,11 @@ class PeriodicBackgroundSyncBrowserTest : public BackgroundSyncBaseBrowserTest {
~PeriodicBackgroundSyncBrowserTest() override {} ~PeriodicBackgroundSyncBrowserTest() override {}
bool Register(const std::string& tag, int min_interval_ms); bool Register(const std::string& tag, int min_interval_ms);
bool RegisterFromIFrame(const std::string& tag, int min_interval_ms);
bool RegisterNoMinInterval(const std::string& tag); bool RegisterNoMinInterval(const std::string& tag);
bool RegisterFromServiceWorker(const std::string& tag, int min_interval_ms); bool RegisterFromServiceWorker(const std::string& tag, int min_interval_ms);
bool RegisterFromCrossOriginFrame(const std::string& frame_url,
std::string* script_result);
bool RegisterFromServiceWorkerNoMinInterval(const std::string& tag); bool RegisterFromServiceWorkerNoMinInterval(const std::string& tag);
bool HasTag(const std::string& tag); bool HasTag(const std::string& tag);
bool HasTagFromServiceWorker(const std::string& tag); bool HasTagFromServiceWorker(const std::string& tag);
...@@ -50,6 +53,31 @@ bool PeriodicBackgroundSyncBrowserTest::Register(const std::string& tag, ...@@ -50,6 +53,31 @@ bool PeriodicBackgroundSyncBrowserTest::Register(const std::string& tag,
return script_result == BuildExpectedResult(tag, "registered"); return script_result == BuildExpectedResult(tag, "registered");
} }
bool PeriodicBackgroundSyncBrowserTest::RegisterFromIFrame(
const std::string& tag,
int min_interval_ms) {
std::string script_result;
EXPECT_TRUE(RunScript(
base::StringPrintf("%s('%s', %d);", "registerPeriodicSyncFromIFrame",
tag.c_str(), min_interval_ms),
&script_result));
return script_result == BuildExpectedResult(tag, "registered");
}
bool PeriodicBackgroundSyncBrowserTest::RegisterFromCrossOriginFrame(
const std::string& frame_url,
std::string* script_result) {
// Start a second https server to use as a second origin.
net::EmbeddedTestServer alt_server(net::EmbeddedTestServer::TYPE_HTTPS);
alt_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
EXPECT_TRUE(alt_server.Start());
GURL url = alt_server.GetURL(frame_url);
return RunScript(
BuildScriptString("registerPeriodicSyncFromCrossOriginFrame", url.spec()),
script_result);
}
bool PeriodicBackgroundSyncBrowserTest::RegisterNoMinInterval( bool PeriodicBackgroundSyncBrowserTest::RegisterNoMinInterval(
const std::string& tag) { const std::string& tag) {
std::string script_result; std::string script_result;
...@@ -137,6 +165,30 @@ IN_PROC_BROWSER_TEST_F(PeriodicBackgroundSyncBrowserTest, ...@@ -137,6 +165,30 @@ IN_PROC_BROWSER_TEST_F(PeriodicBackgroundSyncBrowserTest,
EXPECT_TRUE(Unregister("foo")); EXPECT_TRUE(Unregister("foo"));
} }
IN_PROC_BROWSER_TEST_F(PeriodicBackgroundSyncBrowserTest,
RegisterFromIFrameWithTopLevelFrameForOrigin) {
std::string script_result;
GURL url = https_server()->GetURL(kEmptyURL);
EXPECT_TRUE(RunScript(
BuildScriptString("registerPeriodicSyncFromLocalFrame", url.spec()),
&script_result));
// This succeeds because there's a top level frame for the origin.
EXPECT_EQ(BuildExpectedResult("iframe", "registered periodicSync"),
script_result);
}
IN_PROC_BROWSER_TEST_F(PeriodicBackgroundSyncBrowserTest,
RegisterFromIFrameWithoutTopLevelFrameForOrigin) {
std::string script_result;
EXPECT_TRUE(RegisterFromCrossOriginFrame(kRegisterPeriodicSyncFromIFrameURL,
&script_result));
// This fails because there's no top level frame open for the origin.
EXPECT_EQ(BuildExpectedResult("frame", "failed to register periodicSync"),
script_result);
}
// Verify that Register works in a service worker // Verify that Register works in a service worker
IN_PROC_BROWSER_TEST_F(PeriodicBackgroundSyncBrowserTest, IN_PROC_BROWSER_TEST_F(PeriodicBackgroundSyncBrowserTest,
RegisterFromServiceWorker) { RegisterFromServiceWorker) {
......
...@@ -102,7 +102,7 @@ function registerPeriodicSync(tag, minInterval) { ...@@ -102,7 +102,7 @@ function registerPeriodicSync(tag, minInterval) {
.catch(sendErrorToTest); .catch(sendErrorToTest);
} }
function registerPeriodicSyncFromLocalFrame(frame_url, minInterval) { function registerPeriodicSyncFromLocalFrame(frame_url) {
let frameWindow; let frameWindow;
return createFrame(frame_url) return createFrame(frame_url)
.then((frame) => { .then((frame) => {
...@@ -114,14 +114,26 @@ function registerPeriodicSyncFromLocalFrame(frame_url, minInterval) { ...@@ -114,14 +114,26 @@ function registerPeriodicSyncFromLocalFrame(frame_url, minInterval) {
}) })
.then((frame_registration) => { .then((frame_registration) => {
return frame_registration.periodicSync.register( return frame_registration.periodicSync.register(
'foo', {minInterval: minInterval}); 'foo', {});
}) })
.then(() => { .then(() => {
sendResultToTest('ok - iframe registered periodic sync'); sendResultToTest('ok - iframe registered periodicSync');
}) })
.catch(sendErrorToTest); .catch(sendErrorToTest);
} }
function registerPeriodicSyncFromCrossOriginFrame(cross_frame_url) {
return createFrame(cross_frame_url)
.then((frame) => receiveMessage())
.then((message) => {
if (message !== 'registration failed') {
sendResultToTest('failed - ' + message);
return;
}
sendResultToTest('ok - frame failed to register periodicSync');
});
}
function registerPeriodicSyncFromServiceWorker(tag, minInterval) { function registerPeriodicSyncFromServiceWorker(tag, minInterval) {
navigator.serviceWorker.ready navigator.serviceWorker.ready
.then((swRegistration) => { .then((swRegistration) => {
......
<!DOCTYPE html>
<html>
<head>
<title>Periodic Background Sync Register From IFrame Test</title>
<script src="register_periodicsync_from_iframe.js"></script>
</head>
</html>
// Copyright 2019 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.
'use strict';
navigator.serviceWorker.register('empty_service_worker.js')
.then(() => navigator.serviceWorker.ready)
.then(registration => registration.periodicSync.register('foo', {}))
.then(() => parent.postMessage('registration succeeded', '*'),
() => parent.postMessage('registration failed', '*'));
...@@ -8,4 +8,4 @@ navigator.serviceWorker.register('empty_service_worker.js') ...@@ -8,4 +8,4 @@ navigator.serviceWorker.register('empty_service_worker.js')
.then(() => navigator.serviceWorker.ready) .then(() => navigator.serviceWorker.ready)
.then(registration => registration.sync.register('foo')) .then(registration => registration.sync.register('foo'))
.then(() => parent.postMessage('registration succeeded', '*'), .then(() => parent.postMessage('registration succeeded', '*'),
() => parent.postMessage('registration failed', '*')); () => parent.postMessage('registration failed', '*'));
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