Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

// META: script=/common/get-host-info.sub.js
// META: timeout=long
// META: script=/common/utils.js
// The report-to parameter of Cross-Origin-Embedder-Policy and
// Cross-Origin-Embedder-Policy-Report-Only is only used when it is a structured
// field string. Each test pairs a non-string report-to on one header with a
// string report-to on the other, so the latter shows that reports are sent.
const { REMOTE_ORIGIN } = get_host_info();
function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms));
}
async function fetchReports(key) {
const res = await fetch(`resources/report.py?key=${key}`, {
cache: 'no-store'
});
if (res.status == 200) {
return await res.json();
}
return [];
}
async function fetchCorpReports(key, blockedURL) {
const reports = await fetchReports(key);
return reports.filter(r => (
r.type == 'coep' &&
r.body.type == 'corp' &&
r.body.blockedURL === blockedURL));
}
// `reportTo` and `reportOnlyReportTo` are the report-to parameter values of the
// two headers. `expected` is the header whose endpoint receives the report.
function coepReportToTest(reportTo, reportOnlyReportTo, expected, description) {
promise_test(async t => {
const endpointKey = token();
const reportOnlyEndpointKey = token();
const reportURL = '/html/cross-origin-embedder-policy/resources/report.py';
const frameURL = `resources/reporting-empty-frame.html` +
`?pipe=header(cross-origin-embedder-policy,require-corp;report-to=${reportTo})` +
`|header(cross-origin-embedder-policy-report-only,require-corp;report-to=${reportOnlyReportTo})` +
`|header(reporting-endpoints, endpoint="${reportURL}?key=${endpointKey}"\\, report-only-endpoint="${reportURL}?key=${reportOnlyEndpointKey}")`;
const iframe = document.createElement('iframe');
t.add_cleanup(() => iframe.remove());
iframe.src = frameURL;
await new Promise(resolve => {
iframe.addEventListener('load', resolve, { once: true });
document.body.appendChild(iframe);
});
// The response comes from cross-origin and doesn't have a CORP header, so
// it is blocked. This also shows that the policy itself is still enforced.
const url = `${REMOTE_ORIGIN}/common/text-plain.txt?${token()}`;
await promise_rejects_js(t, iframe.contentWindow.TypeError,
iframe.contentWindow.fetch(url, { mode: 'no-cors', cache: 'no-store' }));
// Wait for the report to the string report-to endpoint to be uploaded.
// Reports from the same document are uploaded together, so once it
// arrives, so would any report to the other endpoint.
const [stringKey, otherKey] = expected === 'enforce' ?
[endpointKey, reportOnlyEndpointKey] :
[reportOnlyEndpointKey, endpointKey];
let reports = [];
while (reports.length === 0) {
await wait(100);
reports = await fetchCorpReports(stringKey, url);
}
assert_equals(reports.length, 1, 'reports for the string report-to');
assert_equals(reports[0].body.disposition, expected);
await wait(500);
const otherReports = await fetchCorpReports(otherKey, url);
assert_equals(otherReports.length, 0, 'reports for the other report-to');
}, description);
}
coepReportToTest('endpoint', '"report-only-endpoint"', 'reporting',
'Cross-Origin-Embedder-Policy ignores a token report-to');
coepReportToTest('"endpoint"', 'report-only-endpoint', 'enforce',
'Cross-Origin-Embedder-Policy-Report-Only ignores a token report-to');
coepReportToTest(`:${btoa('endpoint')}:`, '"report-only-endpoint"', 'reporting',
'Cross-Origin-Embedder-Policy ignores a byte sequence report-to');
coepReportToTest('"endpoint"', `:${btoa('report-only-endpoint')}:`, 'enforce',
'Cross-Origin-Embedder-Policy-Report-Only ignores a byte sequence report-to');