Skip to content

Commit

Permalink
Do not dispatch an opaque response for a mode: "cors" request
Browse files Browse the repository at this point in the history
When a service worker is involved, it's possible to get an opaque
filtered response for a mode: "cors" request. We peviously
checked it in ResourceFetcher but it's insufficient when the resource is
shared before the response arrives.

This CL instead make a CORS error when we see such response in
DocumentThreadableLoader.

Bug: 731669, 625575
Change-Id: I65334dbe21c0e2e8aaedd6d5dd5fae762c7cb72c
Reviewed-on: https://chromium-review.googlesource.com/527768
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: Hiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: Takeshi Yoshino <tyoshino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#481863}
WPT-Export-Revision: 6d70c3eabfdab9acd9a84e1f94bdf78783bef459
  • Loading branch information
yutakahirano authored and chromium-wpt-export-bot committed Jun 23, 2017
1 parent cb34f0c commit e8cbae9
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 13 deletions.
3 changes: 2 additions & 1 deletion lint.whitelist
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ SET TIMEOUT: service-workers/service-worker/update-recovery.https.html
SET TIMEOUT: service-workers/service-worker/resources/extendable-event-async-waituntil.js
SET TIMEOUT: service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js
SET TIMEOUT: service-workers/service-worker/resources/fetch-event-test-worker.js
SET TIMEOUT: service-workers/service-worker/resources/opaque-response-preloaded-iframe.html
SET TIMEOUT: service-workers/service-worker/resources/opaque-response-being-preloaded-xhr.html
SET TIMEOUT: service-workers/service-worker/resources/opaque-response-preloaded-xhr.html
SET TIMEOUT: service-workers/service-worker/resources/performance-timeline-worker.js
SET TIMEOUT: service-workers/service-worker/resources/register-foreign-fetch-errors-worker.js
SET TIMEOUT: shadow-dom/Document-prototype-currentScript.html
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,44 @@
<script>
const WORKER =
'resources/opaque-response-preloaded-worker.js';
const SCOPE =
'resources/opaque-response-preloaded-iframe.html';
var resolve_done;
var done_was_called = new Promise(resolve => resolve_done = resolve);
// Called by the iframe when done.
function done(result) { resolve_done(result); }

// This tests that the browser does not inappropriately use a cached opaque
var done;

// These test that the browser does not inappropriately use a cached opaque
// response for a request that is not no-cors. The test opens a controlled
// iframe that uses link rel=preload to issue a same-origin no-cors request.
// The service worker responds to the request with an opaque response. Then the
// iframe does an XHR (not no-cors) to that URL again. The request should fail.
promise_test(t => {
const SCOPE =
'resources/opaque-response-being-preloaded-xhr.html';
const promise = new Promise(resolve => done = resolve);

return service_worker_unregister_and_register(t, WORKER, SCOPE)
.then(reg => {
add_completion_callback(() => reg.unregister());
return wait_for_state(t, reg.installing, 'activated');
})
.then(() => with_iframe(SCOPE))
.then(frame => t.add_cleanup(() => frame.remove() ))
.then(() => promise)
.then(result => assert_equals(result, 'PASS'));
}, 'Opaque responses should not be reused for XHRs, loading case');

promise_test(t => {
const SCOPE =
'resources/opaque-response-preloaded-xhr.html';
const promise = new Promise(resolve => done = resolve);

return service_worker_unregister_and_register(t, WORKER, SCOPE)
.then(reg => {
add_completion_callback(() => reg.unregister());
return wait_for_state(t, reg.installing, 'activated');
})
.then(() => with_iframe(SCOPE))
.then(frame => t.add_cleanup(() => frame.remove() ))
.then(() => done_was_called)
.then(() => promise)
.then(result => assert_equals(result, 'PASS'));
}, 'Opaque responses should not be reused for XHRs');
}, 'Opaque responses should not be reused for XHRs, done case');

</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<meta charset="utf-8">
<body></body>
<script>
const URL = 'opaque-response?from=opaque-response-being-preloaded-xhr.html';
function runTest() {
var l = document.createElement('link');
// Use link rel=preload to try to get the browser to cache the opaque
// response.
l.setAttribute('rel', 'preload');
l.setAttribute('href', URL);
l.setAttribute('as', 'fetch');
l.onerror = function() {
parent.done('FAIL: preload failed unexpectedly');
};
document.body.appendChild(l);
xhr = new XMLHttpRequest;
xhr.withCredentials = true;
xhr.open('GET', URL);
// opaque-response returns an opaque response from serviceworker and thus
// the XHR must fail because it is not no-cors request.
// Particularly, the XHR must not reuse the opaque response from the
// preload request.
xhr.onerror = function() {
parent.done('PASS');
};
xhr.onload = function() {
parent.done('FAIL: ' + xhr.responseText);
};
xhr.send();
}
</script>
<body onload="setTimeout(runTest, 100)"></body>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var remoteUrl = get_host_info()['HTTPS_REMOTE_ORIGIN'] +
'/service-workers/service-worker/resources/simple.txt'

self.addEventListener('fetch', event => {
if (!event.request.url.match(/opaque-response$/)) {
if (!event.request.url.match(/opaque-response\?from=/)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
<meta charset="utf-8">
<body></body>
<script>
const URL = 'opaque-response?from=opaque-response-preloaded-xhr.html';
function runTest() {
var l = document.createElement('link');
// Use link rel=preload to try to get the browser to cache the opaque
// response.
l.setAttribute('rel', 'preload');
l.setAttribute('href', 'opaque-response');
l.setAttribute('href', URL);
l.setAttribute('as', 'fetch');
l.onload = function() {
xhr = new XMLHttpRequest;
xhr.withCredentials = true;
xhr.open('GET', 'opaque-response');
xhr.open('GET', URL);
// opaque-response returns an opaque response from serviceworker and thus
// the XHR must fail because it is not no-cors request.
// Particularly, the XHR must not reuse the opaque response from the
Expand Down

0 comments on commit e8cbae9

Please sign in to comment.