| // Utility functions to help testing keepalive requests. |
| |
| // Returns a URL to an iframe that loads a keepalive URL on iframe loaded. |
| // |
| // The keepalive URL points to a target that stores `token`. The token will then |
| // be posted back on iframe loaded to the parent document. |
| // `method` defaults to GET. |
| // `frameOrigin` to specify the origin of the iframe to load. If not set, |
| // default to a different site origin. |
| // `requestOrigin` to specify the origin of the fetch request target. |
| // `sendOn` to specify the name of the event when the keepalive request should |
| // be sent instead of the default 'load'. |
| // `mode` to specify the fetch request's CORS mode. |
| // `disallowOrigin` to ask the iframe to set up a server that forbids CORS |
| // requests. |
| function getKeepAliveIframeUrl(token, method, { |
| frameOrigin = 'DEFAULT', |
| requestOrigin = '', |
| sendOn = 'load', |
| mode = 'cors', |
| disallowOrigin = false |
| } = {}) { |
| const https = location.protocol.startsWith('https'); |
| frameOrigin = frameOrigin === 'DEFAULT' ? |
| get_host_info()[https ? 'HTTPS_NOTSAMESITE_ORIGIN' : 'HTTP_NOTSAMESITE_ORIGIN'] : |
| frameOrigin; |
| return `${frameOrigin}/fetch/api/resources/keepalive-iframe.html?` + |
| `token=${token}&` + |
| `method=${method}&` + |
| `sendOn=${sendOn}&` + |
| `mode=${mode}&` + (disallowOrigin ? `disallowOrigin=1&` : ``) + |
| `origin=${requestOrigin}`; |
| } |
| |
| // Returns a different-site URL to an iframe that loads a keepalive URL. |
| // |
| // By default, the keepalive URL points to a target that redirects to another |
| // same-origin destination storing `token`. The token will then be posted back |
| // to parent document. |
| // |
| // The URL redirects can be customized from `origin1` to `origin2` if provided. |
| // Sets `withPreflight` to true to get URL enabling preflight. |
| function getKeepAliveAndRedirectIframeUrl( |
| token, origin1, origin2, withPreflight) { |
| const https = location.protocol.startsWith('https'); |
| const frameOrigin = |
| get_host_info()[https ? 'HTTPS_NOTSAMESITE_ORIGIN' : 'HTTP_NOTSAMESITE_ORIGIN']; |
| return `${frameOrigin}/fetch/api/resources/keepalive-redirect-iframe.html?` + |
| `token=${token}&` + |
| `origin1=${origin1}&` + |
| `origin2=${origin2}&` + (withPreflight ? `with-headers` : ``); |
| } |
| |
| async function iframeLoaded(iframe) { |
| return new Promise((resolve) => iframe.addEventListener('load', resolve)); |
| } |
| |
| // Obtains the token from the message posted by iframe after loading |
| // `getKeepAliveAndRedirectIframeUrl()`. |
| async function getTokenFromMessage() { |
| return new Promise((resolve) => { |
| window.addEventListener('message', (event) => { |
| resolve(event.data); |
| }, {once: true}); |
| }); |
| } |
| |
| // Tells if `token` has been stored in the server. |
| async function queryToken(token) { |
| const response = await fetch(`../resources/stash-take.py?key=${token}`); |
| const json = await response.json(); |
| return json; |
| } |
| |
| // In order to parallelize the work, we are going to have an async_test |
| // for the rest of the work. Note that we want the serialized behavior |
| // for the steps so far, so we don't want to make the entire test case |
| // an async_test. |
| function assertStashedTokenAsync(testName, token, {shouldPass = true} = {}) { |
| async_test((test) => { |
| new Promise((resolve) => test.step_timeout(resolve, 3000)) |
| .then(() => { |
| return queryToken(token); |
| }) |
| .then((result) => { |
| assert_equals(result, 'on'); |
| }) |
| .then(() => { |
| test.done(); |
| }) |
| .catch(test.step_func((e) => { |
| if (shouldPass) { |
| assert_unreached(e); |
| } else { |
| test.done(); |
| } |
| })); |
| }, testName); |
| } |