Bug 1264164 - Add Referrer Policy HTTP header testcases. r=jdm
authorThomas Nguyen <tnguyen@mozilla.com>
Mon, 18 Jul 2016 10:35:13 +0800
changeset 345743 77fbb7ff85e5db985765c7b7a51f7001db5bf42b
parent 345742 81ad4d06462dc2130ade1d35c9949e37ba2d1f00
child 345744 cb72efabe34e4397e3c413fa495860b203f1f938
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1264164
milestone50.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 1264164 - Add Referrer Policy HTTP header testcases. r=jdm MozReview-Commit-ID: JMUr8DxAzVh
dom/workers/test/mochitest.ini
dom/workers/test/referrer_test_server.sjs
dom/workers/test/referrer_worker.html
dom/workers/test/test_referrer_header_worker.html
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin-worker.html
testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.html
testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.html.headers
testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.js
testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.js.headers
--- a/dom/workers/test/mochitest.ini
+++ b/dom/workers/test/mochitest.ini
@@ -60,16 +60,17 @@ support-files =
   sharedWorker_console.js
   sharedWorker_sharedWorker.js
   simpleThread_worker.js
   suspend_iframe.html
   suspend_worker.js
   terminate_worker.js
   test_csp.html^headers^
   test_csp.js
+  referrer_worker.html
   threadErrors_worker1.js
   threadErrors_worker2.js
   threadErrors_worker3.js
   threadErrors_worker4.js
   threadTimeouts_worker.js
   throwingOnerror_worker.js
   timeoutTracing_worker.js
   transferable_worker.js
@@ -89,16 +90,17 @@ support-files =
   bug1062920_worker.js
   webSocket_sharedWorker.js
   bug1104064_worker.js
   worker_consoleAndBlobs.js
   bug1132395_sharedWorker.js
   bug1132924_worker.js
   empty.html
   referrer.sjs
+  referrer_test_server.sjs
   sharedWorker_ports.js
   sharedWorker_lifetime.js
   worker_referrer.js
   websocket_https.html
   websocket_https_worker.js
   worker_fileReader.js
   fileapi_chromeScript.js
   importScripts_3rdParty_worker.js
@@ -216,14 +218,15 @@ skip-if = buildapp == 'b2g' || toolkit =
 skip-if = buildapp == 'b2g' # no https on b2g
 [test_websocket_loadgroup.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
 [test_webSocket_sharedWorker.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
 [test_worker_interfaces.html]
 [test_workersDisabled.html]
 [test_referrer.html]
+[test_referrer_header_worker.html]
 [test_importScripts_3rdparty.html]
 [test_sharedWorker_ports.html]
 [test_sharedWorker_lifetime.html]
 [test_fileReader.html]
 [test_navigator_workers_hardwareConcurrency.html]
 [test_bug1278777.html]
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/referrer_test_server.sjs
@@ -0,0 +1,101 @@
+Components.utils.importGlobalProperties(["URLSearchParams"]);
+const SJS = "referrer_test_server.sjs?";
+const SHARED_KEY = SJS;
+
+var SAME_ORIGIN = "https://example.com/tests/dom/workers/test/" + SJS;
+var CROSS_ORIGIN = "https://test2.example.com/tests/dom/workers/test/" + SJS;
+var DOWNGRADE = "http://example.com/tests/dom/workers/test/" + SJS;
+
+function createUrl(aRequestType, aPolicy) {
+  var searchParams = new URLSearchParams();
+  searchParams.append("ACTION", "request-worker");
+  searchParams.append("Referrer-Policy", aPolicy);
+  searchParams.append("TYPE", aRequestType);
+
+  var url = SAME_ORIGIN;
+
+  if (aRequestType === "cross-origin") {
+    url = CROSS_ORIGIN;
+  } else if (aRequestType === "downgrade") {
+    url = DOWNGRADE;
+  }
+
+  return url + searchParams.toString();
+}
+function createWorker (aRequestType, aPolicy) {
+  return `
+    onmessage = function() {
+      fetch("${createUrl(aRequestType, aPolicy)}").then(function () {
+        postMessage(42);
+        close();
+      });
+    }
+  `;
+}
+
+function handleRequest(request, response) {
+  var params = new URLSearchParams(request.queryString);
+  var policy = params.get("Referrer-Policy");
+  var type = params.get("TYPE");
+  var action = params.get("ACTION");
+  response.setHeader("Content-Security-Policy", "default-src *", false);
+  response.setHeader("Access-Control-Allow-Origin", "*", false);
+
+  if (policy) {
+    response.setHeader("Referrer-Policy", policy, false);
+  }
+
+  if (action === "test") {
+    response.setHeader("Content-Type", "text/javascript", false);
+    response.write(createWorker(type, policy));
+    return;
+  }
+
+  if (action === "resetState") {
+    setSharedState(SHARED_KEY, "{}");
+    response.write("");
+    return;
+  }
+
+  if (action === "get-test-results") {
+    response.setHeader("Cache-Control", "no-cache", false);
+    response.setHeader("Content-Type", "text/plain", false);
+    response.write(getSharedState(SHARED_KEY));
+    return;
+  }
+
+  if (action === "request-worker") {
+    var result = getSharedState(SHARED_KEY);
+    result = result ? JSON.parse(result) : {};
+    var referrerLevel = "none";
+    var test = {};
+
+    if (request.hasHeader("Referer")) {
+      var referrer = request.getHeader("Referer");
+      if (referrer.indexOf("referrer_test_server") > 0) {
+        referrerLevel = "full";
+      } else if (referrer.indexOf("https://example.com") == 0) {
+        referrerLevel = "origin";
+      } else {
+        // this is never supposed to happen
+        referrerLevel = "other-origin";
+      }
+      test.referrer = referrer;
+    } else {
+      test.referrer = "";
+    }
+
+    test.policy = referrerLevel;
+    test.expected = policy;
+
+    // test id equals type + "-" + policy
+    // Ex: same-origin-default
+    result[type + "-" + policy] = test;
+    setSharedState(SHARED_KEY, JSON.stringify(result));
+
+    response.write("'hello world'");
+    return;
+  }
+}
+
+
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/referrer_worker.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body onload="tests.next();">
+<script type="text/javascript;version=1.7">
+const SJS = "referrer_test_server.sjs?";
+const BASE_URL = "https://example.com/tests/dom/workers/test/" + SJS;
+const GET_RESULT = BASE_URL + 'ACTION=get-test-results';
+const RESET_STATE = BASE_URL + 'ACTION=resetState';
+
+function ok(val, message) {
+  val = val ? "true" : "false";
+  window.parent.postMessage("SimpleTest.ok(" + val + ", '" + message + "');", "*");
+}
+
+function info(val) {
+  window.parent.postMessage("SimpleTest.info(" + val + ");", "*");
+}
+
+function is(a, b, message) {
+  ok(a == b, message);
+}
+
+function finish() {
+  // Let window.onerror have a chance to fire
+  setTimeout(function() {
+    setTimeout(function() {
+      tests.close();
+      window.parent.postMessage("SimpleTest.finish();", "*");
+    }, 0);
+  }, 0);
+}
+
+var testCases = {
+  'same-origin':  { 'Referrer-Policy' : { 'default' : 'full',
+                                          'origin' : 'origin',
+                                          'origin-when-cross-origin' : 'full',
+                                          'unsafe-url' : 'full',
+                                          'no-referrer' : 'none',
+                                          'unsafe-url, no-referrer' : 'none',
+                                          'invalid' : 'full' }},
+
+  'cross-origin':  { 'Referrer-Policy' : { 'default' : 'full',
+                                           'origin' : 'origin',
+                                           'origin-when-cross-origin' : 'origin',
+                                           'unsafe-url' : 'full',
+                                           'no-referrer' : 'none',
+                                           'unsafe-url, no-referrer' : 'none',
+                                           'invalid' : 'full' }},
+
+  // Downgrading in worker is blocked entirely without unblock option
+  // https://bugzilla.mozilla.org/show_bug.cgi?id=1198078#c17
+  // Skip the downgrading test
+  /* 'downgrade':  { 'Referrer-Policy' : { 'default' : 'full',
+                                          'origin'  : 'full',
+                                          'origin-when-cross-origin"'  : 'full',
+                                          'unsafe-url'  : 'full',
+                                          'no-referrer'  : 'full',
+                                          'unsafe-url, no-referrer' : 'none',
+                                          'invalid'  : 'full' }}, */
+
+
+};
+
+var advance = function() { tests.next(); };
+
+/**
+ * helper to perform an XHR
+ * to do checkIndividualResults and resetState
+ */
+function doXHR(aUrl, onSuccess, onFail) {
+  var xhr = new XMLHttpRequest({mozSystem: true});
+  xhr.responseType = "json";
+  xhr.onload = function () {
+    onSuccess(xhr);
+  };
+  xhr.onerror = function () {
+    onFail(xhr);
+  };
+  xhr.open('GET', aUrl, true);
+  xhr.send(null);
+}
+
+
+function resetState() {
+  doXHR(RESET_STATE,
+    advance,
+    function(xhr) {
+      ok(false, "error in reset state");
+      finish();
+    });
+}
+
+function checkIndividualResults(aType, aPolicy, aExpected) {
+  var onload = xhr => {
+    var results = xhr.response;
+    dump(JSON.stringify(xhr.response));
+    // test id equals type + "-" + policy
+    // Ex: same-origin-default
+    var id = aType + "-" + aPolicy;
+    ok(id in results, id + " tests have to be performed.");
+    is(results[id].policy, aExpected, id + ' --- ' + results[id].policy + ' (' + results[id].referrer + ')');
+    advance();
+  };
+  var onerror = xhr => {
+    ok(false, "Can't get results from the counter server.");
+    finish();
+  };
+  doXHR(GET_RESULT, onload, onerror);
+}
+
+var tests = (function() {
+
+  for (var type in testCases) {
+    for (var policy in testCases[type]['Referrer-Policy']) {
+      yield resetState();
+      var searchParams = new URLSearchParams();
+      searchParams.append("TYPE", type);
+      searchParams.append("ACTION", "test");
+      searchParams.append("Referrer-Policy", policy);
+      var worker = new Worker(BASE_URL + searchParams.toString());
+      worker.onmessage = function () {
+        advance();
+      };
+      yield worker.postMessage(42);
+      yield checkIndividualResults(type, policy, escape(testCases[type]['Referrer-Policy'][policy]));
+    }
+  }
+
+  // complete.  Be sure to yield so we don't call this twice.
+  yield finish();
+})();
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/test_referrer_header_worker.html
@@ -0,0 +1,39 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test the referrer of workers</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <script class="testbody" type="text/javascript">
+    SimpleTest.waitForExplicitFinish();
+
+    SpecialPowers.pushPrefEnv(
+      {"set": [
+         ['security.mixed_content.block_display_content', false],
+         ['security.mixed_content.block_active_content', false]
+      ]},
+      function() {
+        SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], test);
+    });
+
+    function test() {
+      function messageListener(event) {
+        eval(event.data);
+      }
+      window.addEventListener("message", messageListener, false);
+
+      var ifr = document.createElement('iframe');
+      ifr.setAttribute('src', 'https://example.com/tests/dom/workers/test/referrer_worker.html');
+      document.body.appendChild(ifr);
+    }
+  </script>
+</body>
+</html>
+
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -36398,16 +36398,28 @@
           }
         ],
         "fetch/api/basic/request-referrer.html": [
           {
             "path": "fetch/api/basic/request-referrer.html",
             "url": "/fetch/api/basic/request-referrer.html"
           }
         ],
+        "fetch/api/policies/referrer-origin-when-cross-origin-worker.html": [
+          {
+            "path": "fetch/api/policies/referrer-origin-when-cross-origin-worker.html",
+            "url": "/fetch/api/policies/referrer-origin-when-cross-origin-worker.html"
+          }
+        ],
+        "fetch/api/policies/referrer-origin-when-cross-origin.html": [
+          {
+            "path": "fetch/api/policies/referrer-origin-when-cross-origin.html",
+            "url": "/fetch/api/policies/referrer-origin-when-cross-origin.html"
+          }
+        ],
         "service-workers/service-worker/client-navigate.https.html": [
           {
             "path": "service-workers/service-worker/client-navigate.https.html",
             "url": "/service-workers/service-worker/client-navigate.https.html"
           }
         ],
         "service-workers/service-worker/controller-on-disconnect.https.html": [
           {
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin-worker.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Fetch in worker: referrer with origin-when-cross-origin policy</title>
+    <meta name="help" href="https://fetch.spec.whatwg.org/#main-fetch">
+    <meta name="help" href="https://fetch.spec.whatwg.org/#http-network-or-cache-fetch">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <script>
+      fetch_tests_from_worker(new Worker("referrer-origin-when-cross-origin.js?pipe=sub"));
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Fetch: referrer with origin-when-cross-origin policy</title>
+    <meta name="help" href="https://fetch.spec.whatwg.org/#main-fetch">
+    <meta name="help" href="https://fetch.spec.whatwg.org/#http-network-or-cache-fetch">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <script src="../resources/utils.js"></script>
+    <script src="referrer-origin-when-cross-origin.js?pipe=sub"></script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.html.headers
@@ -0,0 +1,1 @@
+Referrer-Policy: origin-when-cross-origin
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.js
@@ -0,0 +1,16 @@
+if (this.document === undefined) {
+  importScripts("/resources/testharness.js");
+  importScripts("../resources/utils.js");
+}
+
+var referrerOrigin = "http://{{host}}:{{ports[http][0]}}/";
+var fetchedUrl = "http://{{host}}:{{ports[http][1]}}" + dirname(location.pathname) + RESOURCES_DIR + "inspect-headers.py?cors&headers=referer";
+
+promise_test(function(test) {
+  return fetch(fetchedUrl).then(function(resp) {
+    assert_equals(resp.status, 200, "HTTP status is 200");
+    assert_equals(resp.headers.get("x-request-referer"), referrerOrigin, "request's referrer is " + referrerOrigin);
+  });
+}, "Request's referrer is origin");
+
+done();
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/policies/referrer-origin-when-cross-origin.js.headers
@@ -0,0 +1,1 @@
+Referrer-Policy: origin-when-cross-origin