#![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::