Skip to main content

helix_driver_host/network/
config.rs

1use std::sync::Arc;
2use std::time::Duration;
3
4use helix_core::PortError;
5use parking_lot::RwLock;
6use reqwest::header::HeaderMap;
7
8use super::network_util::{header_name, header_value};
9
10const DEFAULT_TIMEOUT_SECS: u64 = 30;
11
12/// Platform-provided network initialization material.
13#[derive(Debug, Clone)]
14pub struct HostNetworkConfig {
15    /// Go IM base URL(例如 `/api/cses` 网关)。
16    pub api_base_url: String,
17    /// 前端/平台显式提供的 Java 默认业务网关 base URL;空串表示未注入。
18    ///
19    /// 不允许从 `api_base_url` 裁路径或拼域名推测,两者可以是完全不同的 origin。
20    pub default_api_base_url: String,
21    pub ws_url: String,
22    pub timeout: Duration,
23    pub user_agent: Option<String>,
24}
25
26impl HostNetworkConfig {
27    pub fn new(api_base_url: impl Into<String>, ws_url: impl Into<String>) -> Self {
28        Self {
29            api_base_url: api_base_url.into(),
30            default_api_base_url: String::new(),
31            ws_url: ws_url.into(),
32            timeout: Duration::from_secs(DEFAULT_TIMEOUT_SECS),
33            user_agent: None,
34        }
35    }
36
37    pub fn with_timeout(mut self, timeout: Duration) -> Self {
38        self.timeout = timeout;
39        self
40    }
41
42    pub fn with_user_agent(mut self, user_agent: impl Into<String>) -> Self {
43        self.user_agent = Some(user_agent.into());
44        self
45    }
46
47    /// 显式注入 Java/default business gateway;不会从 Go base 派生。
48    pub fn with_default_api_base_url(mut self, api_base_url: impl Into<String>) -> Self {
49        self.default_api_base_url = api_base_url.into();
50        self
51    }
52}
53
54/// Shared mutable header registry used by HTTP requests and WS handshakes.
55#[derive(Clone, Default)]
56pub struct HostHeaderRegistry {
57    inner: Arc<RwLock<HeaderMap>>,
58}
59
60impl HostHeaderRegistry {
61    pub async fn set_header(&self, name: &str, value: &str) -> Result<(), PortError> {
62        self.set_header_sync(name, value)
63    }
64
65    pub fn set_header_sync(&self, name: &str, value: &str) -> Result<(), PortError> {
66        let name = header_name(name)?;
67        let value = header_value(name.as_str(), value)?;
68        self.inner.write().insert(name, value);
69        Ok(())
70    }
71
72    pub async fn remove_header(&self, name: &str) -> Result<(), PortError> {
73        self.remove_header_sync(name)
74    }
75
76    pub fn remove_header_sync(&self, name: &str) -> Result<(), PortError> {
77        let name = header_name(name)?;
78        self.inner.write().remove(name);
79        Ok(())
80    }
81
82    pub async fn replace_headers<I, K, V>(&self, headers: I) -> Result<(), PortError>
83    where
84        I: IntoIterator<Item = (K, V)>,
85        K: AsRef<str>,
86        V: AsRef<str>,
87    {
88        let mut next = HeaderMap::new();
89        for (name, value) in headers {
90            let name = header_name(name.as_ref())?;
91            let value = header_value(name.as_str(), value.as_ref())?;
92            next.insert(name, value);
93        }
94        *self.inner.write() = next;
95        Ok(())
96    }
97
98    pub async fn snapshot(&self) -> HeaderMap {
99        self.inner.read().clone()
100    }
101}