<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Bug 1832249 - Consider report-only flag when upgrading insecure requests</title>
  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe id="reportonlyframe"></iframe>
<iframe id="enforceframe"></iframe>

<script class="testbody" type="text/javascript">

/* Description of the test:
 * When we load an http page with the `content-security-policy-report-only: upgrade-insecure-requests`
 * header the `upgrade-insecure-requests` directive must be ignored according to the spec.
 * https://w3c.github.io/webappsec-upgrade-insecure-requests/#delivery
 */

var expectedResults = 4;

function finishTest() {
  // need to wait until all of the tests have resolved before exiting
  if (--expectedResults > 0) {
    return;
  }
  window.removeEventListener("message", receiveMessage);
  SimpleTest.finish();
}

window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
  // make sure the image was correctly loaded. this is the primary purpose of
  // this test. if image isn't loaded correctly then that means we attempted to
  // upgrade the request when we shouldn't have and vice-versa.
  let result = event.data.result;
  if (result === "reportonly-img-ok") {
    ok(true, "successfully loaded insecure image from http without upgrade");
    finishTest();
  }
  if (result === "enforce-img-ok") {
    ok(true, "successfully loaded insecure image from http with upgrade");
    finishTest();
  }
  if (result === "reportonly-img-error") {
    ok (false, "failed to load reportonly image correctly");
    finishTest();
  }
  if (result === "enforce-img-error") {
    ok (false, "failed to load enforce image correctly");
    finishTest();
  }
}

function runTest(route) {
  // Send off an XHR request which will return once the server receives the
  // violation report from the report only policy.
  var myXHR = new XMLHttpRequest();
  myXHR.open("GET", `file_upgrade_insecure_report_only_server.sjs?queryresult-${route}`);
  myXHR.onload = function(e) {
    // make sure that the csp violation report we get is the one we expected
    let report = JSON.parse(myXHR.responseText)["csp-report"];
    ok(
      report["original-policy"].includes("upgrade-insecure-requests"),
      "report should be given by malformed report-only policy"
    );
    ok(
      report["blocked-uri"].startsWith("http:") && report["blocked-uri"].endsWith(`.sjs?img-${route}`),
      "request should be for an img load"
    );

    finishTest();
  }
  myXHR.onerror = function(e) {
    ok(false, "could not query result for csp-report from server (" + e.message + ")");
    SimpleTest.finish();
  }
  myXHR.send();

  // We load a page that is served using a report only CSP which loads an image.
  SimpleTest.executeSoon(function() {
    // we need to test http functionality here, so we need to load an http url
    /* eslint-disable @microsoft/sdl/no-insecure-url */
    document.getElementById(`${route}frame`).src =
      `http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_report_only_server.sjs?${route}=true`;
    /* eslint-enable @microsoft/sdl/no-insecure-url */
  });
}

SimpleTest.waitForExplicitFinish();
runTest("reportonly");
runTest("enforce");

</script>
</body>
</html>
