blob: de93c03ba9ebd7bfc2bd5c51615a94620439f713 [file] [log] [blame]
<!DOCTYPE html>
<title>Service Worker: Tainting of responses fetched via SW.</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/get-host-info.js?pipe=sub"></script>
<script src="resources/test-helpers.js"></script>
<body>
<script>
var host_info = get_host_info();
var BASE_ORIGIN = host_info.HTTP_ORIGIN;
var OTHER_ORIGIN = host_info.HTTP_REMOTE_ORIGIN;
var BASE_URL = BASE_ORIGIN + base_path() +
'resources/fetch-access-control.php?';
var OTHER_BASE_URL = OTHER_ORIGIN + base_path() +
'resources/fetch-access-control.php?';
function frame_fetch(frame, url, mode, credentials) {
return frame.contentWindow.fetch(
new Request(url, {mode: mode, credentials: credentials}));
}
function ng_test(frame, url, mode, credentials) {
return frame_fetch(frame, url, mode, credentials).then(
function() {
throw new Error('fetching url:\"' + url + '\" mode:\"' + mode +
'\" credentials:\"' + credentials + '\" should fail.');
},
function() {});
}
function ok_test(frame, url, mode, credentials, expected_type,
expected_username) {
return frame_fetch(frame, url, mode, credentials)
.then(function(res) {
assert_equals(res.type, expected_type);
return res.text();
})
.then(function(text) {
if (expected_type == 'opaque') {
assert_equals(text, '');
} else {
return new Promise(function(resolve) {
var report = resolve;
// text must contain report() call.
eval(text);
})
.then(function(result) {
assert_equals(result.username, expected_username);
});
}
})
.catch(function(reason) {
throw new Error('fetching url:\"' + url + '\" mode:\"' + mode +
'\" credentials:\"' + credentials + '\" should ' +
'success. - ' + reason.message);
});
}
function build_rewrite_url(origin, url, mode, credentials) {
return origin + '/?url=' + encodeURIComponent(url) + '&mode=' + mode +
'&credentials=' + credentials + '&';
}
function for_each_origin_mode_credentials(callback) {
[BASE_ORIGIN, OTHER_ORIGIN].forEach(function(origin) {
['same-origin', 'no-cors', 'cors'].forEach(function(mode) {
['omit', 'same-origin', 'include'].forEach(function(credentials) {
callback(origin, mode, credentials);
});
});
});
}
promise_test(function(t) {
var SCOPE = 'resources/fetch-response-taint-iframe.html';
var SCRIPT = 'resources/fetch-rewrite-worker.js';
var frame = undefined;
return login(t, host_info.HTTP_ORIGIN, host_info.HTTP_REMOTE_ORIGIN)
.then(function() {
return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
})
.then(function(registration) {
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() { return with_iframe(SCOPE); })
.then(function(f) {
frame = f;
var promises = [
ok_test(f, BASE_URL, 'same-origin', 'omit', 'basic', 'undefined'),
ok_test(f, BASE_URL, 'same-origin', 'same-origin', 'basic',
'username1'),
ok_test(f, BASE_URL, 'same-origin', 'include', 'basic',
'username1'),
ok_test(f, BASE_URL, 'no-cors', 'omit', 'basic', 'undefined'),
ok_test(f, BASE_URL, 'no-cors', 'same-origin', 'basic',
'username1'),
ok_test(f, BASE_URL, 'no-cors', 'include', 'basic', 'username1'),
ok_test(f, BASE_URL, 'cors', 'omit', 'basic', 'undefined'),
ok_test(f, BASE_URL, 'cors', 'same-origin', 'basic', 'username1'),
ok_test(f, BASE_URL, 'cors', 'include', 'basic', 'username1'),
ng_test(f, OTHER_BASE_URL, 'same-origin', 'omit'),
ng_test(f, OTHER_BASE_URL, 'same-origin', 'same-origin'),
ng_test(f, OTHER_BASE_URL, 'same-origin', 'include'),
ok_test(f, OTHER_BASE_URL, 'no-cors', 'omit', 'opaque'),
ok_test(f, OTHER_BASE_URL, 'no-cors', 'same-origin', 'opaque'),
ok_test(f, OTHER_BASE_URL, 'no-cors', 'include', 'opaque'),
ng_test(f, OTHER_BASE_URL, 'cors', 'omit'),
ng_test(f, OTHER_BASE_URL, 'cors', 'same-origin'),
ng_test(f, OTHER_BASE_URL, 'cors', 'include'),
ok_test(f, OTHER_BASE_URL + 'ACAOrigin=*', 'cors', 'omit', 'cors',
'undefined'),
ok_test(f, OTHER_BASE_URL + 'ACAOrigin=*', 'cors', 'same-origin',
'cors', 'undefined'),
ng_test(f, OTHER_BASE_URL + 'ACAOrigin=*', 'cors', 'include'),
ok_test(f,
OTHER_BASE_URL + 'ACAOrigin=' + BASE_ORIGIN +
'&ACACredentials=true',
'cors', 'include', 'cors', 'username2')
];
for_each_origin_mode_credentials(function(origin, mode, credentials) {
var url = build_rewrite_url(
origin, BASE_URL, 'same-origin', 'omit');
// Fetch to the other origin with same-origin mode should fail.
if (origin == OTHER_ORIGIN && mode == 'same-origin')
return promises.push(ng_test(f, url, mode, credentials));
// The response type from the SW should be basic
promises.push(
ok_test(f, url, mode, credentials, 'basic', 'undefined'));
});
for_each_origin_mode_credentials(function(origin, mode, credentials) {
var url = build_rewrite_url(
origin, BASE_URL, 'same-origin', 'same-origin');
// Fetch to the other origin with same-origin mode should fail.
if (origin == OTHER_ORIGIN && mode == 'same-origin')
return promises.push(ng_test(f, url, mode, credentials));
// The response type from the SW should be basic.
promises.push(
ok_test(f, url, mode, credentials, 'basic', 'username1'));
});
for_each_origin_mode_credentials(function(origin, mode, credentials) {
var url = build_rewrite_url(
origin, OTHER_BASE_URL, 'same-origin', 'omit');
// The response from the SW should be an error.
promises.push(ng_test(f, url, mode, credentials));
});
for_each_origin_mode_credentials(function(origin, mode, credentials) {
var url = build_rewrite_url(
origin, OTHER_BASE_URL, 'no-cors', 'omit');
// SW can respond only to no-cors requests.
if (mode != 'no-cors')
return promises.push(ng_test(f, url, mode, credentials));
// The response type from the SW should be opaque.
promises.push(ok_test(f, url, mode, credentials, 'opaque'));
});
for_each_origin_mode_credentials(function(origin, mode, credentials) {
var url = build_rewrite_url(
origin, OTHER_BASE_URL + 'ACAOrigin=*', 'cors', 'omit');
// Fetch to the other origin with same-origin mode should fail.
if (origin == OTHER_ORIGIN && mode == 'same-origin')
return promises.push(ng_test(f, url, mode, credentials));
// The response from the SW should be cors.
promises.push(
ok_test(f, url, mode, credentials, 'cors', 'undefined'));
});
for_each_origin_mode_credentials(function(origin, mode, credentials) {
var url = build_rewrite_url(
origin,
OTHER_BASE_URL + 'ACAOrigin=' + BASE_ORIGIN +
'&ACACredentials=true',
'cors', 'include');
// Fetch to the other origin with same-origin mode should fail.
if (origin == OTHER_ORIGIN && mode == 'same-origin')
return promises.push(ng_test(f, url, mode, credentials));
// The response from the SW should be cors.
promises.push(
ok_test(f, url, mode, credentials, 'cors', 'username2'));
});
return Promise.all(promises);
})
.then(function(f) {
frame.remove()
})
.catch(unreached_rejection(t));
}, 'Verify the tainting of responses fetched via SW');
</script>
</body>