Skip to main content

moqtap_proxy/
hook.rs

1//! Proxy hook trait for optional frame mutation.
2
3use moqtap_codec::dispatch::{AnyControlMessage, AnyDatagramHeader};
4
5use crate::event::{ProxySide, SessionId};
6
7/// Hook for optionally mutating frames before forwarding.
8///
9/// By default all methods return `None`, meaning the original bytes pass
10/// through unchanged. Return `Some(bytes)` to replace the forwarded frame
11/// with the provided bytes.
12///
13/// Implementations must be `Send + Sync` because the hook is shared across
14/// multiple forwarding tasks.
15pub trait ProxyHook: Send + Sync {
16    /// Whether this hook may rewrite control messages.
17    ///
18    /// Returning `true` switches the proxy's control-stream handling from
19    /// the default forward-first / parse-side-path mode to a slower
20    /// parse-then-forward mode that honors the `Some(bytes)` return value
21    /// of [`Self::on_control_message`]. Defaults to `false` so hooks used
22    /// only for observation do not pay the latency cost.
23    fn wants_control_mutation(&self) -> bool {
24        false
25    }
26
27    /// Called before forwarding a control message.
28    ///
29    /// `raw_bytes` contains the original wire bytes (type + scope +
30    /// payload_length + payload). Return `Some(bytes)` to forward modified
31    /// bytes, or `None` to forward unchanged.
32    ///
33    /// Return values are only honored when [`Self::wants_control_mutation`]
34    /// returns `true`; otherwise this method is invoked purely for
35    /// observation and the return value is discarded.
36    fn on_control_message(
37        &self,
38        _session_id: SessionId,
39        _side: ProxySide,
40        _message: &AnyControlMessage,
41        _raw_bytes: &[u8],
42    ) -> Option<Vec<u8>> {
43        None
44    }
45
46    /// Called before forwarding a datagram.
47    ///
48    /// `raw_bytes` contains the full datagram payload (header + object
49    /// data). Return `Some(bytes)` to forward modified bytes, or `None`
50    /// to forward unchanged.
51    fn on_datagram(
52        &self,
53        _session_id: SessionId,
54        _side: ProxySide,
55        _header: &AnyDatagramHeader,
56        _raw_bytes: &[u8],
57    ) -> Option<Vec<u8>> {
58        None
59    }
60}
61
62/// A no-op hook that passes all frames through unchanged.
63pub struct NoOpHook;
64
65impl ProxyHook for NoOpHook {}