wae-https 0.0.2

WAE HTTPS - HTTP/HTTPS 服务核心模块,构建器模式、中间件、统一响应
Documentation
#![doc = include_str!("readme.md")]
#![warn(missing_docs)]

pub mod error;
pub mod extract;
pub mod middleware;
pub mod response;
pub mod router;
pub mod template;
pub mod tls;

pub use wae_session as session;

pub use router::{RouterBuilder, MethodRouter, get, post, put, delete, patch, options, head, trace};
pub use response::{JsonResponse, Html, Redirect, Attachment, StreamResponse};

use http::{Response, StatusCode, header};
use http_body_util::Full;
use hyper::body::Bytes;
use std::{net::SocketAddr, path::Path, time::Duration};
use tokio::net::TcpListener;
use tracing::info;

pub use wae_types::{WaeError, WaeResult};

/// HTTP 响应体类型
pub type Body = Full<Bytes>;

/// 创建空的 Body
pub fn empty_body() -> Body {
    Full::new(Bytes::new())
}

/// 创建带内容的 Body
pub fn full_body<B: Into<Bytes>>(data: B) -> Body {
    Full::new(data.into())
}

/// HTTPS 操作结果类型
pub type HttpsResult<T> = WaeResult<T>;

/// HTTPS 错误类型
pub type HttpsError = WaeError;

/// 将类型转换为 HTTP 响应的 trait
///
/// 类似于 Axum 的 IntoResponse trait,用于将各种类型转换为 HTTP 响应。
pub trait IntoResponse {
    /// 将自身转换为 HTTP 响应
    fn into_response(self) -> Response<Body>;
}

impl IntoResponse for Response<Body> {
    fn into_response(self) -> Response<Body> {
        self
    }
}

impl IntoResponse for &'static str {
    fn into_response(self) -> Response<Body> {
        Response::builder()
            .status(StatusCode::OK)
            .header(header::CONTENT_TYPE, "text/plain; charset=utf-8")
            .body(full_body(self))
            .unwrap()
    }
}

impl IntoResponse for String {
    fn into_response(self) -> Response<Body> {
        Response::builder()
            .status(StatusCode::OK)
            .header(header::CONTENT_TYPE, "text/plain; charset=utf-8")
            .body(full_body(self))
            .unwrap()
    }
}

impl<T: IntoResponse> IntoResponse for (StatusCode, T) {
    fn into_response(self) -> Response<Body> {
        let mut res = self.1.into_response();
        *res.status_mut() = self.0;
        res
    }
}

/// HTTP 版本配置
///
/// 用于配置服务器支持的 HTTP 协议版本。
#[derive(Debug, Clone, Copy, Default)]
pub enum HttpVersion {
    /// 仅支持 HTTP/1.1
    Http1Only,
    /// 仅支持 HTTP/2
    Http2Only,
    /// 同时支持 HTTP/1.1 和 HTTP/2
    #[default]
    Both,
    /// HTTP/3 QUIC 支持
    Http3,
}

/// HTTP/2 配置
///
/// 用于配置 HTTP/2 协议的各项参数。
#[derive(Debug, Clone)]
pub struct Http2Config {
    /// 是否启用 HTTP/2
    pub enabled: bool,
    /// 是否启用服务器推送
    pub enable_push: bool,
    /// 最大并发流数量
    pub max_concurrent_streams: u32,
    /// 初始流窗口大小
    pub initial_stream_window_size: u32,
    /// 最大帧大小
    pub max_frame_size: u32,
    /// 是否启用 CONNECT 协议扩展
    pub enable_connect_protocol: bool,
    /// 流空闲超时时间
    pub stream_idle_timeout: Duration,
}

impl Default for Http2Config {
    fn default() -> Self {
        Self {
            enabled: true,
            enable_push: false,
            max_concurrent_streams: 256,
            initial_stream_window_size: 65535,
            max_frame_size: 16384,
            enable_connect_protocol: false,
            stream_idle_timeout: Duration::from_secs(60),
        }
    }
}

impl Http2Config {
    /// 创建默认的 HTTP/2 配置
    pub fn new() -> Self {
        Self::default()
    }

    /// 创建禁用 HTTP/2 的配置
    pub fn disabled() -> Self {
        Self { enabled: false, ..Self::default() }
    }

    /// 设置是否启用服务器推送
    pub fn with_enable_push(mut self, enable: bool) -> Self {
        self.enable_push = enable;
        self
    }

    /// 设置最大并发流数量
    pub fn with_max_concurrent_streams(mut self, max: u32) -> Self {
        self.max_concurrent_streams = max;
        self
    }

    /// 设置初始流窗口大小
    pub fn with_initial_stream_window_size(mut self, size: u32) -> Self {
        self.initial_stream_window_size = size;
        self
    }

    /// 设置最大帧大小
    pub fn with_max_frame_size(mut self, size: u32) -> Self {
        self.max_frame_size = size;
        self
    }

    /// 设置是否启用 CONNECT 协议扩展
    pub fn with_enable_connect_protocol(mut self, enable: bool) -> Self {
        self.enable_connect_protocol = enable;
        self
    }

    /// 设置流空闲超时时间
    pub fn with_stream_idle_timeout(mut self, timeout: Duration) -> Self {
        self.stream_idle_timeout = timeout;
        self
    }
}

/// TLS 配置
///
/// 用于配置 TLS 证书和密钥。
#[derive(Debug, Clone)]
pub struct TlsConfig {
    /// 证书文件路径
    pub cert_path: String,
    /// 私钥文件路径
    pub key_path: String,
}

impl TlsConfig {
    /// 创建新的 TLS 配置
    ///
    /// # 参数
    ///
    /// * `cert_path` - 证书文件路径
    /// * `key_path` - 私钥文件路径
    pub fn new(cert_path: impl Into<String>, key_path: impl Into<String>) -> Self {
        Self { cert_path: cert_path.into(), key_path: key_path.into() }
    }
}

/// HTTP/3 QUIC 配置
///
/// 用于配置 HTTP/3 QUIC 协议的设置。
#[derive(Debug, Clone, Default)]
pub struct Http3Config {
    /// 是否启用 HTTP/3 QUIC 支持
    pub enabled: bool,
}

impl Http3Config {
    /// 创建默认的 HTTP/3 配置
    pub fn new() -> Self {
        Self::default()
    }

    /// 创建启用 HTTP/3 的配置
    pub fn enabled() -> Self {
        Self { enabled: true }
    }
}

/// HTTPS 服务器配置
///
/// 用于配置 HTTPS 服务器的各项参数。
#[derive(Debug, Clone)]
pub struct HttpsServerConfig {
    /// 服务器监听地址
    pub addr: SocketAddr,
    /// 服务名称
    pub service_name: String,
    /// HTTP 版本配置
    pub http_version: HttpVersion,
    /// HTTP/2 配置
    pub http2_config: Http2Config,
    /// HTTP/3 配置
    pub http3_config: Http3Config,
    /// TLS 配置
    pub tls_config: Option<TlsConfig>,
}

impl Default for HttpsServerConfig {
    fn default() -> Self {
        Self {
            addr: "0.0.0.0:3000".parse().unwrap(),
            service_name: "wae-https-service".to_string(),
            http_version: HttpVersion::Both,
            http2_config: Http2Config::default(),
            http3_config: Http3Config::default(),
            tls_config: None,
        }
    }
}

/// HTTPS 服务器构建器
///
/// 用于构建和配置 HTTPS 服务器。
pub struct HttpsServerBuilder<S = ()> {
    config: HttpsServerConfig,
    router: router::Router<S>,
    _marker: std::marker::PhantomData<S>,
}

impl HttpsServerBuilder<()> {
    /// 创建新的 HTTPS 服务器构建器
    pub fn new() -> Self {
        Self { config: HttpsServerConfig::default(), router: router::Router::new(), _marker: std::marker::PhantomData }
    }
}

impl Default for HttpsServerBuilder<()> {
    fn default() -> Self {
        Self::new()
    }
}

impl<S> HttpsServerBuilder<S>
where
    S: Clone + Send + Sync + 'static,
{
    /// 设置服务器监听地址
    pub fn addr(mut self, addr: SocketAddr) -> Self {
        self.config.addr = addr;
        self
    }

    /// 设置服务名称
    pub fn service_name(mut self, name: impl Into<String>) -> Self {
        self.config.service_name = name.into();
        self
    }

    /// 设置路由
    pub fn router<T>(mut self, router: T) -> Self
    where
        T: Into<router::Router<S>>,
    {
        self.router = router.into();
        self
    }

    /// 合并路由
    pub fn merge_router(mut self, router: router::Router<S>) -> Self {
        self.router = self.router.merge(router);
        self
    }

    /// 设置 HTTP 版本配置
    pub fn http_version(mut self, version: HttpVersion) -> Self {
        self.config.http_version = version;
        self
    }

    /// 设置 HTTP/2 配置
    pub fn http2_config(mut self, config: Http2Config) -> Self {
        self.config.http2_config = config;
        self
    }

    /// 设置 HTTP/3 配置
    pub fn http3_config(mut self, config: Http3Config) -> Self {
        self.config.http3_config = config;
        self
    }

    /// 设置 TLS 证书和密钥
    ///
    /// # 参数
    ///
    /// * `cert_path` - 证书文件路径
    /// * `key_path` - 私钥文件路径
    pub fn tls(mut self, cert_path: impl Into<String>, key_path: impl Into<String>) -> Self {
        self.config.tls_config = Some(TlsConfig::new(cert_path, key_path));
        self
    }

    /// 设置 TLS 配置
    pub fn tls_config(mut self, config: TlsConfig) -> Self {
        self.config.tls_config = Some(config);
        self
    }

    /// 构建 HTTPS 服务器
    pub fn build(self) -> HttpsServer<S> {
        HttpsServer { config: self.config, router: self.router, _marker: std::marker::PhantomData }
    }
}

/// HTTPS 服务器
///
/// 提供 HTTP/HTTPS 服务的核心类型。
pub struct HttpsServer<S = ()> {
    config: HttpsServerConfig,
    router: router::Router<S>,
    _marker: std::marker::PhantomData<S>,
}

impl<S> HttpsServer<S>
where
    S: Clone + Send + Sync + 'static,
{
    /// 启动服务器
    pub async fn serve(self) -> HttpsResult<()> {
        let addr = self.config.addr;
        let service_name = self.config.service_name.clone();
        let protocol_info = self.get_protocol_info();
        let tls_config = self.config.tls_config.clone();

        let listener =
            TcpListener::bind(addr).await.map_err(|e| WaeError::internal(format!("Failed to bind address: {}", e)))?;

        info!("{} {} server starting on {}", service_name, protocol_info, addr);

        match tls_config {
            Some(tls_config) => self.serve_tls(listener, &tls_config).await,
            None => self.serve_plain(listener).await,
        }
    }

    /// 启动 HTTP 服务器
    async fn serve_plain(self, listener: TcpListener) -> HttpsResult<()> {
        loop {
            let (stream, _addr) = listener
                .accept()
                .await
                .map_err(|e| WaeError::internal(format!("Accept error: {}", e)))?;

            let router = self.router.clone();
            tokio::spawn(async move {
                let service = router::RouterService::new(router);
                let io = hyper_util::rt::tokio::TokioIo::new(stream);
                let _ = hyper_util::server::conn::auto::Builder::new(hyper_util::rt::