summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html
blob: c8480bf1be003903383404fa90ff28af668f6533 (plain)
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>