<!doctype html>
<meta charset="utf-8">
<title>Referrer Policy: iframe src="about:blank"</title>
<link rel="author" title="Hiroshige Hayashizaki" href="mailto:hiroshige@chromium.org">
<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<meta name="referrer" content="origin">
<body>
<script>
const testFetchClientReferrer =
  async_test("The fetch() API in an about:blank iframe with the 'client' " +
             "referrer is fetched with no 'Referer' header");
const testFetchURLReferrer =
  async_test("The fetch() API in an about:blank iframe with a custom URL " +
             "referrer is fetched with a 'Referer` header that uses the " +
             "outer document's URL along with its referrer policy");
const testDocumentReferrer =
  async_test("The value of document.referrer in an about:blank iframe is the " +
             "outer document's full URL, regardless of referrer policy");
const testSubresource =
  async_test("A subresource fetched from an about:blank iframe is fetched " +
             "with no 'Referer' header");

window.addEventListener("message", msg => {
  const test_name = msg.data.test;
  const referrer = msg.data.referrer;
  if (test_name === "testFetchClientReferrer") {
    testFetchClientReferrer.step_func_done(() => {
      // Because the URL of the Document of <iframe src="about:blank"> is
      // "about:blank", the stripped URL is no referrer:
      // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
      assert_equals(referrer, undefined);
    })();
  } else if (test_name === "testFetchURLReferrer") {
    // <iframe src="about:blank"> inherits its parent's referrer policy.
    // Note: Setting an explicit URL as referrer succeeds
    // because the same-origin check at
    // https://fetch.spec.whatwg.org/#dom-request
    // is done against <iframe>'s origin, which inherits the parent
    // Document's origin == location.orgin. Furthermore, since the iframe
    // inherits its parent's referrer policy, the URL should be restricted to
    // its origin.
    testFetchURLReferrer.step_func_done(() => {
      assert_equals(referrer, location.origin + '/');
    })();
  } else if (test_name === "testDocumentReferrer") {
    // The referrer of the initial document in an about:blank iframe is set to
    // its creating document's URL, unredacted by a referrer policy, as per step
    // 13 of:
    // https://html.spec.whatwg.org/multipage/browsers.html#creating-a-new-browsing-context.
    testDocumentReferrer.step_func_done(() => {
      assert_equals(referrer, location.href);
    })();
  } else if (test_name === "testSubresource") {
    // Because the URL of the Document of <iframe src="about:blank"> is
    // "about:blank", the stripped URL is no referrer:
    // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
    testSubresource.step_func_done(() => {
      assert_equals(referrer, "");
    })();
  }
});

const iframe = document.createElement("iframe");

iframe.addEventListener("load", function() {
  const iframe_script = iframe.contentDocument.createElement('script');
  iframe_script.textContent = `
    // Test fetch() API with default "client" referrer.
    fetch("${location.origin}/common/security-features/subresource/xhr.py?name=testFetchClientReferrer")
      .then(r => r.json())
      .then(j => {
          top.postMessage({test: "testFetchClientReferrer", referrer: j.headers.referer}, "*")
        }).catch(e => {
          top.postMessage({test: "testFetchClientReferrer", referrer: "FAILURE"}, "*");
        });

    // Test fetch() API with custom URL referrer.
    fetch("${location.origin}/common/security-features/subresource/xhr.py?name=URL",
        {referrer: "${location.href}/custom"})
      .then(r => r.json())
      .then(j => {
          top.postMessage({test: "testFetchURLReferrer", referrer: j.headers.referer}, "*")
        }).catch(e => {
          top.postMessage({test: "testFetchURLReferrer", referrer: "FAILURE"}, "*");
        });

    // Test document.referrer.
    top.postMessage({test: "testDocumentReferrer", referrer: document.referrer}, "*");

    // Test a subresource being fetched by the iframe.
    const subresource_script = document.createElement('script');
    subresource_script.src = "${location.origin}/common/security-features/subresource/referrer.py";
    subresource_script.onload = e => {
      top.postMessage({test: "testSubresource", referrer: window.referrer}, "*");
    }
    subresource_script.onerror = function(e) {
      top.postMessage({test: "testSubresource", referrer: "FAILURE"}, "*");
    };
    document.head.appendChild(subresource_script);
  `;
  iframe.contentDocument.body.appendChild(iframe_script);
});

document.body.appendChild(iframe);
</script>
