зеркало из https://github.com/mozilla/gecko-dev.git
Bug 704320 - Add tests for whether preloaded resources can be reused after script-added meta referrer policy is added to a document. (r=bz)
This commit is contained in:
Родитель
97f0aa29c2
Коммит
a40721427c
|
@ -0,0 +1,94 @@
|
|||
// Handle counting loads for bug 704320.
|
||||
|
||||
const SHARED_KEY="bug704320_counter";
|
||||
const DEFAULT_STATE = {'css': {'count': 0, 'referrers': []},
|
||||
'img': {'count': 0, 'referrers': []},
|
||||
'js': {'count': 0, 'referrers': []}};
|
||||
const TYPE_MAP = {'css': 'text/css',
|
||||
'js': 'application/javascript',
|
||||
'img': 'image/png',
|
||||
'html': 'text/html'};
|
||||
|
||||
// Writes an image to the response
|
||||
function WriteOutImage(response)
|
||||
{
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties)
|
||||
.get("CurWorkD", Components.interfaces.nsIFile);
|
||||
|
||||
file.append("tests");
|
||||
file.append("image");
|
||||
file.append("test");
|
||||
file.append("mochitest");
|
||||
file.append('blue.png');
|
||||
|
||||
var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
|
||||
.createInstance(Components.interfaces.nsIFileInputStream);
|
||||
fileStream.init(file, 1, 0, false);
|
||||
response.bodyOutputStream.writeFrom(fileStream, fileStream.available());
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
var referrerLevel = "none";
|
||||
if (request.hasHeader('Referer')) {
|
||||
let referrer = request.getHeader('Referer');
|
||||
if (referrer.indexOf("bug704320_preload") > 0) {
|
||||
referrerLevel = "full";
|
||||
} else if (referrer == "http://mochi.test:8888") {
|
||||
referrerLevel = "origin";
|
||||
}
|
||||
}
|
||||
|
||||
var state = getSharedState(SHARED_KEY);
|
||||
if (state === '') {
|
||||
state = DEFAULT_STATE;
|
||||
} else {
|
||||
state = JSON.parse(state);
|
||||
}
|
||||
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
|
||||
|
||||
//avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
if ("reset" in query) {
|
||||
//reset server state
|
||||
setSharedState(SHARED_KEY, JSON.stringify(DEFAULT_STATE));
|
||||
//serve any CSS that we want to use.
|
||||
response.write("");
|
||||
return;
|
||||
}
|
||||
|
||||
if ("results" in query) {
|
||||
response.setHeader("Content-Type", "text/javascript", false);
|
||||
response.write(JSON.stringify(state));
|
||||
return;
|
||||
}
|
||||
|
||||
if ('type' in query) {
|
||||
state[query.type].count++;
|
||||
response.setHeader("Content-Type", TYPE_MAP[query.type], false);
|
||||
if (state[query.type].referrers.indexOf(referrerLevel) < 0) {
|
||||
state[query.type].referrers.push(referrerLevel);
|
||||
}
|
||||
|
||||
if (query.type == 'img') {
|
||||
WriteOutImage(response);
|
||||
}
|
||||
}
|
||||
|
||||
if ('content' in query) {
|
||||
response.write(unescape(query['content']));
|
||||
}
|
||||
|
||||
setSharedState(SHARED_KEY, JSON.stringify(state));
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Common code for the iframes used by bug704320_preload.
|
||||
|
||||
var loadCount = 0;
|
||||
|
||||
// Called by the various onload handlers to indicate that a resource has
|
||||
// been fully loaded. We require three loads to complete (img, script,
|
||||
// link) for this test.
|
||||
function incrementLoad(tag) {
|
||||
loadCount++;
|
||||
if (loadCount == 3) {
|
||||
window.parent.postMessage("childLoadComplete", window.location.origin);
|
||||
} else if (loadCount > 3) {
|
||||
document.write("<h1>Too Many Load Events!</h1>");
|
||||
window.parent.postMessage("childOverload", window.location.origin);
|
||||
}
|
||||
}
|
||||
|
||||
// in case something fails to load, cause the test to fail.
|
||||
function postfail(msg) {
|
||||
window.parent.postMessage("fail-" + msg, window.location.origin);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript" src="file_bug704320_preload_common.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
// mess with parser speculation's choice of referrer policy
|
||||
document.write("<meta name='referrer' content='origin'>");
|
||||
</script>
|
||||
|
||||
<!-- preload happens with full referrer, but real load should happen with origin -->
|
||||
<script src="/tests/dom/base/test/bug704320_counter.sjs?type=js"
|
||||
onload="incrementLoad('script');"></script>
|
||||
|
||||
<!-- preload happens with full referrer, but real load should happen with origin -->
|
||||
<link rel="stylesheet"
|
||||
href="/tests/dom/base/test/bug704320_counter.sjs?type=css"
|
||||
onload="incrementLoad('link');"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- preload happens with full referrer, but real load should happen with origin -->
|
||||
<img src="/tests/dom/base/test/bug704320_counter.sjs?type=img"
|
||||
onload="incrementLoad('img');"
|
||||
onerror="postfail('image load caused an error in noreuse test');"/>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="referrer" content="origin">
|
||||
<script type="text/javascript" src="file_bug704320_preload_common.js"></script>
|
||||
<script language="javascript" type="text/javascript">
|
||||
// mess with parser speculation -- the loads here MAY be reused because the
|
||||
// referrer policy did not change.
|
||||
document.write("<meta name='referrer' content='origin'>");
|
||||
</script>
|
||||
|
||||
<script src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=js"
|
||||
onload="incrementLoad('script');"></script>
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=css"
|
||||
onload="incrementLoad('link');"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img"
|
||||
onload="incrementLoad('img');"
|
||||
onerror="postfail('image load caused an error in reuse test');"/>
|
||||
</body>
|
||||
</html>
|
|
@ -53,6 +53,7 @@ support-files =
|
|||
bug696301-script-1.js^headers^
|
||||
bug696301-script-2.js
|
||||
bug704320.sjs
|
||||
bug704320_counter.sjs
|
||||
bug819051.sjs
|
||||
copypaste.js
|
||||
delayedServerEvents.sjs
|
||||
|
@ -139,6 +140,9 @@ support-files =
|
|||
file_bug687859-http.js^headers^
|
||||
file_bug687859-inherit.js
|
||||
file_bug692434.xml
|
||||
file_bug704320_preload_common.js
|
||||
file_bug704320_preload_reuse.html
|
||||
file_bug704320_preload_noreuse.html
|
||||
file_bug704320_redirect.html
|
||||
file_bug707142_baseline.json
|
||||
file_bug707142_bom.json
|
||||
|
@ -597,6 +601,7 @@ skip-if = buildapp == 'b2g'
|
|||
[test_bug704063.html]
|
||||
[test_bug704320.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g (Needs multiple window.open support) android(times out, bug 1100609) e10s(randomly fails, bug 1100362)
|
||||
[test_bug704320_preload.html]
|
||||
[test_bug707142.html]
|
||||
[test_bug708620.html]
|
||||
[test_bug711047.html]
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test preloads for Bug 704320</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var advance = function() { tests.next(); };
|
||||
|
||||
/**
|
||||
* Listen for notifications from the child.
|
||||
* These are sent in case of error, or when the loads we await have completed.
|
||||
*/
|
||||
window.addEventListener("message", function(event) {
|
||||
if (event.data == "childLoadComplete") {
|
||||
// all three loads happen, continue the test.
|
||||
advance();
|
||||
} else if (event.data == "childOverload") {
|
||||
// too many loads happened in a test frame, abort.
|
||||
ok(false, "Too many load handlers called in test.");
|
||||
SimpleTest.finish();
|
||||
} else if (event.data.indexOf("fail-") == 0) {
|
||||
// something else failed in the test frame, abort.
|
||||
ok(false, "Child failed the test with error " + event.data.substr(5));
|
||||
SimpleTest.finish();
|
||||
}});
|
||||
|
||||
/**
|
||||
* This is the main test routine -- serialized by use of a generator.
|
||||
* It resets the counter, then performs two tests in sequence using
|
||||
* the same iframe.
|
||||
*/
|
||||
var tests = (function() {
|
||||
var iframe = document.getElementById("testframe");
|
||||
|
||||
// reset the counter
|
||||
yield resetCounter();
|
||||
|
||||
// load the first test frame
|
||||
// it will call back into this function via postMessage when it finishes loading.
|
||||
// and continue beyond the yield.
|
||||
yield iframe.src = 'file_bug704320_preload_noreuse.html';
|
||||
|
||||
// check the first test
|
||||
yield checkResults(finalizePreloadNoreuse);
|
||||
|
||||
// reset the counter
|
||||
yield resetCounter();
|
||||
|
||||
// load the second test frame
|
||||
// it will call back into this function via postMessage when it finishes loading.
|
||||
// and continue beyond the yield.
|
||||
yield iframe.src = 'file_bug704320_preload_reuse.html';
|
||||
|
||||
// check the second test
|
||||
yield checkResults(finalizePreloadReuse);
|
||||
|
||||
// complete. Be sure to yield so we don't call this twice.
|
||||
yield SimpleTest.finish();
|
||||
})();
|
||||
|
||||
// Helper functions below.
|
||||
|
||||
/**
|
||||
* This checks the first test: a test where the preloads should not
|
||||
* be reused. * we expect two requests for each image, script, js request
|
||||
* since the referrer policy changed after speculative loads were started.
|
||||
* Problem is that the "origin"/revised loads won't necessarily happen,
|
||||
* so we test for one or two loads (both are OK) and make the 'origin'
|
||||
* referrer optional.
|
||||
*/
|
||||
function finalizePreloadNoreuse(results) {
|
||||
console.log("<br/><pre>" + JSON.stringify(results) + "</pre>");
|
||||
var expected = {'css': {'count': 2, 'referrers': ['full', 'origin']},
|
||||
'img': {'count': 2, 'referrers': ['full', 'origin']},
|
||||
'js': {'count': 2, 'referrers': ['full', 'origin']}};
|
||||
|
||||
for (var x in expected) {
|
||||
ok(x in results, "some " + x + " loads required in results object.");
|
||||
|
||||
ok(results[x].count == 1 || results[x].count == 2,
|
||||
"Expected 1-2 loads for " + x + " requests.");
|
||||
|
||||
// the 'full' preload is optional, but required if count > 1
|
||||
if (results[x].count > 1) {
|
||||
ok(results[x].referrers.indexOf('full') >= 0,
|
||||
"More than one load for " + x + ", so expected an 'full' referrer preload.")
|
||||
}
|
||||
|
||||
// 'origin' (final load) is required
|
||||
ok(results[x].referrers.indexOf('origin') >= 0,
|
||||
"One load for " + x + " should have had 'origin' referrer.");
|
||||
|
||||
// no other values should be in the referrers.
|
||||
is(results[x].referrers.indexOf('none'), -1,
|
||||
"No loads for " + x + " should have a missing referrer.");
|
||||
}
|
||||
|
||||
advance();
|
||||
}
|
||||
|
||||
/**
|
||||
* This checks the second test: a test where preloads SHOULD be reused.
|
||||
* We expect one request for each image, script, js request since
|
||||
* the referrer policy does not change after speculative loads.
|
||||
*/
|
||||
function finalizePreloadReuse(results) {
|
||||
var expected = {'css': {'count': 1, 'referrers': ['origin']},
|
||||
'img': {'count': 1, 'referrers': ['origin']},
|
||||
'js': {'count': 1, 'referrers': ['origin']}};
|
||||
|
||||
for (var x in expected) {
|
||||
ok(x in results, "some " + x + " loads required in results object.");
|
||||
|
||||
is(results[x].count, expected[x].count,
|
||||
"Expected " + expected[x].count + " loads for " + x + " requests.");
|
||||
|
||||
// 'origin' is required
|
||||
ok(results[x].referrers.indexOf('origin') >= 0,
|
||||
"One load for " + x + " should have had 'origin' referrer.");
|
||||
|
||||
// no other values should be in the referrers.
|
||||
is(results[x].referrers.indexOf('none'), -1,
|
||||
"No loads for " + x + " should have a missing referrer.");
|
||||
is(results[x].referrers.indexOf('full'), -1,
|
||||
"No loads for " + x + " should have an 'full' referrer.")
|
||||
}
|
||||
|
||||
advance();
|
||||
}
|
||||
|
||||
/**
|
||||
* helper to perform an XHR.
|
||||
* Used by resetCounter() and checkResults().
|
||||
*/
|
||||
function doXHR(url, onSuccess, onFail) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onload = function () {
|
||||
if (xhr.status == 200) {
|
||||
onSuccess(xhr);
|
||||
} else {
|
||||
onFail(xhr);
|
||||
}
|
||||
};
|
||||
xhr.open('GET', url, true);
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This triggers state-resetting on the counter server.
|
||||
*/
|
||||
function resetCounter() {
|
||||
doXHR('/tests/dom/base/test/bug704320_counter.sjs?reset',
|
||||
advance,
|
||||
function(xhr) {
|
||||
ok(false, "Need to be able to reset the request counter");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the results via XHR and passes to checker.
|
||||
*/
|
||||
function checkResults(checker) {
|
||||
doXHR('/tests/dom/base/test/bug704320_counter.sjs?results',
|
||||
function(xhr) {
|
||||
checker(JSON.parse(xhr.responseText));
|
||||
},
|
||||
function(xhr) {
|
||||
ok(false, "Can't get results from the counter server.");
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="tests.next();">
|
||||
<iframe id="testframe"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче