Skip to content

Commit 6e901b5

Browse files
mingycchromium-wpt-export-bot
authored andcommitted
[fetch-later] Add FetchLaterParams into network::mojom::URLRequest.
Sequence Diagram: https://docs.google.com/document/d/1U8XSnICPY3j-fjzG35UVm6zjwL6LvX6ETU3T8WrzLyQ/edit#heading=h.y51nt9atd97v - Replace `URLRequest::is_fetch_later_api` with `URLRequest::fetch_later_params`. - Define `FetchLaterPrams`, which includes a pending_remote of FetchLaterClient. - Define `FetchLaterClient`, which supports `SetFetchLaterHost()` and `Clone()`. The former should be implemented in blink to support Renderer->Browser communication. - Define `FetchLaterHost`, which is implemented by every KeepAliveURLLoader. It supports a one-time method `SendNow()` and `Abort()`. - Aborting a FetchLater request right after calling fetchLater(), and then disposing a page, can introduce race condition, such that the browser still send out the request. In KeepAliveURLLoader, it tries to mitigate this by looking into the custom disconnection reason from the remote of FetchLaterClient. But the race can still happen. OT info will include this problem. See the "Renderer->Browser Communication" section [1] for the details and other considered alternatives. Subsequent CL https://crrev.com/c/4803283 will use this interface to implement fetchLater()'s backgroundTimeout feature. [1]: https://docs.google.com/document/d/1U8XSnICPY3j-fjzG35UVm6zjwL6LvX6ETU3T8WrzLyQ/edit#heading=h.15fe7ufeo4uv Bug: 1465781 Change-Id: Ib5067de1a10478cd0bb16ff6c4d981872bf5c1a6
1 parent 10645f3 commit 6e901b5

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// META: script=/resources/testharness.js
2+
// META: script=/resources/testharnessreport.js
3+
// META: script=/common/dispatcher/dispatcher.js
4+
// META: script=/common/get-host-info.sub.js
5+
// META: script=/common/utils.js
6+
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
7+
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
8+
// META: script=/pending-beacon/resources/pending_beacon-helper.js
9+
10+
'use strict';
11+
12+
parallelPromiseTest(async t => {
13+
const uuid = token();
14+
const url = generateSetBeaconURL(uuid);
15+
// Sets no option to test the default behavior when a document enters BFCache.
16+
const helper = new RemoteContextHelper();
17+
// Opens a window with noopener so that BFCache will work.
18+
const rc1 = await helper.addWindow(
19+
/*config=*/ null, /*options=*/ {features: 'noopener'});
20+
21+
// Creates a fetchLater request with default config in remote, which should
22+
// only be sent on page discarded (not on entering BFCache).
23+
await rc1.executeScript(url => {
24+
fetchLater(url);
25+
// Add a pageshow listener to stash the BFCache event.
26+
window.addEventListener('pageshow', e => {
27+
window.pageshowEvent = e;
28+
});
29+
}, [url]);
30+
// Navigates away to let page enter BFCache.
31+
const rc2 = await rc1.navigateToNew();
32+
// Navigate back.
33+
await rc2.historyBack();
34+
// Verify that the page was BFCached.
35+
assert_true(await rc1.executeScript(() => {
36+
return window.pageshowEvent.persisted;
37+
}));
38+
39+
await expectBeacon(uuid, {count: 0});
40+
}, `fetchLater() does not send on page entering BFCache.`);
41+
42+
parallelPromiseTest(async t => {
43+
const uuid = token();
44+
const url = generateSetBeaconURL(uuid);
45+
// Sets no option to test the default behavior when a document gets discarded
46+
// on navigated away.
47+
const helper = new RemoteContextHelper();
48+
// Opens a window without BFCache.
49+
const rc1 = await helper.addWindow();
50+
51+
// Creates 2 fetchLater requests in remote, and one of them is aborted
52+
// immediately. The other one should only be sent right on navigating away.
53+
await rc1.executeScript(url => {
54+
const controller = new AbortController();
55+
fetchLater(url, {signal: controller.signal});
56+
fetchLater(url);
57+
// Current implementation does not guarantee the execution of abort() in the
58+
// same task. Hence, put in anonymous task.
59+
(() => {
60+
controller.abort();
61+
})();
62+
// Add a pageshow listener to stash the BFCache event.
63+
window.addEventListener('pageshow', e => {
64+
window.pageshowEvent = e;
65+
});
66+
}, [url]);
67+
// Navigates away to trigger request sending.
68+
const rc2 = await rc1.navigateToNew();
69+
// Navigate back.
70+
await rc2.historyBack();
71+
// Verify that the page was NOT BFCached.
72+
assert_equals(undefined, await rc1.executeScript(() => {
73+
return window.pageshowEvent;
74+
}));
75+
76+
// TODO(crbug.com/1465781): Fix this in https://crrev.com/c/4803283.
77+
await expectBeacon(uuid, {count: 1});
78+
}, `fetchLater() does not send aborted request on navigating away a page w/o BFCache.`);

fetch/fetch-later/send-on-discard.tentative.https.window.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ parallelPromiseTest(async t => {
3636
const controller = new AbortController();
3737
fetchLater(url, {signal: controller.signal});
3838
fetchLater(url, {method: 'POST'});
39-
controller.abort();
39+
// Current implementation does not guarantee the execution of abort() in the
40+
// same task. Hence, put in anonymous task.
41+
(() => { controller.abort(); })();
4042
`);
4143
// Delete the iframe to trigger deferred request sending.
4244
document.body.removeChild(iframe);

0 commit comments

Comments
 (0)