warpdrive_proxy/router/
protocol.rs

1//! Protocol definitions for upstream backends
2//!
3//! Defines the supported protocols that WarpDrive can proxy to:
4//! - HTTP: Plain HTTP connections
5//! - HTTPS: TLS-secured HTTP connections
6//! - WebSocket (ws): Plain WebSocket upgrade
7//! - WebSocket Secure (wss): TLS-secured WebSocket
8//! - gRPC: HTTP/2 + application/grpc
9
10use serde::{Deserialize, Serialize};
11
12/// Supported upstream protocols
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
14#[serde(rename_all = "lowercase")]
15pub enum Protocol {
16    /// Plain HTTP
17    #[default]
18    Http,
19    /// TLS-secured HTTP
20    Https,
21    /// Plain WebSocket (Upgrade: websocket)
22    Ws,
23    /// TLS-secured WebSocket
24    Wss,
25    /// gRPC over HTTP/2
26    #[serde(rename = "grpc")]
27    Grpc,
28}
29
30impl Protocol {
31    /// Returns true if this protocol requires TLS
32    pub fn requires_tls(&self) -> bool {
33        matches!(self, Protocol::Https | Protocol::Wss | Protocol::Grpc)
34    }
35
36    /// Returns the default port for this protocol
37    pub fn default_port(&self) -> u16 {
38        match self {
39            Protocol::Http | Protocol::Ws => 80,
40            Protocol::Https | Protocol::Wss => 443,
41            Protocol::Grpc => 9000,
42        }
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_protocol_tls() {
52        assert!(!Protocol::Http.requires_tls());
53        assert!(Protocol::Https.requires_tls());
54        assert!(!Protocol::Ws.requires_tls());
55        assert!(Protocol::Wss.requires_tls());
56        assert!(Protocol::Grpc.requires_tls());
57    }
58
59    #[test]
60    fn test_protocol_default_ports() {
61        assert_eq!(Protocol::Http.default_port(), 80);
62        assert_eq!(Protocol::Https.default_port(), 443);
63        assert_eq!(Protocol::Ws.default_port(), 80);
64        assert_eq!(Protocol::Wss.default_port(), 443);
65        assert_eq!(Protocol::Grpc.default_port(), 9000);
66    }
67
68    #[test]
69    fn test_protocol_deserialization() {
70        use serde::Deserialize;
71
72        #[derive(Deserialize)]
73        struct TestConfig {
74            protocol: Protocol,
75        }
76
77        let http: TestConfig = toml::from_str("protocol = \"http\"").unwrap();
78        assert_eq!(http.protocol, Protocol::Http);
79
80        let grpc: TestConfig = toml::from_str("protocol = \"grpc\"").unwrap();
81        assert_eq!(grpc.protocol, Protocol::Grpc);
82    }
83}