Skip to main content

platform/config/bind/
http.rs

1use serde::{Deserialize, Serialize};
2
3/// HTTP/HTTPS 服务绑定配置
4///
5/// 统一的 HTTP 绑定配置。配置了 `cert` 和 `key` 即启用 TLS (HTTPS),
6/// 否则为纯 HTTP 模式。
7#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
8pub struct HttpBindConfig {
9    /// 域名
10    ///
11    /// 服务绑定的域名,用于生成正确的 URL 和证书验证。
12    pub domain_name: String,
13
14    /// 公网 IP 地址
15    ///
16    /// 服务对外宣告的 IP 地址,客户端将使用此地址连接。
17    /// 在 NAT 环境中,这通常是路由器的公网 IP。
18    pub advertised_ip: String,
19
20    /// 绑定 IP 地址
21    ///
22    /// 服务实际绑定的网络接口 IP 地址。
23    /// 默认使用 "::" 以在支持双栈的系统上同时覆盖 IPv4/IPv6。
24    pub ip: String,
25
26    /// 绑定端口
27    ///
28    /// 服务监听的端口号。
29    pub port: u16,
30
31    /// 公网宣告端口(可选)
32    ///
33    /// 对外宣告的端口号。在 NAT/反向代理环境中可能与绑定端口不同。
34    /// 默认与 `port` 相同。
35    #[serde(default)]
36    pub advertised_port: Option<u16>,
37
38    /// TLS 证书文件路径(可选)
39    ///
40    /// PEM 格式的 TLS 证书文件路径。配置此字段和 `key` 即启用 HTTPS。
41    #[serde(default)]
42    pub cert: Option<String>,
43
44    /// TLS 私钥文件路径(可选)
45    ///
46    /// 与证书对应的 PEM 格式私钥文件路径。
47    #[serde(default)]
48    pub key: Option<String>,
49}
50
51impl HttpBindConfig {
52    /// 是否启用 TLS
53    ///
54    /// 当 `cert` 和 `key` 都配置了非空值时返回 true。
55    pub fn is_tls(&self) -> bool {
56        self.cert.as_ref().is_some_and(|c| !c.is_empty())
57            && self.key.as_ref().is_some_and(|k| !k.is_empty())
58    }
59
60    /// 返回有效的宣告端口
61    ///
62    /// 优先使用 `advertised_port`,未配置则回退到 `port`。
63    pub fn effective_advertised_port(&self) -> u16 {
64        self.advertised_port.unwrap_or(self.port)
65    }
66
67    /// 返回协议方案字符串
68    pub fn scheme(&self) -> &'static str {
69        if self.is_tls() { "https" } else { "http" }
70    }
71
72    /// 返回 WebSocket 协议方案字符串
73    pub fn ws_scheme(&self) -> &'static str {
74        if self.is_tls() { "wss" } else { "ws" }
75    }
76}
77
78impl Default for HttpBindConfig {
79    fn default() -> Self {
80        Self {
81            domain_name: "localhost".to_string(),
82            advertised_ip: "127.0.0.1".to_string(),
83            ip: "::".to_string(),
84            port: 8080,
85            advertised_port: None,
86            cert: None,
87            key: None,
88        }
89    }
90}