Skip to main content

ocular_protocol/
lib.rs

1pub mod resp;
2pub mod mysql;
3pub mod amqp;
4pub mod postgres;
5pub mod mongodb;
6pub mod http;
7pub mod handler;
8pub mod handlers;
9
10pub use resp::{RespValue, parse_resp};
11pub use mysql::{parse_mysql_request, parse_mysql_response};
12pub use amqp::{parse_amqp_request, parse_amqp_response, format_amqp_response_detail, parse_amqp_frame, parse_amqp_request_full, is_async_method, frame_len as amqp_frame_len};
13pub use handler::ProtocolHandler;
14pub use handlers::*;
15
16use std::time::{Duration, SystemTime};
17
18/// A single request→response event (merged)
19#[derive(Debug, Clone)]
20pub struct ProxyEvent {
21    pub timestamp: SystemTime,
22    pub component: String,
23    pub protocol: Protocol,
24    /// The command/SQL sent (request summary, truncated for display)
25    pub command: String,
26    /// Full command extracted from raw request (no truncation)
27    pub full_command: String,
28    /// Response summary (e.g. "OK", "ResultSet (19 rows, ...)")
29    pub response: String,
30    /// Formatted response detail for the detail panel
31    pub response_detail: String,
32    /// Request→response latency
33    pub latency: Duration,
34    /// Process that initiated the connection (PID + name)
35    pub process: Option<String>,
36    /// Client address (source)
37    pub src: Option<String>,
38    /// Remote address (destination)
39    pub dest: Option<String>,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum Direction {
44    Request,
45    Response,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum Protocol {
50    Redis,
51    Mysql,
52    Amqp,
53    Postgres,
54    Mongodb,
55    Http,
56}
57
58impl Protocol {
59    pub fn parse(s: &str) -> Option<Self> {
60        match s.to_lowercase().as_str() {
61            "redis" => Some(Protocol::Redis),
62            "mysql" => Some(Protocol::Mysql),
63            "amqp" | "rabbitmq" => Some(Protocol::Amqp),
64            "postgres" | "postgresql" => Some(Protocol::Postgres),
65            "mongodb" | "mongo" => Some(Protocol::Mongodb),
66            "http" | "elasticsearch" | "es" => Some(Protocol::Http),
67            _ => None,
68        }
69    }
70}
71
72/// Parse request bytes, returning a human-readable summary (truncated)
73pub fn parse_request(protocol: Protocol, buf: &[u8]) -> Option<String> {
74    get_handler(protocol).parse_request(buf)
75}
76
77/// Extract the full command/SQL from raw bytes (no truncation)
78pub fn extract_full_command(protocol: Protocol, buf: &[u8]) -> Option<String> {
79    get_handler(protocol).extract_full_command(buf)
80}
81
82/// Parse response bytes, returning a short summary
83pub fn parse_response(protocol: Protocol, buf: &[u8]) -> Option<String> {
84    get_handler(protocol).parse_response(buf)
85}
86
87/// Parse response bytes into a detailed display string (for detail panel)
88pub fn format_response_detail(protocol: Protocol, buf: &[u8]) -> Option<String> {
89    get_handler(protocol).format_response_detail(buf)
90}
91
92/// Get the protocol handler for a given protocol.
93pub fn get_handler(protocol: Protocol) -> &'static dyn ProtocolHandler {
94    match protocol {
95        Protocol::Redis => &RedisHandler,
96        Protocol::Mysql => &MysqlHandler,
97        Protocol::Amqp => &AmqpHandler,
98        Protocol::Postgres => &PostgresHandler,
99        Protocol::Mongodb => &MongodbHandler,
100        Protocol::Http => &HttpHandler,
101    }
102}