diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-07-06 13:21:42 +0200 |
---|---|---|
committer | Neal H. Walfield <neal@sequoia-pgp.org> | 2024-03-06 11:40:22 +0100 |
commit | 02bf980e2283b64a51ba2e290bf58fda54bbd4a7 (patch) | |
tree | 641f490769f0c751780231acebda3b2aa6609340 | |
parent | 3a55fb2a4b88ad56b7f455176729f84ff15efe14 (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.rs | 32 | ||||
-rw-r--r-- | ipc/src/gnupg.rs | 18 |
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. |