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:
Sid Stamm 2014-11-18 08:47:26 -05:00
Родитель 97f0aa29c2
Коммит a40721427c
6 изменённых файлов: 375 добавлений и 0 удалений

Просмотреть файл

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