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
use proxyapi_models::{ProxiedRequest, ProxiedResponse, WsFrame};
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicU64, Ordering};
static NEXT_ID: AtomicU64 = AtomicU64::new(1);
/// An event emitted by the proxy for each completed request/response pair.
///
/// Variants are boxed to keep the enum size small.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ProxyEvent {
/// A full request/response round-trip was captured.
RequestComplete {
/// Monotonically increasing event identifier.
id: u64,
/// The captured request.
request: Box<ProxiedRequest>,
/// The captured response.
response: Box<ProxiedResponse>,
},
/// A request is held pending a UI decision (intercept mode).
///
/// The proxy handler is paused until the UI calls
/// [`InterceptConfig::resolve`](crate::intercept::InterceptConfig::resolve).
/// The `id` matches the eventual [`RequestComplete`](Self::RequestComplete)
/// event for the same flow.
RequestIntercepted {
/// Same ID that will appear in the `RequestComplete` event for this flow.
id: u64,
/// Snapshot of the captured request.
request: Box<ProxiedRequest>,
},
/// A non-fatal error occurred during proxying.
Error {
/// Human-readable error description.
message: String,
},
/// A WebSocket upgrade completed (101 Switching Protocols received).
///
/// The `id` is shared with all subsequent [`WebSocketFrame`](Self::WebSocketFrame)
/// and [`WebSocketClosed`](Self::WebSocketClosed) events for this connection.
WebSocketConnected {
id: u64,
request: Box<ProxiedRequest>,
/// The 101 response — contains `Sec-WebSocket-Accept`, negotiated subprotocol, etc.
response: Box<ProxiedResponse>,
},
/// A single WebSocket frame was captured (either direction).
WebSocketFrame {
/// Matches the `id` of the [`WebSocketConnected`](Self::WebSocketConnected) event.
conn_id: u64,
frame: Box<WsFrame>,
},
/// The WebSocket connection closed (either side closed, or an error occurred).
WebSocketClosed { conn_id: u64 },
}
pub(crate) fn next_id() -> u64 {
NEXT_ID.fetch_add(1, Ordering::Relaxed)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_next_id_increments() {
let id1 = next_id();
let id2 = next_id();
assert!(id2 > id1);
}
}