Skip to main content

ap_proxy_client/
config.rs

1use ap_proxy_protocol::{Identity, IdentityFingerprint, RendezvousCode};
2
3/// Configuration for creating a proxy client.
4///
5/// # Examples
6///
7/// ```
8/// use ap_proxy_client::ProxyClientConfig;
9///
10/// let config = ProxyClientConfig {
11///     proxy_url: "ws://localhost:8080".to_string(),
12/// };
13/// ```
14pub struct ProxyClientConfig {
15    /// WebSocket URL of the proxy server.
16    ///
17    /// Format: `ws://host:port` or `wss://host:port` for TLS.
18    ///
19    /// # Examples
20    /// - `"ws://localhost:8080"` - Local development
21    /// - `"wss://proxy.example.com:443"` - Production with TLS
22    pub proxy_url: String,
23}
24
25/// Messages received by the client from the proxy server.
26///
27/// These messages are delivered via the channel returned by
28/// [`ProxyProtocolClient::connect()`](crate::ProxyProtocolClient::connect).
29///
30/// # Examples
31///
32/// ```no_run
33/// use ap_proxy_client::{ProxyClientConfig, ProxyProtocolClient, IncomingMessage, IdentityKeyPair};
34///
35/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
36/// let config = ProxyClientConfig {
37///     proxy_url: "ws://localhost:8080".to_string(),
38/// };
39/// let mut client = ProxyProtocolClient::new(config);
40/// let mut incoming = client.connect(IdentityKeyPair::generate()).await?;
41///
42/// while let Some(msg) = incoming.recv().await {
43///     match msg {
44///         IncomingMessage::Send { source, payload, .. } => {
45///             println!("Message from {:?}: {} bytes", source, payload.len());
46///         }
47///         IncomingMessage::RendezvousInfo(code) => {
48///             println!("Your rendezvous code: {}", code.as_str());
49///         }
50///         IncomingMessage::IdentityInfo { identity, .. } => {
51///             println!("Found peer: {:?}", identity.fingerprint());
52///         }
53///     }
54/// }
55/// # Ok(())
56/// # }
57/// ```
58#[derive(Debug, Clone)]
59pub enum IncomingMessage {
60    /// Server responded with a rendezvous code.
61    ///
62    /// Received in response to [`ProxyProtocolClient::request_rendezvous()`](crate::ProxyProtocolClient::request_rendezvous).
63    /// The code can be shared with other clients to enable them to discover your identity.
64    ///
65    /// Codes expire after 5 minutes and are single-use.
66    RendezvousInfo(RendezvousCode),
67
68    /// Server responded with a peer's identity.
69    ///
70    /// Received in response to [`ProxyProtocolClient::request_identity()`](crate::ProxyProtocolClient::request_identity).
71    /// Contains the full identity and fingerprint of the peer who created the rendezvous code.
72    ///
73    /// After receiving this, you can send messages to the peer using their fingerprint.
74    IdentityInfo {
75        /// SHA256 fingerprint of the peer's identity
76        fingerprint: IdentityFingerprint,
77        /// The peer's full public identity
78        identity: Identity,
79    },
80
81    /// Received a message from another client.
82    ///
83    /// The `source` is cryptographically verified by the proxy server - it cannot be forged.
84    /// The `payload` should be decrypted or validated by the receiving client, as the proxy
85    /// does not inspect message contents.
86    Send {
87        /// The sender's fingerprint (validated by proxy)
88        source: IdentityFingerprint,
89        /// Your fingerprint (the recipient)
90        destination: IdentityFingerprint,
91        /// Arbitrary message payload (should be encrypted by clients)
92        payload: Vec<u8>,
93    },
94}
95
96/// Internal client connection state
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub(crate) enum ClientState {
99    Disconnected,
100    Connected,
101    Authenticated { fingerprint: IdentityFingerprint },
102}