Commit 6407d484 authored by Elena's avatar Elena 🤷‍♀️ Committed by Pier Angelo Vendrame
Browse files

fixup! TB 44806: Implement the tor integration in Rust.

TB 44930: Implement the commands on the Rust control port

Add a way to add a handler for when connections are closed.
parent 1c6d5d63
Loading
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -190,10 +190,7 @@ class ControlPortClient {
    } else {
      throw new Error("Unknown server protocol");
    }
    const receiver = {
      onAsyncMessage: message => this.onAsyncMessage(message),
    };
    this.#controlPort.start(receiver);
    this.#controlPort.start(this);
  }

  sendCommand(command) {
@@ -216,4 +213,6 @@ class ControlPortClient {
  onAsyncMessage(_message) {
    Assert.ok(false, "This test does not use async notifications.");
  }

  onClosed() {}
}
+13 −3
Original line number Diff line number Diff line
@@ -67,18 +67,27 @@ add_task(async function test_invalidSyntax() {
class ControlPortClientAsyncNotification extends ControlPortClient {
  notificationPromise;
  #resolve;
  closedPromise;
  #closedResolve;

  constructor(server) {
    super(server);
    const { promise, resolve } = Promise.withResolvers();
    this.notificationPromise = promise;
    this.#resolve = resolve;
    this.notificationPromise = new Promise(
      resolve => (this.#resolve = resolve)
    );
    this.closedPromise = new Promise(
      resolve => (this.#closedResolve = resolve)
    );
  }

  onAsyncMessage(message) {
    Assert.equal(message, "650-Test\r\n650 notification");
    this.#resolve();
  }

  onClosed() {
    this.#closedResolve();
  }
}

add_task(async function test_asyncNotification() {
@@ -91,6 +100,7 @@ add_task(async function test_asyncNotification() {
    await cp.notificationPromise;
    cp.close();
    server.close();
    await cp.closedPromise;
  });
});

+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
[scriptable, uuid(4b250614-968a-412f-9191-9ffd9d4bd001)]
interface torITorControlPortReceiver : nsISupports {
  void onAsyncMessage(in ACString message);
  void onClosed();
};

[scriptable, uuid(1389d157-4695-43a2-a7d8-538aaa350766)]
+24 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@

use bytes::Bytes;
use std::{
    cell::Cell,
    cell::{Cell, RefCell},
    rc::{Rc, Weak},
};

@@ -25,6 +25,7 @@ struct ControlPortInner {
    socket: Rc<dyn ControlSocket>,
    writer: Rc<CommandWriter>,
    message_pump: Rc<MessagePump>,
    close_handler: RefCell<Option<Box<dyn FnOnce()>>>,
    closed: Cell<bool>,
}

@@ -41,6 +42,7 @@ impl ControlPortInner {
                Self::make_data_cb(weak_self.clone()),
                Self::make_async_failure_cb(weak_self.clone()),
            ),
            close_handler: RefCell::new(None),
            closed: Cell::new(false),
        });
        cp.message_pump.start().inspect_err(|_| {
@@ -140,7 +142,22 @@ impl ControlPortInner {
        }
        self.reply_dispatcher.fail_all(ReplyError::ConnectionClosed);
        self.reply_dispatcher.set_async_handler(None);
        self.socket.close()
        let res = self.socket.close();
        let handler = self.close_handler.borrow_mut().take();
        if let Some(h) = handler {
            h();
        }
        res
    }

    fn set_close_handler(&self, cb: Box<dyn FnOnce()>) {
        if self.closed.get() {
            // This should never happen in reality, but let's just call the
            // callback if it does to make sure the callback is always called.
            cb();
            return;
        }
        *self.close_handler.borrow_mut() = Some(cb);
    }
}

@@ -183,4 +200,9 @@ impl ControlPort {
    pub fn close(&self) -> Result<(), ControlSocketError> {
        self.0.close()
    }

    #[inline]
    pub fn set_close_handler(&self, cb: Box<dyn FnOnce()>) {
        self.0.set_close_handler(cb);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ impl ControlPortXpcom {
    xpcom_method!(start => Start(receiver: *const torITorControlPortReceiver));
    pub fn start(&self, receiver: &torITorControlPortReceiver) -> Result<(), nsresult> {
        let receiver = RefPtr::new(receiver);
        let receiver2 = receiver.clone();
        self.control_port
            .set_async_handler(Some(Box::new(move |reply| {
                let mut buf = Vec::new();
@@ -58,6 +59,11 @@ impl ControlPortXpcom {
                // pass nsCStrings created in Rust to C++.
                unsafe { receiver.OnAsyncMessage(&*as_str) };
            })));
        self.control_port.set_close_handler(Box::new(move || {
            // Safety: call to an XPCOM method of our interface that we crafted
            // to make sure it was exposed on Rust bindings.
            unsafe { receiver2.OnClosed() };
        }));
        Ok(())
    }

Loading