1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
<!DOCTYPE html>
<title>ServiceWorker FetchEvent issued from workers in an iframe sandboxed via CSP HTTP response header.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
let lastCallbackId = 0;
let callbacks = {};
function doTest(frame, type) {
return new Promise(function(resolve) {
var id = ++lastCallbackId;
callbacks[id] = resolve;
frame.contentWindow.postMessage({id: id, type: type}, '*');
});
}
// Asks the service worker for data about requests and clients seen. The
// worker posts a message back with |data| where:
// |data.requests|: the requests the worker received FetchEvents for
// |data.clients|: the URLs of all the worker's clients
// The worker clears its data after responding.
function getResultsFromWorker(worker) {
return new Promise(resolve => {
let channel = new MessageChannel();
channel.port1.onmessage = msg => {
resolve(msg.data);
};
worker.postMessage({port: channel.port2}, [channel.port2]);
});
}
window.onmessage = function (e) {
message = e.data;
let id = message['id'];
let callback = callbacks[id];
delete callbacks[id];
callback(message['result']);
};
const SCOPE = 'resources/sandboxed-iframe-fetch-event-iframe.py';
const SCRIPT = 'resources/sandboxed-iframe-fetch-event-worker.js';
const expected_base_url = new URL(SCOPE, location.href);
// A service worker controlling |SCOPE|.
let worker;
// An iframe whose response header has
// 'Content-Security-Policy: allow-scripts'.
// This should NOT be controlled by a service worker.
let sandboxed_frame_by_header;
// An iframe whose response header has
// 'Content-Security-Policy: allow-scripts allow-same-origin'.
// This should be controlled by a service worker.
let sandboxed_same_origin_frame_by_header;
promise_test(t => {
return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
.then(function(registration) {
add_completion_callback(() => registration.unregister());
worker = registration.installing;
return wait_for_state(t, registration.installing, 'activated');
});
}, 'Prepare a service worker.');
promise_test(t => {
const iframe_full_url = expected_base_url + '?sandbox=allow-scripts&' +
'sandboxed-frame-by-header';
return with_iframe(iframe_full_url)
.then(f => {
sandboxed_frame_by_header = f;
add_completion_callback(() => f.remove());
return getResultsFromWorker(worker);
})
.then(data => {
let requests = data.requests;
assert_equals(requests.length, 1,
'Service worker should provide the response');
assert_equals(requests[0], iframe_full_url);
assert_false(data.clients.includes(iframe_full_url),
'Service worker should NOT control the sandboxed page');
});
}, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts.');
promise_test(t => {
const iframe_full_url =
expected_base_url + '?sandbox=allow-scripts%20allow-same-origin&' +
'sandboxed-iframe-same-origin-by-header';
return with_iframe(iframe_full_url)
.then(f => {
sandboxed_same_origin_frame_by_header = f;
add_completion_callback(() => f.remove());
return getResultsFromWorker(worker);
})
.then(data => {
let requests = data.requests;
assert_equals(requests.length, 1);
assert_equals(requests[0], iframe_full_url);
assert_true(data.clients.includes(iframe_full_url));
})
}, 'Prepare an iframe sandboxed by CSP HTTP header with allow-scripts and ' +
'allow-same-origin.');
promise_test(t => {
let frame = sandboxed_frame_by_header;
return doTest(frame, 'fetch-from-worker')
.then(result => {
assert_equals(result, 'done');
return getResultsFromWorker(worker);
})
.then(data => {
assert_equals(data.requests.length, 0,
'The request should NOT be handled by SW.');
});
}, 'Fetch request from a worker in iframe sandboxed by CSP HTTP header ' +
'allow-scripts flag');
promise_test(t => {
let frame = sandboxed_same_origin_frame_by_header;
return doTest(frame, 'fetch-from-worker')
.then(result => {
assert_equals(result, 'done');
return getResultsFromWorker(worker);
})
.then(data => {
let requests = data.requests;
assert_equals(requests.length, 1,
'The request should be handled by SW.');
assert_equals(requests[0], frame.src + '&test=fetch-from-worker');
});
}, 'Fetch request from a worker in iframe sandboxed by CSP HTTP header ' +
'with allow-scripts and allow-same-origin flag');
</script>
</body>
|