| <!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> |