use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum TunnelType {
Http,
Tcp,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ClientMessage {
RequestTunnel {
subdomain: Option<String>,
tunnel_type: TunnelType,
local_port: u16,
},
HttpResponse {
stream_id: u64,
status: u16,
headers: Vec<(String, String)>,
body: Vec<u8>,
},
TcpData {
stream_id: u64,
data: Vec<u8>,
},
TcpClose {
stream_id: u64,
},
Ping {
timestamp: u64,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ServerMessage {
TunnelEstablished {
subdomain: String,
url: String,
port: Option<u16>,
},
TunnelDenied {
reason: String,
},
HttpRequest {
stream_id: u64,
method: String,
uri: String,
headers: Vec<(String, String)>,
body: Vec<u8>,
},
TcpConnect {
stream_id: u64,
},
TcpData {
stream_id: u64,
data: Vec<u8>,
},
TcpClose {
stream_id: u64,
},
Pong {
timestamp: u64,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_message_serialization() {
let msg = ClientMessage::RequestTunnel {
subdomain: Some("myapp".to_string()),
tunnel_type: TunnelType::Http,
local_port: 3000,
};
let json = serde_json::to_string(&msg).unwrap();
let parsed: ClientMessage = serde_json::from_str(&json).unwrap();
match parsed {
ClientMessage::RequestTunnel {
subdomain,
tunnel_type,
local_port,
} => {
assert_eq!(subdomain, Some("myapp".to_string()));
assert_eq!(tunnel_type, TunnelType::Http);
assert_eq!(local_port, 3000);
}
_ => panic!("Wrong variant"),
}
}
#[test]
fn test_server_message_serialization() {
let msg = ServerMessage::TunnelEstablished {
subdomain: "myapp".to_string(),
url: "https://myapp.tunnel.example.com".to_string(),
port: None,
};
let json = serde_json::to_string(&msg).unwrap();
let parsed: ServerMessage = serde_json::from_str(&json).unwrap();
match parsed {
ServerMessage::TunnelEstablished {
subdomain,
url,
port,
} => {
assert_eq!(subdomain, "myapp");
assert_eq!(url, "https://myapp.tunnel.example.com");
assert_eq!(port, None);
}
_ => panic!("Wrong variant"),
}
}
}