tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_dbgsocket.js (4826B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 "use strict";
      4 
      5 /* global structuredClone */
      6 
      7 var gPort;
      8 var gExtraListener;
      9 
     10 function run_test() {
     11  info("Starting test at " + new Date().toTimeString());
     12  initTestDevToolsServer();
     13 
     14  add_task(test_socket_conn);
     15  add_task(test_socket_shutdown);
     16  add_test(test_pipe_conn);
     17 
     18  run_next_test();
     19 }
     20 
     21 const { Actor } = require("resource://devtools/shared/protocol/Actor.js");
     22 class EchoTestActor extends Actor {
     23  constructor(conn) {
     24    super(conn, { typeName: "EchoTestActor", methods: [] });
     25 
     26    this.requestTypes = {
     27      echo: EchoTestActor.prototype.onEcho,
     28    };
     29  }
     30 
     31  onEcho(request) {
     32    /*
     33     * Request packets are frozen. Copy request, so that
     34     * DevToolsServerConnection.onPacket can attach a 'from' property.
     35     */
     36    return structuredClone(request);
     37  }
     38 }
     39 
     40 async function test_socket_conn() {
     41  Assert.equal(DevToolsServer.listeningSockets, 0);
     42  const AuthenticatorType = DevToolsServer.Authenticators.get("PROMPT");
     43  const authenticator = new AuthenticatorType.Server();
     44  authenticator.allowConnection = () => {
     45    return DevToolsServer.AuthenticationResult.ALLOW;
     46  };
     47  const socketOptions = {
     48    authenticator,
     49    portOrPath: -1,
     50  };
     51  const listener = new SocketListener(DevToolsServer, socketOptions);
     52  Assert.ok(listener);
     53  listener.open();
     54  Assert.equal(DevToolsServer.listeningSockets, 1);
     55  gPort = DevToolsServer._listeners[0].port;
     56  info("DevTools server port is " + gPort);
     57  // Open a second, separate listener
     58  gExtraListener = new SocketListener(DevToolsServer, socketOptions);
     59  gExtraListener.open();
     60  Assert.equal(DevToolsServer.listeningSockets, 2);
     61  Assert.ok(!DevToolsServer.hasConnection());
     62 
     63  info("Starting long and unicode tests at " + new Date().toTimeString());
     64  // We can't use EventEmitter.once as this is the second argument we care about...
     65  const onConnectionChange = new Promise(res => {
     66    DevToolsServer.once("connectionchange", (type, conn) => res(conn));
     67  });
     68 
     69  const transport = await DevToolsClient.socketConnect({
     70    host: "127.0.0.1",
     71    port: gPort,
     72  });
     73  Assert.ok(DevToolsServer.hasConnection());
     74  info("Wait for server connection");
     75  const conn = await onConnectionChange;
     76 
     77  // Register a custom actor to do echo requests
     78  const actor = new EchoTestActor(conn);
     79  actor.actorID = "echo-actor";
     80  conn.addActor(actor);
     81 
     82  // Assert that connection settings are available on transport object
     83  const settings = transport.connectionSettings;
     84  Assert.equal(settings.host, "127.0.0.1");
     85  Assert.equal(settings.port, gPort);
     86 
     87  const onDebuggerConnectionClosed = DevToolsServer.once("connectionchange");
     88  const unicodeString = "(╯°□°)╯︵ ┻━┻";
     89  await new Promise(resolve => {
     90    transport.hooks = {
     91      onPacket(packet) {
     92        this.onPacket = function ({ unicode }) {
     93          Assert.equal(unicode, unicodeString);
     94          transport.close();
     95        };
     96        // Verify that things work correctly when bigger than the output
     97        // transport buffers and when transporting unicode...
     98        transport.send({
     99          to: "echo-actor",
    100          type: "echo",
    101          reallylong: really_long(),
    102          unicode: unicodeString,
    103        });
    104        Assert.equal(packet.from, "root");
    105      },
    106      onTransportClosed() {
    107        resolve();
    108      },
    109    };
    110    transport.ready();
    111  });
    112  const type = await onDebuggerConnectionClosed;
    113  Assert.equal(type, "closed");
    114  Assert.ok(!DevToolsServer.hasConnection());
    115 }
    116 
    117 async function test_socket_shutdown() {
    118  Assert.equal(DevToolsServer.listeningSockets, 2);
    119  gExtraListener.close();
    120  Assert.equal(DevToolsServer.listeningSockets, 1);
    121  Assert.ok(DevToolsServer.closeAllSocketListeners());
    122  Assert.equal(DevToolsServer.listeningSockets, 0);
    123  // Make sure closing the listener twice does nothing.
    124  Assert.ok(!DevToolsServer.closeAllSocketListeners());
    125  Assert.equal(DevToolsServer.listeningSockets, 0);
    126 
    127  info("Connecting to a server socket at " + new Date().toTimeString());
    128  try {
    129    await DevToolsClient.socketConnect({
    130      host: "127.0.0.1",
    131      port: gPort,
    132    });
    133  } catch (e) {
    134    if (
    135      e.result == Cr.NS_ERROR_CONNECTION_REFUSED ||
    136      e.result == Cr.NS_ERROR_NET_TIMEOUT
    137    ) {
    138      // The connection should be refused here, but on slow or overloaded
    139      // machines it may just time out.
    140      Assert.ok(true);
    141      return;
    142    }
    143    throw e;
    144  }
    145 
    146  // Shouldn't reach this, should never connect.
    147  Assert.ok(false);
    148 }
    149 
    150 function test_pipe_conn() {
    151  const transport = DevToolsServer.connectPipe();
    152  transport.hooks = {
    153    onPacket(packet) {
    154      Assert.equal(packet.from, "root");
    155      transport.close();
    156    },
    157    onTransportClosed() {
    158      run_next_test();
    159    },
    160  };
    161 
    162  transport.ready();
    163 }