/**
 * @fileoverview Utilities for mixed-content in Web Platform Tests.
 * @author burnik@google.com (Kristijan Burnik)
 * Disclaimer: Some methods of other authors are annotated in the corresponding
 *     method's JSDoc.
 */

// ===============================================================
// Types
// ===============================================================
// Objects of the following types are used to represent what kind of
// subresource requests should be sent with what kind of policies,
// from what kind of possibly nested source contexts.
// The objects are represented as JSON objects (not JavaScript/Python classes
// in a strict sense) to be passed between JavaScript/Python code.

// Note: So far this document covers:
// - resources/common.sub.js : client-side test infra code
// - scope/ - server-side scripts that serves nested source contexts
// but doesn't cover:
// - tools/ - generator scripts that generates top-level HTML documents.
// There are some policies only handled by generators (e.g. mixed-content
// opt-ins) and not yet covered by the docs here.

/**
  @typedef PolicyDelivery
  @type {object}
  Referrer policy etc. can be applied/delivered in several ways.
  A PolicyDelivery object specifies what policy is delivered and how.

  @property {string} deliveryType
    Specifies how the policy is delivered.
    The valid deliveryType are:

     "attr"
        [A] DOM attributes e.g. referrerPolicy.

      "rel-noref"
        [A] <link rel="noreferrer"> (referrer-policy only).

      "http-rp"
        [B] HTTP response headers.

      "meta"
        [B] <meta> elements.

  @property {string} key
  @property {string} value
    Specifies what policy to be delivered. The valid keys are:

      "referrerPolicy"
        Referrer Policy
        https://w3c.github.io/webappsec-referrer-policy/
        Valid values are those listed in
        https://w3c.github.io/webappsec-referrer-policy/#referrer-policy
        (except that "" is represented as null/None)

  A PolicyDelivery can be specified in several ways:

  - (for [A]) Associated with an individual subresource request and
    specified in `Subresource.policies`,
    e.g. referrerPolicy attributes of DOM elements.
    This is handled in invokeRequest().

  - (for [B]) Associated with an nested environmental settings object and
    specified in `SourceContext.policies`,
    e.g. HTTP referrer-policy response headers of HTML/worker scripts.
    This is handled in server-side under /common/security-features/scope/.

  - (for [B]) Associated with the top-level HTML document.
    This is handled by the generators.d
*/

/**
  @typedef Subresource
  @type {object}
  A Subresource represents how a subresource request is sent.

  @property{SubresourceType} subresourceType
    How the subresource request is sent,
    e.g. "img-tag" for sending a request via <img src>.
    See the keys of `subresourceMap` for valid values.

  @property{string} url
    subresource's URL.
    Typically this is constructed by getRequestURLs() below.

  @property{PolicyDelivery} policyDeliveries
    Policies delivered specific to the subresource request.
*/

/**
  @typedef SourceContext
  @type {object}
  Requests can be possibly sent from various kinds of source contexts, i.e.
  fetch client's environment settings objects:
  top-level windows, iframes, or workers.
  A SourceContext object specifies one environment settings object, and
  an Array<SourceContext> specifies a possibly nested context,
  from the outer-most to inner-most environment settings objects.

  For example:
    [{sourceContextType: "srcdoc"}, {sourceContextType: "worker-classic"}]
  means that a subresource request is to be sent from
  a classic dedicated worker created from <iframe srcdoc>
  inside the top-level HTML document.
  Note: the top-level document is not included in the array and
  is assumed implicitly.

  SourceContext (or Array<SourceContext>) is set based on
  the fetch client's settings object that is used for the subresource request,
  NOT on module map settings object, and
  NOT on the inner-most settings object that appears in the test.
  For example, Array<SourceContext> is `[]` (indicating the top Window)
  for `worker.js`
  - When it is the root worker script: `new Worker('worker.js')`, or
  - When it is imported from the root worker script:
    `new Worker('top.js', {type: 'module'})`
    where `top.js` has `import 'worker.js'`.
  because the request for `worker.js` uses the Window as its fetch client's
  settings object, while a WorkerGlobalScope is created though.

  @property {string} sourceContextType
    Kind of the source context to be used.
    Valid values are the keys of `sourceContextMap` below.

  @property {Array<PolicyDelivery>} policyDeliveries
    A list of PolicyDelivery applied to the source context.
*/

// ===============================================================
// General utility functions
// ===============================================================

function timeoutPromise(t, ms) {
  return new Promise(resolve => { t.step_timeout(resolve, ms); });
}

/**
 * Normalizes the target port for use in a URL. For default ports, this is the
 *     empty string (omitted port), otherwise it's a colon followed by the port
 *     number. Ports 80, 443 and an empty string are regarded as default ports.
 * @param {number} targetPort The port to use
 * @return {string} The port portion for using as part of a URL.
 */
function getNormalizedPort(targetPort) {
  return ([80, 443, ""].indexOf(targetPort) >= 0) ? "" : ":" + targetPort;
}

/**
 * Creates a GUID.
 *     See: https://en.wikipedia.org/wiki/Globally_unique_identifier
 *     Original author: broofa (http://www.broofa.com/)
 *     Sourced from: http://stackoverflow.com/a/2117523/4949715
 * @return {string} A pseudo-random GUID.
 */
function guid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

/**
 * Initiates a new XHR via GET.
 * @param {string} url The endpoint URL for the XHR.
 * @param {string} responseType Optional - how should the response be parsed.
 *     Default is "json".
 *     See: https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsetype
 * @return {Promise} A promise wrapping the success and error events.
 */
function xhrRequest(url, responseType) {
  return new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = responseType || "json";

    xhr.addEventListener("error", function() {
      reject(Error("Network Error"));
    });

    xhr.addEventListener("load", function() {
      if (xhr.status != 200)
        reject(Error(xhr.statusText));
      else
        resolve(xhr.response);
    });

    xhr.send();
  });
}

/**
 * Sets attributes on a given DOM element.
 * @param {DOMElement} element The element on which to set the attributes.
 * @param {object} An object with keys (serving as attribute names) and values.
 */
function setAttributes(el, attrs) {
  attrs = attrs || {}
  for (var attr in attrs) {
    if (attr !== 'src')
      el.setAttribute(attr, attrs[attr]);
  }
  // Workaround for Chromium: set <img>'s src attribute after all other
  // attributes to ensure the policy is applied.
  for (var attr in attrs) {
    if (attr === 'src')
      el.setAttribute(attr, attrs[attr]);
  }
}

/**
 * Binds to success and error events of an object wrapping them into a promise
 *     available through {@code element.eventPromise}. The success event
 *     resolves and error event rejects.
 * This method adds event listeners, and then removes all the added listeners
 * when one of listened event is fired.
 * @param {object} element An object supporting events on which to bind the
 *     promise.
 * @param {string} resolveEventName [="load"] The event name to bind resolve to.
 * @param {string} rejectEventName [="error"] The event name to bind reject to.
 */
function bindEvents(element, resolveEventName, rejectEventName) {
  element.eventPromise =
      bindEvents2(element, resolveEventName, element, rejectEventName);
}

// Returns a promise wrapping success and error events of objects.
// This is a variant of bindEvents that can accept separate objects for each
// events and two events to reject, and doesn't set `eventPromise`.
//
// When `resolveObject`'s `resolveEventName` event (default: "load") is
// fired, the promise is resolved with the event.
//
// When `rejectObject`'s `rejectEventName` event (default: "error") or
// `rejectObject2`'s `rejectEventName2` event (default: "error") is
// fired, the promise is rejected.
//
// `rejectObject2` is optional.
function bindEvents2(resolveObject, resolveEventName, rejectObject, rejectEventName, rejectObject2, rejectEventName2) {
  return new Promise(function(resolve, reject) {
    const actualResolveEventName = resolveEventName || "load";
    const actualRejectEventName = rejectEventName || "error";
    const actualRejectEventName2 = rejectEventName2 || "error";

    const resolveHandler = function(event) {
      cleanup();
      resolve(event);
    };

    const rejectHandler = function(event) {
      // Chromium starts propagating errors from worker.onerror to
      // window.onerror. This handles the uncaught exceptions in tests.
      event.preventDefault();
      cleanup();
      reject(event);
    };

    const cleanup = function() {
      resolveObject.removeEventListener(actualResolveEventName, resolveHandler);
      rejectObject.removeEventListener(actualRejectEventName, rejectHandler);
      if (rejectObject2) {
        rejectObject2.removeEventListener(actualRejectEventName2, rejectHandler);
      }
    };

    resolveObject.addEventListener(actualResolveEventName, resolveHandler);
    rejectObject.addEventListener(actualRejectEventName, rejectHandler);
    if (rejectObject2) {
      rejectObject2.addEventListener(actualRejectEventName2, rejectHandler);
    }
  });
}

/**
 * Creates a new DOM element.
 * @param {string} tagName The type of the DOM element.
 * @param {object} attrs A JSON with attributes to apply to the element.
 * @param {DOMElement} parent Optional - an existing DOM element to append to
 *     If not provided, the returned element will remain orphaned.
 * @param {boolean} doBindEvents Optional - Whether to bind to load and error
 *     events and provide the promise wrapping the events via the element's
 *     {@code eventPromise} property. Default value evaluates to false.
 * @return {DOMElement} The newly created DOM element.
 */
function createElement(tagName, attrs, parentNode, doBindEvents) {
  var element = document.createElement(tagName);

  if (doBindEvents)
    bindEvents(element);

  // We set the attributes after binding to events to catch any
  // event-triggering attribute changes. E.g. form submission.
  //
  // But be careful with images: unlike other elements they will start the load
  // as soon as the attr is set, even if not in the document yet, and sometimes
  // complete it synchronously, so the append doesn't have the effect we want.
  // So for images, we want to set the attrs after appending, whereas for other
  // elements we want to do it before appending.
  var isImg = (tagName == "img");
  if (!isImg)
    setAttributes(element, attrs);

  if (parentNode)
    parentNode.appendChild(element);

  if (isImg)
    setAttributes(element, attrs);

  return element;
}

function createRequestViaElement(tagName, attrs, parentNode) {
  return createElement(tagName, attrs, parentNode, true).eventPromise;
}

/**
 * Creates a new empty iframe and appends it to {@code document.body} .
 * @param {string} name The name and ID of the new iframe.
 * @param {boolean} doBindEvents Whether to bind load and error events.
 * @return {DOMElement} The newly created iframe.
 */
function createHelperIframe(name, doBindEvents) {
  return createElement("iframe",
                       {"name": name, "id": name},
                       document.body,
                       doBindEvents);
}

function wrapResult(server_data) {
  if (typeof(server_data) === "string") {
    throw server_data;
  }
  return {
    referrer: server_data.headers.referer,
    headers: server_data.headers
  }
}

// ===============================================================
// Subresources
// ===============================================================

/**
  @typedef RequestResult
  @type {object}
  Represents the result of sending an request.
  All properties are optional. See the comments for
  requestVia*() and invokeRequest() below to see which properties are set.

  @property {Array<Object<string, string>>} headers
    HTTP request headers sent to server.
  @property {string} referrer - Referrer.
  @property {string} location - The URL of the subresource.
  @property {string} sourceContextUrl
    the URL of the global object where the actual request is sent.
*/

/**
  requestVia*(url, additionalAttributes) functions send a subresource
  request from the current environment settings object.

  @param {string} url
    The URL of the subresource.
  @param {Object<string, string>} additionalAttributes
    Additional attributes set to DOM elements
    (element-initiated requests only).

  @returns {Promise} that are resolved with a RequestResult object
  on successful requests.

  - Category 1:
      `headers`: set.
      `referrer`: set via `document.referrer`.
      `location`: set via `document.location`.
      See `template/document.html.template`.
  - Category 2:
      `headers`: set.
      `referrer`: set to `headers.referer` by `wrapResult()`.
      `location`: not set.
  - Category 3:
      All the keys listed above are NOT set.
  `sourceContextUrl` is not set here.

  -------------------------------- -------- --------------------------
  Function name                    Category Used in
                                            -------- ------- ---------
                                            referrer mixed-  upgrade-
                                            policy   content insecure-
                                            policy   content request
  -------------------------------- -------- -------- ------- ---------
  requestViaAnchor                 1        Y        Y       -
  requestViaArea                   1        Y        Y       -
  requestViaAudio                  3        -        Y       -
  requestViaDedicatedWorker        2        Y        Y       Y
  requestViaFetch                  2        Y        Y       -
  requestViaForm                   3        -        Y       -
  requestViaIframe                 1        Y        Y       -
  requestViaImage                  2        Y        Y       -
  requestViaLinkPrefetch           3        -        Y       -
  requestViaLinkStylesheet         3        -        Y       -
  requestViaObject                 3        -        Y       -
  requestViaPicture                3        -        Y       -
  requestViaScript                 2        Y        Y       -
  requestViaSendBeacon             3        -        Y       -
  requestViaSharedWorker           2        Y        -       -
  requestViaVideo                  3        -        Y       -
  requestViaWebSocket              3        -        Y       -
  requestViaWorklet                3        -        Y       Y
  requestViaXhr                    2        Y        Y       -
  -------------------------------- -------- -------- ------- ---------
*/

/**
 * Creates a new iframe, binds load and error events, sets the src attribute and
 *     appends it to {@code document.body} .
 * @param {string} url The src for the iframe.
 * @return {Promise} The promise for success/error events.
 */
function requestViaIframe(url, additionalAttributes) {
  const iframe = createElement(
      "iframe",
      Object.assign({"src": url}, additionalAttributes),
      document.body,
      false);
  return bindEvents2(window, "message", iframe, "error", window, "error")
      .then(event => {
          if (event.source !== iframe.contentWindow)
            return Promise.reject(new Error('Unexpected event.source'));
          return event.data;
        });
}

/**
 * Creates a new image, binds load and error events, sets the src attribute and
 *     appends it to {@code document.body} .
 * @param {string} url The src for the image.
 * @return {Promise} The promise for success/error events.
 */
function requestViaImage(url, additionalAttributes) {
  const img = createElement(
      "img",
      // crossOrigin attribute is added to read the pixel data of the response.
      Object.assign({"src": url, "crossOrigin": "Anonymous"}, additionalAttributes),
      document.body, true);
  return img.eventPromise.then(() => wrapResult(decodeImageData(img)));
}

// Helper for requestViaImage().
function decodeImageData(img) {
  var canvas = document.createElement("canvas");
  var context = canvas.getContext('2d');
  context.drawImage(img, 0, 0);
  var imgData = context.getImageData(0, 0, img.clientWidth, img.clientHeight);
  const rgba = imgData.data;

  let decodedBytes = new Uint8ClampedArray(rgba.length);
  let decodedLength = 0;

  for (var i = 0; i + 12 <= rgba.length; i += 12) {
    // A single byte is encoded in three pixels. 8 pixel octets (among
    // 9 octets = 3 pixels * 3 channels) are used to encode 8 bits,
    // the most significant bit first, where `0` and `255` in pixel values
    // represent `0` and `1` in bits, respectively.
    // This encoding is used to avoid errors due to different color spaces.
    const bits = [];
    for (let j = 0; j < 3; ++j) {
      bits.push(rgba[i + j * 4 + 0]);
      bits.push(rgba[i + j * 4 + 1]);
      bits.push(rgba[i + j * 4 + 2]);
      // rgba[i + j * 4 + 3]: Skip alpha channel.
    }
    // The last one element is not used.
    bits.pop();

    // Decode a single byte.
    let byte = 0;
    for (let j = 0; j < 8; ++j) {
      byte <<= 1;
      if (bits[j] >= 128)
        byte |= 1;
    }

    // Zero is the string terminator.
    if (byte == 0)
      break;

    decodedBytes[decodedLength++] = byte;
  }

  // Remove trailing nulls from data.
  decodedBytes = decodedBytes.subarray(0, decodedLength);
  var string_data = (new TextDecoder("ascii")).decode(decodedBytes);

  return JSON.parse(string_data);
}

/**
 * Initiates a new XHR GET request to provided URL.
 * @param {string} url The endpoint URL for the XHR.
 * @return {Promise} The promise for success/error events.
 */
function requestViaXhr(url) {
  return xhrRequest(url).then(result => wrapResult(result));
}

/**
 * Initiates a new GET request to provided URL via the Fetch API.
 * @param {string} url The endpoint URL for the Fetch.
 * @return {Promise} The promise for success/error events.
 */
function requestViaFetch(url) {
  return fetch(url)
    .then(res => res.json())
    .then(j => wrapResult(j));
}

function dedicatedWorkerUrlThatFetches(url) {
  return `data:text/javascript,
    fetch('${url}')
      .then(r => r.json())
      .then(j => postMessage(j))
      .catch((e) => postMessage(e.message));`;
}

function workerUrlThatImports(url) {
  return `data:text/javascript,import '${url}';`;
}

/**
 * Creates a new Worker, binds message and error events wrapping them into.
 *     {@code worker.eventPromise} and posts an empty string message to start
 *     the worker.
 * @param {string} url The endpoint URL for the worker script.
 * @param {object} options The options for Worker constructor.
 * @return {Promise} The promise for success/error events.
 */
function requestViaDedicatedWorker(url, options) {
  var worker;
  try {
    worker = new Worker(url, options);
  } catch (e) {
    return Promise.reject(e);
  }
  worker.postMessage('');
  return bindEvents2(worker, "message", worker, "error")
    .then(event => wrapResult(event.data));
}

function requestViaSharedWorker(url) {
  var worker;
  try {
    worker = new SharedWorker(url);
  } catch(e) {
    return Promise.reject(e);
  }
  const promise = bindEvents2(worker.port, "message", worker, "error")
    .then(event => wrapResult(event.data));
  worker.port.start();
  return promise;
}

// Returns a reference to a worklet object corresponding to a given type.
function get_worklet(type) {
  if (type == 'animation')
    return CSS.animationWorklet;
  if (type == 'layout')
    return CSS.layoutWorklet;
  if (type == 'paint')
    return CSS.paintWorklet;
  if (type == 'audio')
    return new OfflineAudioContext(2,44100*40,44100).audioWorklet;

  throw new Error('unknown worklet type is passed.');
}

function requestViaWorklet(type, url) {
  try {
    return get_worklet(type).addModule(url);
  } catch (e) {
    return Promise.reject(e);
  }
}

/**
 * Sets the href attribute on a navigable DOM element and performs a navigation
 *     by clicking it. To avoid navigating away from the current execution
 *     context, a target attribute is set to point to a new helper iframe.
 * @param {DOMElement} navigableElement The navigable DOMElement
 * @param {string} url The href for the navigable element.
 * @return {Promise} The promise for success/error events.
 */
function requestViaNavigable(navigableElement, url) {
  var iframe = createHelperIframe(guid(), false);
  setAttributes(navigableElement,
                {"href": url,
                 "target": iframe.name});

  const promise =
    bindEvents2(window, "message", iframe, "error", window, "error")
      .then(event => {
          if (event.source !== iframe.contentWindow)
            return Promise.reject(new Error('Unexpected event.source'));
          return event.data;
        });
  navigableElement.click();
  return promise;
}

/**
 * Creates a new anchor element, appends it to {@code document.body} and
 *     performs the navigation.
 * @param {string} url The URL to navigate to.
 * @return {Promise} The promise for success/error events.
 */
function requestViaAnchor(url, additionalAttributes) {
  var a = createElement(
      "a",
      Object.assign({"innerHTML": "Link to resource"}, additionalAttributes),
      document.body);

  return requestViaNavigable(a, url);
}

/**
 * Creates a new area element, appends it to {@code document.body} and performs
 *     the navigation.
 * @param {string} url The URL to navigate to.
 * @return {Promise} The promise for success/error events.
 */
function requestViaArea(url, additionalAttributes) {
  var area = createElement(
      "area",
      Object.assign({}, additionalAttributes),
      document.body);

  // TODO(kristijanburnik): Append to map and add image.
  return requestViaNavigable(area, url);
}

/**
 * Creates a new script element, sets the src to url, and appends it to
 *     {@code document.body}.
 * @param {string} url The src URL.
 * @return {Promise} The promise for success/error events.
 */
function requestViaScript(url, additionalAttributes) {
  const script = createElement(
      "script",
      Object.assign({"src": url}, additionalAttributes),
      document.body,
      false);

  return bindEvents2(window, "message", script, "error", window, "error")
    .then(event => wrapResult(event.data));
}

/**
 * Creates a new form element, sets attributes, appends it to
 *     {@code document.body} and submits the form.
 * @param {string} url The URL to submit to.
 * @return {Promise} The promise for success/error events.
 */
function requestViaForm(url) {
  var iframe = createHelperIframe(guid());
  var form = createElement("form",
                           {"action": url,
                            "method": "POST",
                            "target": iframe.name},
                           document.body);
  bindEvents(iframe);
  form.submit();

  return iframe.eventPromise;
}

/**
 * Creates a new link element for a stylesheet, binds load and error events,
 *     sets the href to url and appends it to {@code document.head}.
 * @param {string} url The URL for a stylesheet.
 * @return {Promise} The promise for success/error events.
 */
function requestViaLinkStylesheet(url) {
  return createRequestViaElement("link",
                                 {"rel": "stylesheet", "href": url},
                                 document.head);
}

/**
 * Creates a new link element for a prefetch, binds load and error events, sets
 *     the href to url and appends it to {@code document.head}.
 * @param {string} url The URL of a resource to prefetch.
 * @return {Promise} The promise for success/error events.
 */
function requestViaLinkPrefetch(url) {
  var link = document.createElement('link');
  if (link.relList && link.relList.supports && link.relList.supports("prefetch")) {
    return createRequestViaElement("link",
                                   {"rel": "prefetch", "href": url},
                                   document.head);
  } else {
    return Promise.reject("This browser does not support 'prefetch'.");
  }
}

/**
 * Initiates a new beacon request.
 * @param {string} url The URL of a resource to prefetch.
 * @return {Promise} The promise for success/error events.
 */
async function requestViaSendBeacon(url) {
  function wait(ms) {
    return new Promise(resolve => step_timeout(resolve, ms));
  }
  if (!navigator.sendBeacon(url)) {
    // If mixed-content check fails, it should return false.
    throw new Error('sendBeacon() fails.');
  }
  // We don't have a means to see the result of sendBeacon() request
  // for sure. Let's wait for a while and let the generic test function
  // ask the server for the result.
  await wait(500);
  return 'allowed';
}

/**
 * Creates a new media element with a child source element, binds loadeddata and
 *     error events, sets attributes and appends to document.body.
 * @param {string} type The type of the media element (audio/video/picture).
 * @param {object} media_attrs The attributes for the media element.
 * @param {object} source_attrs The attributes for the child source element.
 * @return {DOMElement} The newly created media element.
 */
function createMediaElement(type, media_attrs, source_attrs) {
  var mediaElement = createElement(type, {});

  var sourceElement = createElement("source", {});

  mediaElement.eventPromise = new Promise(function(resolve, reject) {
    mediaElement.addEventListener("loadeddata", function (e) {
      resolve(e);
    });

    // Safari doesn't fire an `error` event when blocking mixed content.
    mediaElement.addEventListener("stalled", function(e) {
      reject(e);
    });

    sourceElement.addEventListener("error", function(e) {
      reject(e);
    });
  });

  setAttributes(mediaElement, media_attrs);
  setAttributes(sourceElement, source_attrs);

  mediaElement.appendChild(sourceElement);
  document.body.appendChild(mediaElement);

  return mediaElement;
}

/**
 * Creates a new video element, binds loadeddata and error events, sets
 *     attributes and source URL and appends to {@code document.body}.
 * @param {string} url The URL of the video.
 * @return {Promise} The promise for success/error events.
 */
function requestViaVideo(url) {
  return createMediaElement("video",
                            {},
                            {"src": url}).eventPromise;
}

/**
 * Creates a new audio element, binds loadeddata and error events, sets
 *     attributes and source URL and appends to {@code document.body}.
 * @param {string} url The URL of the audio.
 * @return {Promise} The promise for success/error events.
 */
function requestViaAudio(url) {
  return createMediaElement("audio",
                            {},
                            {"type": "audio/wav", "src": url}).eventPromise;
}

/**
 * Creates a new picture element, binds loadeddata and error events, sets
 *     attributes and source URL and appends to {@code document.body}. Also
 *     creates new image element appending it to the picture
 * @param {string} url The URL of the image for the source and image elements.
 * @return {Promise} The promise for success/error events.
 */
function requestViaPicture(url) {
  var picture = createMediaElement("picture", {}, {"srcset": url,
                                                "type": "image/png"});
  return createRequestViaElement("img", {"src": url}, picture);
}

/**
 * Creates a new object element, binds load and error events, sets the data to
 *     url, and appends it to {@code document.body}.
 * @param {string} url The data URL.
 * @return {Promise} The promise for success/error events.
 */
function requestViaObject(url) {
  return createRequestViaElement("object", {"data": url, "type": "text/html"}, document.body);
}

/**
 * Creates a new WebSocket pointing to {@code url} and sends a message string
 * "echo". The {@code message} and {@code error} events are triggering the
 * returned promise resolve/reject events.
 * @param {string} url The URL for WebSocket to connect to.
 * @return {Promise} The promise for success/error events.
 */
function requestViaWebSocket(url) {
  return new Promise(function(resolve, reject) {
    var websocket = new WebSocket(url);

    websocket.addEventListener("message", function(e) {
      resolve(e.data);
    });

    websocket.addEventListener("open", function(e) {
      websocket.send("echo");
    });

    websocket.addEventListener("error", function(e) {
      reject(e)
    });
  })
  .then(data => {
      return JSON.parse(data);
    });
}

/**
  @typedef SubresourceType
  @type {string}

  Represents how a subresource is sent.
  The keys of `subresourceMap` below are the valid values.
*/

// Subresource paths and invokers.
const subresourceMap = {
  "a-tag": {
    path: "/common/security-features/subresource/document.py",
    invoker: requestViaAnchor,
  },
  "area-tag": {
    path: "/common/security-features/subresource/document.py",
    invoker: requestViaArea,
  },
  "audio-tag": {
    path: "/common/security-features/subresource/audio.py",
    invoker: requestViaAudio,
  },
  "beacon": {
    path: "/common/security-features/subresource/empty.py",
    invoker: requestViaSendBeacon,
  },
  "fetch": {
    path: "/common/security-features/subresource/xhr.py",
    invoker: requestViaFetch,
  },
  "form-tag": {
    path: "/common/security-features/subresource/empty.py",
    invoker: requestViaForm,
  },
  "iframe-tag": {
    path: "/common/security-features/subresource/document.py",
    invoker: requestViaIframe,
  },
  "img-tag": {
    path: "/common/security-features/subresource/image.py",
    invoker: requestViaImage,
  },
  "link-css-tag": {
    path: "/common/security-features/subresource/empty.py",
    invoker: requestViaLinkStylesheet,
  },
  "link-prefetch-tag": {
    path: "/common/security-features/subresource/empty.py",
    invoker: requestViaLinkPrefetch,
  },
  "object-tag": {
    path: "/common/security-features/subresource/empty.py",
    invoker: requestViaObject,
  },
  "picture-tag": {
    path: "/common/security-features/subresource/image.py",
    invoker: requestViaPicture,
  },
  "script-tag": {
    path: "/common/security-features/subresource/script.py",
    invoker: requestViaScript,
  },
  "video-tag": {
    path: "/common/security-features/subresource/video.py",
    invoker: requestViaVideo,
  },
  "xhr": {
    path: "/common/security-features/subresource/xhr.py",
    invoker: requestViaXhr,
  },

  "worker-classic": {
    path: "/common/security-features/subresource/worker.py",
    invoker: url => requestViaDedicatedWorker(url),
  },
  "worker-module": {
    path: "/common/security-features/subresource/worker.py",
    invoker: url => requestViaDedicatedWorker(url, {type: "module"}),
  },
  "worker-import-data": {
    path: "/common/security-features/subresource/worker.py",
    invoker: url =>
        requestViaDedicatedWorker(workerUrlThatImports(url), {type: "module"}),
  },
  "sharedworker-classic": {
    path: "/common/security-features/subresource/shared-worker.py",
    invoker: requestViaSharedWorker,
  },

  "websocket": {
    path: "/stash_responder",
    invoker: requestViaWebSocket,
  },
};
for (const workletType of ['animation', 'audio', 'layout', 'paint']) {
  subresourceMap[`worklet-${workletType}`] = {
      path: "/common/security-features/subresource/worker.py",
      invoker: url => requestViaWorklet(workletType, url)
    };
  subresourceMap[`worklet-${workletType}-import-data`] = {
      path: "/common/security-features/subresource/worker.py",
      invoker: url =>
          requestViaWorklet(workletType, workerUrlThatImports(url))
    };
}

/**
  @typedef RedirectionType
  @type {string}

  Represents what redirects should occur to the subresource request
  after initial request.
  See preprocess_redirection() in
  /common/security-features/subresource/subresource.py for valid values.
*/

/**
  Construct subresource (and related) origin.

  @param {string} originType
  @returns {object} the origin of the subresource.
*/
function getSubresourceOrigin(originType) {
  const httpProtocol = "http";
  const httpsProtocol = "https";
  const wsProtocol = "ws";
  const wssProtocol = "wss";

  const sameOriginHost = "{{host}}";
  const crossOriginHost = "{{domains[www1]}}";

  // These values can evaluate to either empty strings or a ":port" string.
  const httpPort = getNormalizedPort(parseInt("{{ports[http][0]}}", 10));
  const httpsPort = getNormalizedPort(parseInt("{{ports[https][0]}}", 10));
  const wsPort = getNormalizedPort(parseInt("{{ports[ws][0]}}", 10));
  const wssPort = getNormalizedPort(parseInt("{{ports[wss][0]}}", 10));

  /**
    @typedef OriginType
    @type {string}

    Represents the origin of the subresource request URL.
    The keys of `originMap` below are the valid values.

    Note that there can be redirects from the specified origin
    (see RedirectionType), and thus the origin of the subresource
    response URL might be different from what is specified by OriginType.
  */
  const originMap = {
    "same-https": httpsProtocol + "://" + sameOriginHost + httpsPort,
    "same-http": httpProtocol + "://" + sameOriginHost + httpPort,
    "cross-https": httpsProtocol + "://" + crossOriginHost + httpsPort,
    "cross-http": httpProtocol + "://" + crossOriginHost + httpPort,
    "same-wss": wssProtocol + "://" + sameOriginHost + wssPort,
    "same-ws": wsProtocol + "://" + sameOriginHost + wsPort,
    "cross-wss": wssProtocol + "://" + crossOriginHost + wssPort,
    "cross-ws": wsProtocol + "://" + crossOriginHost + wsPort,
  };

  return originMap[originType];
}

/**
  Construct subresource (and related) URLs.

  @param {SubresourceType} subresourceType
  @param {OriginType} originType
  @param {RedirectionType} redirectionType
  @returns {object} with following properties:
    {string} testUrl
      The subresource request URL.
    {string} announceUrl
    {string} assertUrl
      The URLs to be used for detecting whether `testUrl` is actually sent
      to the server.
      1. Fetch `announceUrl` first,
      2. then possibly fetch `testUrl`, and
      3. finally fetch `assertUrl`.
         The fetch result of `assertUrl` should indicate whether
         `testUrl` is actually sent to the server or not.
*/
function getRequestURLs(subresourceType, originType, redirectionType) {
  const key = guid();
  const value = guid();

  // We use the same stash path for both HTTP/S and WS/S stash requests.
  const stashPath = encodeURIComponent("/mixed-content");

  const stashEndpoint = "/common/security-features/subresource/xhr.py?key=" +
                        key + "&path=" + stashPath;
  return {
    testUrl:
      getSubresourceOrigin(originType) +
        subresourceMap[subresourceType].path +
        "?redirection=" + encodeURIComponent(redirectionType) +
        "&action=purge&key=" + key +
        "&path=" + stashPath,
    announceUrl: stashEndpoint + "&action=put&value=" + value,
    assertUrl: stashEndpoint + "&action=take",
  };
}

// ===============================================================
// Source Context
// ===============================================================
// Requests can be sent from several source contexts,
// such as the main documents, iframes, workers, or so,
// possibly nested, and possibly with <meta>/http headers added.
// invokeRequest() and invokeFrom*() functions handles
// SourceContext-related setup in client-side.

/**
  invokeRequest() invokes a subresource request
  (specified as `subresource`)
  from a (possibly nested) environment settings object
  (specified as `sourceContextList`).

  For nested contexts, invokeRequest() calls an invokeFrom*() function
  that creates a nested environment settings object using
  /common/security-features/scope/, which calls invokeRequest()
  again inside the nested environment settings object.
  This cycle continues until all specified
  nested environment settings object are created, and
  finally invokeRequest() calls a requestVia*() function to start the
  subresource request from the inner-most environment settings object.

  @param {Subresource} subresource
  @param {Array<SourceContext>} sourceContextList

  @returns {Promise} A promise that is resolved with an RequestResult object.
  `sourceContextUrl` is always set. For whether other properties are set,
  see the comments for requestVia*() above.
*/
function invokeRequest(subresource, sourceContextList) {
  if (sourceContextList.length === 0) {
    // No further nested global objects. Send the subresource request here.

    const additionalAttributes = {};
    /** @type {PolicyDelivery} policyDelivery */
    for (const policyDelivery of (subresource.policyDeliveries || [])) {
      // Depending on the delivery method, extend the subresource element with
      // these attributes.
      if (policyDelivery.deliveryType === "attr") {
        additionalAttributes[policyDelivery.key] = policyDelivery.value;
      } else if (policyDelivery.deliveryType === "rel-noref") {
        additionalAttributes["rel"] = "noreferrer";
      }
    }

    return subresourceMap[subresource.subresourceType].invoker(
        subresource.url,
        additionalAttributes)
      .then(result => Object.assign(
          {sourceContextUrl: location.toString()},
          result));
  }

  // Defines invokers for each valid SourceContext.sourceContextType.
  const sourceContextMap = {
    "srcdoc": { // <iframe srcdoc></iframe>
      invoker: invokeFromIframe,
    },
    "iframe": { // <iframe src="same-origin-URL"></iframe>
      invoker: invokeFromIframe,
    },
    "worker-classic": {
      // Classic dedicated worker loaded from same-origin.
      invoker: invokeFromWorker.bind(undefined, false, {}),
    },
    "worker-classic-data": {
      // Classic dedicated worker loaded from data: URL.
      invoker: invokeFromWorker.bind(undefined, true, {}),
    },
    "worker-module": {
      // Module dedicated worker loaded from same-origin.
      invoker: invokeFromWorker.bind(undefined, false, {type: 'module'}),
    },
    "worker-module-data": {
      // Module dedicated worker loaded from data: URL.
      invoker: invokeFromWorker.bind(undefined, true, {type: 'module'}),
    },
  };

  return sourceContextMap[sourceContextList[0].sourceContextType].invoker(
      subresource, sourceContextList);
}

// Quick hack to expose invokeRequest when common.sub.js is loaded either
// as a classic or module script.
self.invokeRequest = invokeRequest;

/**
  invokeFrom*() functions are helper functions with the same parameters
  and return values as invokeRequest(), that are tied to specific types
  of top-most environment settings objects.
  For example, invokeFromIframe() is the helper function for the cases where
  sourceContextList[0] is an iframe.
*/

/**
  @param {boolean} isDataUrl
    true if the worker script is loaded from data: URL.
    Otherwise, the script is loaded from same-origin.
  @param {object} workerOptions
    The `options` argument for Worker constructor.

  Other parameters and return values are the same as those of invokeRequest().
*/
function invokeFromWorker(isDataUrl, workerOptions,
                          subresource, sourceContextList) {
  const currentSourceContext = sourceContextList[0];
  let workerUrl =
    "/common/security-features/scope/worker.py?policyDeliveries=" +
    encodeURIComponent(JSON.stringify(
        currentSourceContext.policyDeliveries || []));
  if (workerOptions.type === 'module') {
    workerUrl += "&type=module";
  }

  let promise;
  if (isDataUrl) {
    promise = fetch(workerUrl)
      .then(r => r.text())
      .then(source => {
          return 'data:text/javascript;base64,' + btoa(source);
        });
  } else {
    promise = Promise.resolve(workerUrl);
  }

  return promise
    .then(url => {
      const worker = new Worker(url, workerOptions);
      worker.postMessage({subresource: subresource,
                          sourceContextList: sourceContextList.slice(1)});
      return bindEvents2(worker, "message", worker, "error", window, "error");
    })
    .then(event => {
        if (event.data.error)
          return Promise.reject(event.data.error);
        return event.data;
      });
}

function invokeFromIframe(subresource, sourceContextList) {
  const currentSourceContext = sourceContextList[0];
  const frameUrl =
    "/common/security-features/scope/document.py?policyDeliveries=" +
    encodeURIComponent(JSON.stringify(
        currentSourceContext.policyDeliveries || []));

  let promise;
  if (currentSourceContext.sourceContextType === 'srcdoc') {
    promise = fetch(frameUrl)
      .then(r => r.text())
      .then(srcdoc => {
          return createElement("iframe", {srcdoc: srcdoc}, document.body, true);
        });
  } else if (currentSourceContext.sourceContextType === 'iframe') {
    promise = Promise.resolve(
        createElement("iframe", {src: frameUrl}, document.body, true));
  }

  return promise
    .then(iframe => {
        return iframe.eventPromise
          .then(() => {
              const promise = bindEvents2(
                  window, "message", iframe, "error", window, "error");
              iframe.contentWindow.postMessage(
                  {subresource: subresource,
                   sourceContextList: sourceContextList.slice(1)},
                  "*");
              return promise;
            })
          .then(event => {
              if (event.data.error)
                return Promise.reject(event.data.error);
              return event.data;
            });
      });
}

// SanityChecker does nothing in release mode. See sanity-checker.js for debug
// mode.
function SanityChecker() {}
SanityChecker.prototype.checkScenario = function() {};
SanityChecker.prototype.setFailTimeout = function(test, timeout) {};
SanityChecker.prototype.checkSubresourceResult = function() {};
