ocular_protocol/handler.rs
1use crate::{Direction, ProxyEvent};
2
3/// Trait that each protocol implements for parsing and display.
4pub trait ProtocolHandler: Send + Sync {
5 /// Parse request bytes → summary for event list
6 fn parse_request(&self, buf: &[u8]) -> Option<String>;
7
8 /// Extract full command from request (for Detail panel, copy, edit)
9 fn extract_full_command(&self, buf: &[u8]) -> Option<String> {
10 self.parse_request(buf)
11 }
12
13 /// Parse response bytes → short summary
14 fn parse_response(&self, buf: &[u8]) -> Option<String>;
15
16 /// Format response detail (for Detail panel)
17 fn format_response_detail(&self, buf: &[u8]) -> Option<String> {
18 self.parse_response(buf)
19 }
20
21 /// Generate a replayable command string (for yank/copy)
22 fn to_replay_command(&self, ev: &ProxyEvent) -> String {
23 ev.full_command.clone()
24 }
25
26 /// Does this protocol need request buffering across reads?
27 fn needs_request_buffering(&self) -> bool { false }
28
29 /// Does this protocol need response buffering across reads?
30 fn needs_response_buffering(&self) -> bool { false }
31
32 /// Is the request buffer complete?
33 fn request_complete(&self, _buf: &[u8]) -> bool { true }
34
35 /// Is the response buffer complete?
36 fn response_complete(&self, _buf: &[u8]) -> bool { true }
37
38 /// Is this a frame-based protocol with custom proxy logic? (AMQP)
39 fn is_frame_based(&self) -> bool { false }
40
41 // ─── Capture mode support ───────────────────────────────────────────────
42
43 /// Length of the first complete message in buf (for discarding unparseable messages).
44 /// The length should include any header bytes (i.e., total bytes to drain).
45 /// Returns None if the protocol doesn't have self-describing message boundaries.
46 fn message_length(&self, _buf: &[u8]) -> Option<usize> { None }
47
48 /// In capture mode, should this packet be skipped? (e.g., connection handshake)
49 /// `handshake_done` is false until this method returns `HandshakeAction::Done`.
50 fn capture_handshake(&self, _payload: &[u8], _direction: Direction) -> HandshakeAction {
51 HandshakeAction::Done
52 }
53
54 /// Default port for this protocol.
55 fn default_port(&self) -> u16 { 0 }
56}
57
58/// Action to take during capture handshake phase.
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum HandshakeAction {
61 /// Handshake is complete (or protocol has no handshake). Process normally.
62 Done,
63 /// Skip this packet (still in handshake phase).
64 Skip,
65 /// Handshake just completed with this packet. Skip it but mark as done.
66 Complete,
67}