Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/toolkit/modules/tests/browser/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 16 kB image not shown  

Quelle  browser_web_channel.js   Sprache: JAVA

 
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */


ChromeUtils.defineESModuleGetters(this, {
  WebChannel: "resource://gre/modules/WebChannel.sys.mjs",
});

const HTTP_PATH = "http://example.com";
const HTTP_ENDPOINT =
  getRootDirectory(gTestPath).replace("chrome://mochitests/content", "") +
  "file_web_channel.html";
const HTTP_MISMATCH_PATH = "http://example.org";
const HTTP_IFRAME_PATH = "http://mochi.test:8888";
const HTTP_REDIRECTED_IFRAME_PATH = "http://example.org";

requestLongerTimeout(2); // timeouts in debug builds.

// Keep this synced with /mobile/android/tests/browser/robocop/testWebChannel.js
// as much as possible.  (We only have that since we can't run browser chrome
// tests on Android.  Yet?)
var gTests = [
  {
    desc: "WebChannel generic message",
    run() {
      return new Promise(function (resolve) {
        let tab;
        let channel = new WebChannel("generic", Services.io.newURI(HTTP_PATH));
        channel.listen(function (id, message) {
          is(id, "generic");
          is(message.something.nested, "hello");
          channel.stopListening();
          gBrowser.removeTab(tab);
          resolve();
        });

        tab = BrowserTestUtils.addTab(
          gBrowser,
          HTTP_PATH + HTTP_ENDPOINT + "?generic"
        );
      });
    },
  },
  {
    desc: "WebChannel generic message in a private window.",
    async run() {
      let promiseTestDone = new Promise(function (resolve) {
        let channel = new WebChannel("generic", Services.io.newURI(HTTP_PATH));
        channel.listen(function (id, message) {
          is(id, "generic");
          is(message.something.nested, "hello");
          channel.stopListening();
          resolve();
        });
      });

      const url = HTTP_PATH + HTTP_ENDPOINT + "?generic";
      let privateWindow = await BrowserTestUtils.openNewBrowserWindow({
        privatetrue,
      });
      await BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, url);
      await promiseTestDone;
      await BrowserTestUtils.closeWindow(privateWindow);
    },
  },
  {
    desc: "WebChannel two way communication",
    run() {
      return new Promise(function (resolve) {
        let tab;
        let channel = new WebChannel("twoway", Services.io.newURI(HTTP_PATH));

        channel.listen(function (id, message, sender) {
          is(id, "twoway""bad id");
          ok(message.command, "command not ok");

          if (message.command === "one") {
            channel.send({ data: { nested: true } }, sender);
          }

          if (message.command === "two") {
            is(message.detail.data.nested, true);
            channel.stopListening();
            gBrowser.removeTab(tab);
            resolve();
          }
        });

        tab = BrowserTestUtils.addTab(
          gBrowser,
          HTTP_PATH + HTTP_ENDPOINT + "?twoway"
        );
      });
    },
  },
  {
    desc: "WebChannel two way communication in an iframe",
    async run() {
      let parentChannel = new WebChannel("echo", Services.io.newURI(HTTP_PATH));
      let iframeChannel = new WebChannel(
        "twoway",
        Services.io.newURI(HTTP_IFRAME_PATH)
      );
      let promiseTestDone = new Promise(function (resolve, reject) {
        parentChannel.listen(function () {
          reject(new Error("WebChannel message incorrectly sent to parent"));
        });

        iframeChannel.listen(function (id, message, sender) {
          is(id, "twoway""bad id (2)");
          ok(message.command, "command not ok (2)");

          if (message.command === "one") {
            iframeChannel.send({ data: { nested: true } }, sender);
          }

          if (message.command === "two") {
            is(message.detail.data.nested, true);
            resolve();
          }
        });
      });
      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?iframe",
        },
        async function () {
          await promiseTestDone;
          parentChannel.stopListening();
          iframeChannel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel response to a redirected iframe",
    async run() {
      /**
       * This test checks that WebChannel responses are only sent
       * to an iframe if the iframe has not redirected to another origin.
       * Test flow:
       * 1. create a page, embed an iframe on origin A.
       * 2. the iframe sends a message `redirecting`, then redirects to
       *    origin B.
       * 3. the iframe at origin B is set up to echo any messages back to the
       *    test parent.
       * 4. the test parent receives the `redirecting` message from origin A.
       *    the test parent creates a new channel with origin B.
       * 5. when origin B is ready, it sends a `loaded` message to the test
       *    parent, letting the test parent know origin B is ready to echo
       *    messages.
       * 5. the test parent tries to send a response to origin A. If the
       *    WebChannel does not perform a valid origin check, the response
       *    will be received by origin B. If the WebChannel does perform
       *    a valid origin check, the response will not be sent.
       * 6. the test parent sends a `done` message to origin B, which origin
       *    B echoes back. If the response to origin A is not echoed but
       *    the message to origin B is, then hooray, the test passes.
       */


      let preRedirectChannel = new WebChannel(
        "pre_redirect",
        Services.io.newURI(HTTP_IFRAME_PATH)
      );
      let postRedirectChannel = new WebChannel(
        "post_redirect",
        Services.io.newURI(HTTP_REDIRECTED_IFRAME_PATH)
      );

      let promiseTestDone = new Promise(function (resolve, reject) {
        preRedirectChannel.listen(function (id, message, preRedirectSender) {
          if (message.command === "redirecting") {
            postRedirectChannel.listen(
              function (aId, aMessage, aPostRedirectSender) {
                is(aId, "post_redirect");
                isnot(aMessage.command, "no_response_expected");

                if (aMessage.command === "loaded") {
                  // The message should not be received on the preRedirectChannel
                  // because the target window has redirected.
                  preRedirectChannel.send(
                    { command: "no_response_expected" },
                    preRedirectSender
                  );
                  postRedirectChannel.send(
                    { command: "done" },
                    aPostRedirectSender
                  );
                } else if (aMessage.command === "done") {
                  resolve();
                } else {
                  reject(new Error(`Unexpected command ${aMessage.command}`));
                }
              }
            );
          } else {
            reject(new Error(`Unexpected command ${message.command}`));
          }
        });
      });

      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?iframe_pre_redirect",
        },
        async function () {
          await promiseTestDone;
          preRedirectChannel.stopListening();
          postRedirectChannel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel multichannel",
    run() {
      return new Promise(function (resolve) {
        let tab;
        let channel = new WebChannel(
          "multichannel",
          Services.io.newURI(HTTP_PATH)
        );

        channel.listen(function (id) {
          is(id, "multichannel");
          gBrowser.removeTab(tab);
          resolve();
        });

        tab = BrowserTestUtils.addTab(
          gBrowser,
          HTTP_PATH + HTTP_ENDPOINT + "?multichannel"
        );
      });
    },
  },
  {
    desc: "WebChannel unsolicited send, using system principal",
    async run() {
      let channel = new WebChannel("echo", Services.io.newURI(HTTP_PATH));

      // an unsolicted message is sent from Chrome->Content which is then
      // echoed back. If the echo is received here, then the content
      // received the message.
      let messagePromise = new Promise(function (resolve) {
        channel.listen(function (id, message) {
          is(id, "echo");
          is(message.command, "unsolicited");

          resolve();
        });
      });

      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?unsolicited",
        },
        async function (targetBrowser) {
          channel.send(
            { command: "unsolicited" },
            {
              browsingContext: targetBrowser.browsingContext,
              principal: Services.scriptSecurityManager.getSystemPrincipal(),
            }
          );
          await messagePromise;
          channel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel unsolicited send, using target origin's principal",
    async run() {
      let targetURI = Services.io.newURI(HTTP_PATH);
      let channel = new WebChannel("echo", targetURI);

      // an unsolicted message is sent from Chrome->Content which is then
      // echoed back. If the echo is received here, then the content
      // received the message.
      let messagePromise = new Promise(function (resolve) {
        channel.listen(function (id, message) {
          is(id, "echo");
          is(message.command, "unsolicited");

          resolve();
        });
      });

      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?unsolicited",
        },
        async function (targetBrowser) {
          channel.send(
            { command: "unsolicited" },
            {
              browsingContext: targetBrowser.browsingContext,
              principal: Services.scriptSecurityManager.createContentPrincipal(
                targetURI,
                {}
              ),
            }
          );

          await messagePromise;
          channel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel unsolicited send with principal mismatch",
    async run() {
      let targetURI = Services.io.newURI(HTTP_PATH);
      let channel = new WebChannel("echo", targetURI);

      // two unsolicited messages are sent from Chrome->Content. The first,
      // `unsolicited_no_response_expected` is sent to the wrong principal
      // and should not be echoed back. The second, `done`, is sent to the
      // correct principal and should be echoed back.
      let messagePromise = new Promise(function (resolve, reject) {
        channel.listen(function (id, message) {
          is(id, "echo");

          if (message.command === "done") {
            resolve();
          } else {
            reject(new Error(`Unexpected command ${message.command}`));
          }
        });
      });

      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?unsolicited",
        },
        async function (targetBrowser) {
          let mismatchURI = Services.io.newURI(HTTP_MISMATCH_PATH);
          let mismatchPrincipal =
            Services.scriptSecurityManager.createContentPrincipal(
              mismatchURI,
              {}
            );

          // send a message to the wrong principal. It should not be delivered
          // to content, and should not be echoed back.
          channel.send(
            { command: "unsolicited_no_response_expected" },
            {
              browsingContext: targetBrowser.browsingContext,
              principal: mismatchPrincipal,
            }
          );

          let targetPrincipal =
            Services.scriptSecurityManager.createContentPrincipal(
              targetURI,
              {}
            );

          // send the `done` message to the correct principal. It
          // should be echoed back.
          channel.send(
            { command: "done" },
            {
              browsingContext: targetBrowser.browsingContext,
              principal: targetPrincipal,
            }
          );

          await messagePromise;
          channel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel non-window target",
    async run() {
      /**
       * This test ensures messages can be received from and responses
       * sent to non-window elements.
       *
       * First wait for the non-window element to send a "start" message.
       * Then send the non-window element a "done" message.
       * The non-window element will echo the "done" message back, if it
       * receives the message.
       * Listen for the response. If received, good to go!
       */

      let channel = new WebChannel(
        "not_a_window",
        Services.io.newURI(HTTP_PATH)
      );

      let testDonePromise = new Promise(function (resolve, reject) {
        channel.listen(function (id, message, sender) {
          if (message.command === "start") {
            channel.send({ command: "done" }, sender);
          } else if (message.command === "done") {
            resolve();
          } else {
            reject(new Error(`Unexpected command ${message.command}`));
          }
        });
      });

      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?bubbles",
        },
        async function () {
          await testDonePromise;
          channel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel disallows non-string messages",
    async run() {
      /**
       * This test ensures that non-string messages can't be sent via WebChannels.
       * We create a page which should send us two messages immediately. The first
       * message has an object for its detail, and the second has a string. We
       * check that we only get the second message.
       */

      let channel = new WebChannel("objects", Services.io.newURI(HTTP_PATH));
      let testDonePromise = new Promise(resolve => {
        channel.listen((id, message) => {
          is(id, "objects");
          is(message.type, "string");
          resolve();
        });
      });
      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?object",
        },
        async function () {
          await testDonePromise;
          channel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel errors handling the message are delivered back to content",
    async run() {
      const ERRNO_UNKNOWN_ERROR = 999; // WebChannel.sys.mjs doesn't export this.

      // The channel where we purposely fail responding to a command.
      let channel = new WebChannel("error", Services.io.newURI(HTTP_PATH));
      // The channel where we see the response when the content sees the error
      let echoChannel = new WebChannel("echo", Services.io.newURI(HTTP_PATH));

      let testDonePromise = new Promise(resolve => {
        // listen for the confirmation that content saw the error.
        echoChannel.listen((id, message) => {
          is(id, "echo");
          is(message.error, "oh no");
          is(message.errno, ERRNO_UNKNOWN_ERROR);
          resolve();
        });

        // listen for a message telling us to simulate an error.
        channel.listen((id, message) => {
          is(id, "error");
          is(message.command, "oops");
          throw new Error("oh no");
        });
      });
      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?error_thrown",
        },
        async function () {
          await testDonePromise;
          channel.stopListening();
          echoChannel.stopListening();
        }
      );
    },
  },
  {
    desc: "WebChannel errors due to an invalid channel are delivered back to content",
    async run() {
      const ERRNO_NO_SUCH_CHANNEL = 2; // WebChannel.sys.mjs doesn't export this.
      // The channel where we see the response when the content sees the error
      let echoChannel = new WebChannel("echo", Services.io.newURI(HTTP_PATH));

      let testDonePromise = new Promise(resolve => {
        // listen for the confirmation that content saw the error.
        echoChannel.listen((id, message) => {
          is(id, "echo");
          is(message.error, "No Such Channel");
          is(message.errno, ERRNO_NO_SUCH_CHANNEL);
          resolve();
        });
      });
      await BrowserTestUtils.withNewTab(
        {
          gBrowser,
          url: HTTP_PATH + HTTP_ENDPOINT + "?error_invalid_channel",
        },
        async function () {
          await testDonePromise;
          echoChannel.stopListening();
        }
      );
    },
  },
]; // gTests

function test() {
  waitForExplicitFinish();

  (async function () {
    await SpecialPowers.pushPrefEnv({
      set: [["dom.security.https_first_pbm"false]],
    });

    for (let testCase of gTests) {
      info("Running: " + testCase.desc);
      await testCase.run();
    }
  })().then(finish, ex => {
    ok(false"Unexpected Exception: " + ex);
    finish();
  });
}

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.34 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.