summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-07-06 13:21:42 +0200
committerNeal H. Walfield <neal@sequoia-pgp.org>2024-03-06 11:40:22 +0100
commit02bf980e2283b64a51ba2e290bf58fda54bbd4a7 (patch)
tree641f490769f0c751780231acebda3b2aa6609340
parent3a55fb2a4b88ad56b7f455176729f84ff15efe14 (diff)
ipc: Add callbacks to simplify tracing client-server interactions.
- To simplify debugging client-server interactions, add tracing callbacks to `Assuan`.
-rw-r--r--ipc/src/assuan/mod.rs32
-rw-r--r--ipc/src/gnupg.rs18
2 files changed, 48 insertions, 2 deletions
diff --git a/ipc/src/assuan/mod.rs b/ipc/src/assuan/mod.rs
index 2fd370b4..2ba0ad9e 100644
--- a/ipc/src/assuan/mod.rs
+++ b/ipc/src/assuan/mod.rs
@@ -63,6 +63,8 @@ pub struct Client {
buffer: Vec<u8>,
done: bool,
w: WriteState,
+ trace_send: Option<Box<dyn Fn(&[u8]) + Send + Sync>>,
+ trace_receive: Option<Box<dyn Fn(&[u8]) + Send + Sync>>,
}
assert_send_and_sync!(Client);
@@ -156,6 +158,9 @@ impl Client {
if ! c.ends_with(b"\n") {
c.push(0x0a);
}
+ if let Some(t) = self.trace_send.as_ref() {
+ t(&c);
+ }
WriteState::Sending(Box::pin(async move {
sink.write_all(&c).await?;
Ok(sink)
@@ -261,6 +266,24 @@ impl Client {
write!(&mut request, "\nEND").unwrap();
self.send(request)
}
+
+ /// Start tracing the data that is sent to the server.
+ ///
+ /// Note: if a tracing function is already registered, this
+ /// replaces it.
+ pub fn trace_data_sent(&mut self, fun: Box<dyn Fn(&[u8]) + Send + Sync>)
+ {
+ self.trace_send = Some(fun);
+ }
+
+ /// Start tracing the data that is received from the server.
+ ///
+ /// Note: if a tracing function is already registered, this
+ /// replaces it.
+ pub fn trace_data_received(&mut self, fun: Box<dyn Fn(&[u8]) + Send + Sync>)
+ {
+ self.trace_receive = Some(fun);
+ }
}
/// Returns a convenient Err value for use in the state machines.
@@ -302,7 +325,9 @@ impl ConnectionFuture {
let buffer = Vec::with_capacity(MAX_LINE_LENGTH);
Self(Some(Client {
r: BufReader::new(r), buffer, done: false,
- w: WriteState::Ready(w)
+ w: WriteState::Ready(w),
+ trace_send: None,
+ trace_receive: None,
}))
}
}
@@ -387,7 +412,7 @@ impl Stream for Client {
// The compiler is not smart enough to figure out disjoint borrows
// through Pin via DerefMut (which wholly borrows `self`), so unwrap it
- let Self { buffer, done, r, .. } = Pin::into_inner(self);
+ let Self { buffer, done, r, trace_receive, .. } = Pin::into_inner(self);
let mut reader = Pin::new(r);
loop {
// Try to yield a line from the buffer. For that, try to
@@ -395,6 +420,9 @@ impl Stream for Client {
if let Some(p) = buffer.iter().position(|&b| b == 0x0a) {
let line: Vec<u8> = buffer.drain(..p+1).collect();
// xxx: rtrim linebreak even more? crlf maybe?
+ if let Some(t) = trace_receive {
+ t(&line[..line.len()-1]);
+ }
let r = Response::parse(&line[..line.len()-1])?;
// If this response is one of ok, error, or inquire,
// we want to surrender control to the client next
diff --git a/ipc/src/gnupg.rs b/ipc/src/gnupg.rs
index 629e19e1..3a84c93b 100644
--- a/ipc/src/gnupg.rs
+++ b/ipc/src/gnupg.rs
@@ -503,6 +503,24 @@ impl Agent {
r.reverse();
r
}
+
+ /// Start tracing the data that is sent to the server.
+ ///
+ /// Note: if a tracing function is already registered, this
+ /// replaces it.
+ pub fn trace_data_sent(&mut self, fun: Box<dyn Fn(&[u8]) + Send + Sync>)
+ {
+ self.c.trace_data_sent(fun);
+ }
+
+ /// Start tracing the data that is received from the server.
+ ///
+ /// Note: if a tracing function is already registered, this
+ /// replaces it.
+ pub fn trace_data_received(&mut self, fun: Box<dyn Fn(&[u8]) + Send + Sync>)
+ {
+ self.c.trace_data_received(fun);
+ }
}
/// A cryptographic key pair.