Skip to main content

wae_https/
lib.rs

1#![doc = include_str!("readme.md")]
2#![warn(missing_docs)]
3
4pub mod error;
5pub mod extract;
6pub mod middleware;
7pub mod response;
8pub mod router;
9pub mod template;
10pub mod tls;
11
12pub use wae_session as session;
13
14use http::{Response, StatusCode, header};
15use http_body_util::Full;
16use hyper::body::Bytes;
17use std::{net::SocketAddr, path::Path, time::Duration};
18use tokio::net::TcpListener;
19use tracing::info;
20
21pub use wae_types::{WaeError, WaeResult};
22
23/// HTTP 响应体类型
24pub type Body = Full<Bytes>;
25
26/// 创建空的 Body
27pub fn empty_body() -> Body {
28    Full::new(Bytes::new())
29}
30
31/// 创建带内容的 Body
32pub fn full_body<B: Into<Bytes>>(data: B) -> Body {
33    Full::new(data.into())
34}
35
36/// HTTPS 操作结果类型
37pub type HttpsResult<T> = WaeResult<T>;
38
39/// HTTPS 错误类型
40pub type HttpsError = WaeError;
41
42/// 自定义路由类型
43#[derive(Clone, Default)]
44pub struct Router {
45    // 暂时为空,后续实现
46}
47
48impl Router {
49    /// 创建新的空路由
50    pub fn new() -> Self {
51        Self::default()
52    }
53
54    /// 合并另一个路由(暂时实现)
55    pub fn merge(self, _other: Self) -> Self {
56        self
57    }
58
59    /// 嵌套服务(暂时实现)
60    pub fn nest_service<S>(self, _prefix: &str, _service: S) -> Self {
61        self
62    }
63}
64
65/// HTTP 版本配置
66///
67/// 用于配置服务器支持的 HTTP 协议版本。
68#[derive(Debug, Clone, Copy, Default)]
69pub enum HttpVersion {
70    /// 仅支持 HTTP/1.1
71    Http1Only,
72    /// 仅支持 HTTP/2
73    Http2Only,
74    /// 同时支持 HTTP/1.1 和 HTTP/2
75    #[default]
76    Both,
77    /// HTTP/3 QUIC 支持
78    Http3,
79}
80
81/// HTTP/2 配置
82///
83/// 用于配置 HTTP/2 协议的各项参数。
84#[derive(Debug, Clone)]
85pub struct Http2Config {
86    /// 是否启用 HTTP/2
87    pub enabled: bool,
88    /// 是否启用服务器推送
89    pub enable_push: bool,
90    /// 最大并发流数量
91    pub max_concurrent_streams: u32,
92    /// 初始流窗口大小
93    pub initial_stream_window_size: u32,
94    /// 最大帧大小
95    pub max_frame_size: u32,
96    /// 是否启用 CONNECT 协议扩展
97    pub enable_connect_protocol: bool,
98    /// 流空闲超时时间
99    pub stream_idle_timeout: Duration,
100}
101
102impl Default for Http2Config {
103    fn default() -> Self {
104        Self {
105            enabled: true,
106            enable_push: false,
107            max_concurrent_streams: 256,
108            initial_stream_window_size: 65535,
109            max_frame_size: 16384,
110            enable_connect_protocol: false,
111            stream_idle_timeout: Duration::from_secs(60),
112        }
113    }
114}
115
116impl Http2Config {
117    /// 创建默认的 HTTP/2 配置
118    pub fn new() -> Self {
119        Self::default()
120    }
121
122    /// 创建禁用 HTTP/2 的配置
123    pub fn disabled() -> Self {
124        Self { enabled: false, ..Self::default() }
125    }
126
127    /// 设置是否启用服务器推送
128    pub fn with_enable_push(mut self, enable: bool) -> Self {
129        self.enable_push = enable;
130        self
131    }
132
133    /// 设置最大并发流数量
134    pub fn with_max_concurrent_streams(mut self, max: u32) -> Self {
135        self.max_concurrent_streams = max;
136        self
137    }
138
139    /// 设置初始流窗口大小
140    pub fn with_initial_stream_window_size(mut self, size: u32) -> Self {
141        self.initial_stream_window_size = size;
142        self
143    }
144
145    /// 设置最大帧大小
146    pub fn with_max_frame_size(mut self, size: u32) -> Self {
147        self.max_frame_size = size;
148        self
149    }
150
151    /// 设置是否启用 CONNECT 协议扩展
152    pub fn with_enable_connect_protocol(mut self, enable: bool) -> Self {
153        self.enable_connect_protocol = enable;
154        self
155    }
156
157    /// 设置流空闲超时时间
158    pub fn with_stream_idle_timeout(mut self, timeout: Duration) -> Self {
159        self.stream_idle_timeout = timeout;
160        self
161    }
162}
163
164/// TLS 配置
165///
166/// 用于配置 TLS 证书和密钥。
167#[derive(Debug, Clone)]
168pub struct TlsConfig {
169    /// 证书文件路径
170    pub cert_path: String,
171    /// 私钥文件路径
172    pub key_path: String,
173}
174
175impl TlsConfig {
176    /// 创建新的 TLS 配置
177    ///
178    /// # 参数
179    ///
180    /// * `cert_path` - 证书文件路径
181    /// * `key_path` - 私钥文件路径
182    pub fn new(cert_path: impl Into<String>, key_path: impl Into<String>) -> Self {
183        Self { cert_path: cert_path.into(), key_path: key_path.into() }
184    }
185}
186
187/// HTTP/3 QUIC 配置
188///
189/// 用于配置 HTTP/3 QUIC 协议的设置。
190#[derive(Debug, Clone, Default)]
191pub struct Http3Config {
192    /// 是否启用 HTTP/3 QUIC 支持
193    pub enabled: bool,
194}
195
196impl Http3Config {
197    /// 创建默认的 HTTP/3 配置
198    pub fn new() -> Self {
199        Self::default()
200    }
201
202    /// 创建启用 HTTP/3 的配置
203    pub fn enabled() -> Self {
204        Self { enabled: true }
205    }
206}
207
208/// HTTPS 服务器配置
209///
210/// 用于配置 HTTPS 服务器的各项参数。
211#[derive(Debug, Clone)]
212pub struct HttpsServerConfig {
213    /// 服务器监听地址
214    pub addr: SocketAddr,
215    /// 服务名称
216    pub service_name: String,
217    /// HTTP 版本配置
218    pub http_version: HttpVersion,
219    /// HTTP/2 配置
220    pub http2_config: Http2Config,
221    /// HTTP/3 配置
222    pub http3_config: Http3Config,
223    /// TLS 配置
224    pub tls_config: Option<TlsConfig>,
225}
226
227impl Default for HttpsServerConfig {
228    fn default() -> Self {
229        Self {
230            addr: "0.0.0.0:3000".parse().unwrap(),
231            service_name: "wae-https-service".to_string(),
232            http_version: HttpVersion::Both,
233            http2_config: Http2Config::default(),
234            http3_config: Http3Config::default(),
235            tls_config: None,
236        }
237    }
238}
239
240/// HTTPS 服务器构建器
241///
242/// 用于构建和配置 HTTPS 服务器。
243pub struct HttpsServerBuilder {
244    config: HttpsServerConfig,
245    router: Router,
246}
247
248impl HttpsServerBuilder {
249    /// 创建新的 HTTPS 服务器构建器
250    pub fn new() -> Self {
251        Self { config: HttpsServerConfig::default(), router: Router::new() }
252    }
253
254    /// 设置服务器监听地址
255    pub fn addr(mut self, addr: SocketAddr) -> Self {
256        self.config.addr = addr;
257        self
258    }
259
260    /// 设置服务名称
261    pub fn service_name(mut self, name: impl Into<String>) -> Self {
262        self.config.service_name = name.into();
263        self
264    }
265
266    /// 设置路由
267    pub fn router(mut self, router: Router) -> Self {
268        self.router = router;
269        self
270    }
271
272    /// 合并路由
273    pub fn merge_router(mut self, router: Router) -> Self {
274        self.router = self.router.merge(router);
275        self
276    }
277
278    /// 设置 HTTP 版本配置
279    pub fn http_version(mut self, version: HttpVersion) -> Self {
280        self.config.http_version = version;
281        self
282    }
283
284    /// 设置 HTTP/2 配置
285    pub fn http2_config(mut self, config: Http2Config) -> Self {
286        self.config.http2_config = config;
287        self
288    }
289
290    /// 设置 HTTP/3 配置
291    pub fn http3_config(mut self, config: Http3Config) -> Self {
292        self.config.http3_config = config;
293        self
294    }
295
296    /// 设置 TLS 证书和密钥
297    ///
298    /// # 参数
299    ///
300    /// * `cert_path` - 证书文件路径
301    /// * `key_path` - 私钥文件路径
302    pub fn tls(mut self, cert_path: impl Into<String>, key_path: impl Into<String>) -> Self {
303        self.config.tls_config = Some(TlsConfig::new(cert_path, key_path));
304        self
305    }
306
307    /// 设置 TLS 配置
308    pub fn tls_config(mut self, config: TlsConfig) -> Self {
309        self.config.tls_config = Some(config);
310        self
311    }
312
313    /// 构建 HTTPS 服务器
314    pub fn build(self) -> HttpsServer {
315        HttpsServer { config: self.config, router: self.router }
316    }
317}
318
319impl Default for HttpsServerBuilder {
320    fn default() -> Self {
321        Self::new()
322    }
323}
324
325/// HTTPS 服务器
326///
327/// 提供 HTTP/HTTPS 服务的核心类型。
328pub struct HttpsServer {
329    config: HttpsServerConfig,
330    router: Router,
331}
332
333impl HttpsServer {
334    /// 启动服务器
335    pub async fn serve(self) -> HttpsResult<()> {
336        let addr = self.config.addr;
337        let service_name = self.config.service_name.clone();
338        let protocol_info = self.get_protocol_info();
339        let tls_config = self.config.tls_config.clone();
340
341        let listener =
342            TcpListener::bind(addr).await.map_err(|e| WaeError::internal(format!("Failed to bind address: {}", e)))?;
343
344        info!("{} {} server starting on {}", service_name, protocol_info, addr);
345
346        match tls_config {
347            Some(tls_config) => self.serve_tls(listener, &tls_config).await,
348            None => self.serve_plain(listener).await,
349        }
350    }
351
352    async fn serve_plain(self, _listener: TcpListener) -> HttpsResult<()> {
353        // TODO: 使用 hyper::server 实现
354        // 暂时挂起,等待 Router 实现
355        loop {
356            tokio::time::sleep(Duration::from_secs(3600)).await;
357        }
358    }
359
360    async fn serve_tls(self, _listener: TcpListener, _tls_config: &TlsConfig) -> HttpsResult<()> {
361        // TODO: 使用 hyper::server 实现
362        // 暂时挂起,等待 Router 实现
363        loop {
364            tokio::time::sleep(Duration::from_secs(3600)).await;
365        }
366    }
367
368    fn get_protocol_info(&self) -> String {
369        let tls_info = if self.config.tls_config.is_some() { "S" } else { "" };
370        let version_info = match self.config.http_version {
371            HttpVersion::Http1Only => "HTTP/1.1",
372            HttpVersion::Http2Only => "HTTP/2",
373            HttpVersion::Both => "HTTP/1.1+HTTP/2",
374            HttpVersion::Http3 => "HTTP/3",
375        };
376        format!("{}{}", version_info, tls_info)
377    }
378}
379
380/// API 响应结构
381///
382/// 用于标准化 API 响应格式。
383#[derive(Debug, serde::Serialize)]
384pub struct ApiResponse<T> {
385    /// 是否成功
386    pub success: bool,
387    /// 响应数据
388    pub data: Option<T>,
389    /// 错误信息
390    pub error: Option<ApiErrorBody>,
391    /// 追踪 ID
392    pub trace_id: Option<String>,
393}
394
395/// API 错误响应结构
396///
397/// 用于标准化 API 错误响应格式。
398#[derive(Debug, serde::Serialize)]
399pub struct ApiErrorBody {
400    /// 错误代码
401    pub code: String,
402    /// 错误消息
403    pub message: String,
404}
405
406impl<T: serde::Serialize> ApiResponse<T> {
407    /// 将 API 响应转换为 HTTP 响应
408    pub fn into_response(self) -> Response<Body> {
409        let status = if self.success { StatusCode::OK } else { StatusCode::BAD_REQUEST };
410        let body = serde_json::to_string(&self).unwrap_or_default();
411        Response::builder()
412            .status(status)
413            .header(header::CONTENT_TYPE, "application/json")
414            .body(Full::new(Bytes::from(body)))
415            .unwrap()
416    }
417}
418
419/// 创建静态文件服务路由
420///
421/// 用于提供静态资源文件服务。
422///
423/// # 参数
424///
425/// * `path` - 静态文件所在的目录路径
426/// * `prefix` - 路由前缀,例如 "/static"
427pub fn static_files_router(_path: impl AsRef<Path>, _prefix: &str) -> Router {
428    // TODO: 实现静态文件路由
429    Router::new()
430}
431
432impl<T> ApiResponse<T>
433where
434    T: serde::Serialize,
435{
436    /// 创建成功的 API 响应
437    ///
438    /// # 参数
439    ///
440    /// * `data` - 响应数据
441    pub fn success(data: T) -> Self {
442        Self { success: true, data: Some(data), error: None, trace_id: None }
443    }
444
445    /// 创建带追踪 ID 的成功 API 响应
446    ///
447    /// # 参数
448    ///
449    /// * `data` - 响应数据
450    /// * `trace_id` - 追踪 ID
451    pub fn success_with_trace(data: T, trace_id: impl Into<String>) -> Self {
452        Self { success: true, data: Some(data), error: None, trace_id: Some(trace_id.into()) }
453    }
454
455    /// 创建错误的 API 响应
456    ///
457    /// # 参数
458    ///
459    /// * `code` - 错误代码
460    /// * `message` - 错误消息
461    pub fn error(code: impl Into<String>, message: impl Into<String>) -> Self {
462        Self {
463            success: false,
464            data: None,
465            error: Some(ApiErrorBody { code: code.into(), message: message.into() }),
466            trace_id: None,
467        }
468    }
469
470    /// 创建带追踪 ID 的错误 API 响应
471    ///
472    /// # 参数
473    ///
474    /// * `code` - 错误代码
475    /// * `message` - 错误消息
476    /// * `trace_id` - 追踪 ID
477    pub fn error_with_trace(code: impl Into<String>, message: impl Into<String>, trace_id: impl Into<String>) -> Self {
478        Self {
479            success: false,
480            data: None,
481            error: Some(ApiErrorBody { code: code.into(), message: message.into() }),
482            trace_id: Some(trace_id.into()),
483        }
484    }
485}