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}