Bug 1174915 - Allow changing meta referrer policy on the fly, tests (r=sstamm)
authorFranziskus Kiefer <franziskuskiefer@gmail.com>
Mon, 29 Jun 2015 11:05:05 -0700
changeset 294860 4f506110d1af514bee46fddcaeae9c63153985c1
parent 294859 c02f4d8cbb0563ad2e930cb68f9452bd0fe0b1a5
child 294861 4496829ff993e1ff864b930eac75e88a6fa64ea8
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssstamm
bugs1174915
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1174915 - Allow changing meta referrer policy on the fly, tests (r=sstamm)
dom/base/test/file_change_policy_redirect.html
dom/base/test/mochitest.ini
dom/base/test/referrer_change_server.sjs
dom/base/test/test_change_policy.html
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_change_policy_redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script>
+    parent.postMessage('childLoadComplete', 'http://mochi.test:8888');
+  </script>
+</head>
+<body>
+</body>
+</html>
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -249,16 +249,18 @@ support-files =
   referrer_helper.js
   referrer_testserver.sjs
   script_postmessages_fileList.js
   iframe_postMessages.html
   test_performance_observer.js
   performance_observer.html
   test_anonymousContent_style_csp.html^headers^
   file_explicit_user_agent.sjs
+  referrer_change_server.sjs
+  file_change_policy_redirect.html
 
 [test_anonymousContent_api.html]
 [test_anonymousContent_append_after_reflow.html]
 [test_anonymousContent_insert.html]
 [test_anonymousContent_manipulate_content.html]
 [test_anonymousContent_style_csp.html]
 [test_applet_alternate_content.html]
 [test_appname_override.html]
@@ -840,8 +842,10 @@ skip-if = buildapp == 'mulet' || buildap
 [test_window_element_enumeration.html]
 [test_referrer_redirect.html]
 [test_postMessages.html]
 support-files = worker_postMessages.js
 [test_window_proto.html]
 [test_frameLoader_switchProcess.html]
 skip-if = e10s || os != 'linux' || buildapp != 'browser'
 [test_explicit_user_agent.html]
+[test_change_policy.html]
+skip-if = buildapp == 'b2g' #no ssl support
new file mode 100644
--- /dev/null
+++ b/dom/base/test/referrer_change_server.sjs
@@ -0,0 +1,139 @@
+var BASE_URL = 'example.com/tests/dom/base/test/referrer_change_server.sjs';
+
+function createTestUrl(aPolicy, aAction, aName) {
+  return 'http://' + BASE_URL + '?' +
+         'action=' + aAction + '&' +
+         'policy=' + aPolicy + '&' +
+         'name=' + aName + '&' +
+         'type=link';
+}
+
+function createTest(aMetaPolicy, aReferrerPolicy, aName) {
+  return '<!DOCTYPE HTML>\n\
+         <html>'+
+           '<meta name="referrer" content="' + aMetaPolicy + '">' +
+           '<body>' +
+             '<a href="' + createTestUrl(aReferrerPolicy, 'test', aName + aReferrerPolicy) + '" id="link">' + aReferrerPolicy + '</a>' +
+             '<script>' +
+
+               // LOAD EVENT (of the test)
+               // fires when the page is loaded, then click link
+               // first change meta referrer, then click link
+               'window.addEventListener("load", function() {\n\
+                 document.getElementsByName("referrer")[0].content = "'+aReferrerPolicy+'";\n\
+                 document.getElementById("link").click();\n\
+               }.bind(window), false);' +
+
+             '</script>\n\
+           </body>\n\
+         </html>';
+}
+
+function createTest2(aMetaPolicy, aReferrerPolicy, aName) {
+  return '<!DOCTYPE HTML>\n\
+         <html>'+
+           '<meta name="referrer" content="' + aMetaPolicy + '">' +
+           '<body>' +
+             '<a href="' + createTestUrl(aReferrerPolicy, 'test', aName + aReferrerPolicy) + '" id="link">' + aReferrerPolicy + '</a>' +
+             '<script>' +
+
+               // LOAD EVENT (of the test)
+               // fires when the page is loaded, then click link
+               // first change meta referrer, then click link
+               'window.addEventListener("load", function() {\n\
+                 document.getElementsByName("referrer")[0].setAttribute("content", "'+aReferrerPolicy+'");\n\
+                 document.getElementById("link").click();\n\
+               }.bind(window), false);' +
+
+             '</script>\n\
+           </body>\n\
+         </html>';
+}
+
+function handleRequest(request, response) {
+  var sharedKey = 'referrer_change_server.sjs';
+  var params = request.queryString.split('&');
+  var action = params[0].split('=')[1];
+
+  if (action === 'resetState') {
+    var state = getSharedState(sharedKey);
+    state = {};
+    setSharedState(sharedKey, JSON.stringify(state));
+    response.write("");
+    return;
+  } else if (action === 'test') {
+    // ?action=test&policy=origin&name=name
+    var policy = params[1].split('=')[1];
+    var name = params[2].split('=')[1];
+    var type = params[3].split('=')[1];
+    var result = getSharedState(sharedKey);
+
+    if (result === '') {
+      result = {};
+    } else {
+      result = JSON.parse(result);
+    }
+
+    if (!result["tests"]) {
+      result["tests"] = {};
+    }
+
+    var referrerLevel = "none";
+    var test = {}
+    if (request.hasHeader('Referer')) {
+        let referrer = request.getHeader('Referer');
+        if (referrer.indexOf("referrer_change_server") > 0) {
+          referrerLevel = "full";
+        } else if (referrer == "http://mochi.test:8888") {
+          referrerLevel = "origin";
+        }
+      test.referrer = request.getHeader('Referer');
+    } else {
+      test.referrer = '';
+    }
+    test.policy = referrerLevel;
+    test.expected = policy;
+
+    result["tests"][name] = test;
+
+    setSharedState(sharedKey, JSON.stringify(result));
+
+    // forward link click to redirect URL to finish test
+    if (type === 'link') {
+      var loc = 'https://example.com/tests/dom/base/test/file_change_policy_redirect.html';
+      response.setStatusLine('1.1', 302, 'Found');
+      response.setHeader('Location', loc, false);
+    }
+
+    return;
+  } else if (action === 'get-test-results') {
+    // ?action=get-result
+    response.setHeader('Cache-Control', 'no-cache', false);
+    response.setHeader('Content-Type', 'text/plain', false);
+    response.write(getSharedState(sharedKey));
+    return;
+  } else if (action === 'generate-policy-test') {
+    // ?action=generate-policy-test&referrerPolicy=b64-encoded-string&name=name&newPolicy=b64-encoded-string
+    response.setHeader('Cache-Control', 'no-cache', false);
+    response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
+    var referrerPolicy = unescape(params[1].split('=')[1]);
+    var name = unescape(params[2].split('=')[1]);
+    var newPolicy = params[3].split('=')[1];
+
+    response.write(createTest(referrerPolicy, newPolicy, name));
+    return;
+  } else if (action === 'generate-policy-test2') {
+    // ?action=generate-policy-test2&referrerPolicy=b64-encoded-string&name=name&newPolicy=b64-encoded-string
+    response.setHeader('Cache-Control', 'no-cache', false);
+    response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
+    var referrerPolicy = unescape(params[1].split('=')[1]);
+    var name = unescape(params[2].split('=')[1]);
+    var newPolicy = params[3].split('=')[1];
+
+    response.write(createTest2(referrerPolicy, newPolicy, name));
+    return;
+  } else {
+    response.write("I don't know action "+action);
+    return;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_change_policy.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test policies for Bug 1101288</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+<!--
+This checks if the right policies are applied from a given string when the policy is changed after the document has been loaded.
+https://bugzilla.mozilla.org/show_bug.cgi?id=1101288
+-->
+<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 loads happen, continue the test.
+    advance();
+  }
+});
+
+/**
+ * helper to perform an XHR.
+ */
+function doXHR(aUrl, onSuccess, onFail) {
+  var xhr = new XMLHttpRequest();
+  xhr.responseType = "json";
+  xhr.onload = function () {
+    onSuccess(xhr);
+  };
+  xhr.onerror = function () {
+    onFail(xhr);
+  };
+  xhr.open('GET', aUrl, true);
+  xhr.send(null);
+}
+
+/**
+ * Grabs the results via XHR and passes to checker.
+ */
+function checkIndividualResults(aTestname, aExpectedReferrer, aName) {
+  doXHR('/tests/dom/base/test/referrer_change_server.sjs?action=get-test-results',
+        function(xhr) {
+          var results = xhr.response;
+          info(JSON.stringify(xhr.response));
+
+          for (i in aName) {
+            ok(aName[i] in results.tests, aName[i] + " tests have to be performed.");
+            is(results.tests[aName[i]].policy, aExpectedReferrer[i], aTestname + ' --- ' + results.tests[aName[i]].policy + ' (' + results.tests[aName[i]].referrer + ')');
+          }
+          advance();
+        },
+        function(xhr) {
+          ok(false, "Can't get results from the counter server.");
+          SimpleTest.finish();
+        });
+}
+
+function resetState() {
+  doXHR('/tests/dom/base/test/referrer_change_server.sjs?action=resetState',
+    advance,
+    function(xhr) {
+      ok(false, "error in reset state");
+      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");
+  var sjs = "/tests/dom/base/test/referrer_change_server.sjs?action=generate-policy-test";
+
+  yield resetState();
+  var name = "no-referrer-unsafe-url";
+  yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name + "&newPolicy=" + escape('unsafe-url');
+  yield checkIndividualResults("unsafe-url (changed) with no-referrer first", ["full"], [name+'unsafe-url']);
+
+  yield resetState();
+  var name = "origin-no-referrer";
+  yield iframe.src = sjs + "&policy=" + escape('origin') + "&name=" + name + "&newPolicy=" + escape('no-referrer');
+  yield checkIndividualResults("no-referrer (changed) with origin first", ["none"], [name+'no-referrer']);
+
+  yield resetState();
+  var name = "unsafe-url-no-referrer";
+  yield iframe.src = sjs + "&policy=" + escape('unsafe-url') + "&name=" + name + "&newPolicy=" + escape('no-referrer');
+  yield checkIndividualResults("no-referrer (changed) with unsafe-url first", ["none"], [name+'no-referrer']);
+
+  sjs = "/tests/dom/base/test/referrer_change_server.sjs?action=generate-policy-test2";
+
+  yield resetState();
+  var name = "no-referrer-unsafe-url";
+  yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name + "&newPolicy=" + escape('unsafe-url');
+  yield checkIndividualResults("unsafe-url (changed) with no-referrer first", ["full"], [name+'unsafe-url']);
+
+  yield resetState();
+  var name = "origin-no-referrer";
+  yield iframe.src = sjs + "&policy=" + escape('origin') + "&name=" + name + "&newPolicy=" + escape('no-referrer');
+  yield checkIndividualResults("no-referrer (changed) with origin first", ["none"], [name+'no-referrer']);
+
+  yield resetState();
+  var name = "unsafe-url-no-referrer";
+  yield iframe.src = sjs + "&policy=" + escape('unsafe-url') + "&name=" + name + "&newPolicy=" + escape('no-referrer');
+  yield checkIndividualResults("no-referrer (changed) with unsafe-url first", ["none"], [name+'no-referrer']);
+
+  // complete.  Be sure to yield so we don't call this twice.
+  yield SimpleTest.finish();
+})();
+
+</script>
+</head>
+
+<body onload="tests.next();">
+  <iframe id="testframe"></iframe>
+
+</body>
+</html>
+