1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
//! High-level APIs for an RPC session
//!
//! A "session" is created when a user authenticates on an RPC connection. It
//! is the root for all other RPC capabilities.
use std::sync::Arc;
use tor_rpcbase as rpc;
/// An authenticated RPC session.
pub(crate) struct Session {
/// An inner TorClient object that we use to implement remaining
/// functionality.
#[allow(unused)]
client: Arc<dyn rpc::Object>,
}
impl rpc::Object for Session {}
rpc::decl_object! {Session}
impl Session {
/// Create a new session object.
pub(crate) fn new(client: Arc<dyn rpc::Object>) -> Arc<Self> {
Arc::new(Self { client })
}
}
/// RPC method to release a single strong reference.
#[derive(Debug, serde::Deserialize)]
struct RpcRelease {
/// The object to release. Must be a strong reference.
///
/// TODO RPC: Releasing a weak reference is perilous and hard-to-define
/// based on how we have implemented our object ids. If you tell the objmap
/// to "release" a single name for a weak reference, you are releasing every
/// name for that weak reference, which may have surprising results.
///
/// This might be a sign of a design problem.
obj: rpc::ObjectId,
}
/// RPC method to release a single strong reference, creating a weak reference
/// in its place.
#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct RpcDowngrade {
/// The object to downgrade
obj: rpc::ObjectId,
}
rpc::decl_method! { "rpc:release" => RpcRelease}
impl rpc::Method for RpcRelease {
type Output = rpc::Nil;
type Update = rpc::NoUpdates;
}
/// Implementation for calling "release" on a Session.
async fn rpc_release(
_obj: Arc<Session>,
method: Box<RpcRelease>,
ctx: Box<dyn rpc::Context>,
) -> Result<rpc::Nil, rpc::RpcError> {
ctx.release_owned(&method.obj)?;
Ok(rpc::Nil::default())
}
rpc::rpc_invoke_fn! {
rpc_release(Session,RpcRelease);
}
/// A simple temporary method to echo a reply.
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Echo {
/// A message to echo.
msg: String,
}
rpc::decl_method! { "arti:x-echo" => Echo}
impl rpc::Method for Echo {
type Output = Echo;
type Update = rpc::NoUpdates;
}
/// Implementation for calling "echo" on a Session.
///
/// TODO RPC: Remove this. It shouldn't exist.
async fn echo_on_session(
_obj: Arc<Session>,
method: Box<Echo>,
_ctx: Box<dyn rpc::Context>,
) -> Result<Echo, rpc::RpcError> {
Ok(*method)
}
rpc::rpc_invoke_fn! {
echo_on_session(Session,Echo);
}
|