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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! Connection hooks for customizing connection establishment.
//!
//! Connection hooks are attached when establishing connections and allow custom
//! authentication, handshakes, or protocol negotiations. The [`ConnectionHook`] trait
//! is called during connection setup, before the connection is used for messaging.
//!
//! # Built-in Hooks
//!
//! The [`token`] module provides ready-to-use token-based authentication hooks:
//! - [`token::ServerHook`] - Server-side hook that validates client tokens
//! - [`token::ClientHook`] - Client-side hook that sends a token to the server
//!
//! # Custom Hooks
//!
//! Implement [`ConnectionHook`] for custom authentication or protocol negotiation:
//!
//! ```no_run
//! use msg_socket::hooks::{ConnectionHook, Error, HookResult};
//! use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
//!
//! struct MyAuth;
//!
//! #[derive(Debug, thiserror::Error)]
//! enum MyAuthError {
//! #[error("invalid token")]
//! InvalidToken,
//! }
//!
//! impl<Io> ConnectionHook<Io> for MyAuth
//! where
//! Io: AsyncRead + AsyncWrite + Send + Unpin + 'static,
//! {
//! type Error = MyAuthError;
//!
//! async fn on_connection(&self, mut io: Io) -> HookResult<Io, Self::Error> {
//! let mut buf = [0u8; 32];
//! io.read_exact(&mut buf).await?;
//! if &buf == b"expected_token_value_32_bytes!!!" {
//! io.write_all(b"OK").await?;
//! Ok(io)
//! } else {
//! Err(Error::hook(MyAuthError::InvalidToken))
//! }
//! }
//! }
//! ```
//!
//! # Future Extensions
//!
//! TODO: Additional hooks may be added for different parts of the connection lifecycle
//! (e.g., disconnection, reconnection, periodic health checks).
use ;
use ;
/// Error type for connection hooks.
///
/// Distinguishes between I/O errors and hook-specific errors.
/// Result type for connection hooks.
///
/// This is intentionally named `HookResult` (not `Result`) to make it clear this is not
/// `std::result::Result`. A `HookResult` can be:
/// - `Ok(io)` - success, returns the IO stream
/// - `Err(Error::Io(..))` - an I/O error occurred
/// - `Err(Error::Hook(..))` - a hook-specific error occurred
pub type HookResult<T, E> = Result;
/// Type-erased hook result used internally by drivers.
pub type ErasedHookResult<T> = ;
/// Connection hook executed during connection establishment.
///
/// For server sockets: called when a connection is accepted.
/// For client sockets: called after connecting.
///
/// The connection hook receives the raw IO stream and has full control over the handshake protocol.
// ============================================================================
// Type-erased connection hook for internal use
// ============================================================================
/// Type-erased connection hook for internal use.
///
/// This trait allows storing connection hooks with different concrete types behind a single
/// `Arc<dyn ConnectionHookErased<Io>>`. The hook error type is erased to `Box<dyn Error>`.
pub