3 个版本 (重大更新)
0.4.0 | 2024年3月25日 |
---|---|
0.3.0 | 2023年10月10日 |
0.2.2 | 2023年10月9日 |
168 在 HTTP 服务器 中
每月下载 22 次
580KB
1.5K SLoC
狐狸洞是一个简单、快速、同步的框架,旨在帮助您完成项目。
有偏见的决策
- 无异步。二进制膨胀和差的用户体验
- 最小化依赖
功能
- 闪电般的性能 (~600k req/sec 在 ryzen 7 5700x 上使用
wrk
) 可能已过时。 - 内置的线程系统,允许您高效地处理请求。
- 最小构建大小,剥离后约为 ~500kb。
- 使用
http
,您可能已经熟悉的模型库。 - 魔法函数处理程序!请参阅 入门指南。
- 独特的强大路由系统
- 几乎完全支持 Http1.1
- 正在开发中的 Https 支持。在“功能”下可用,大部分未测试!
- 即将到来的 Http2 支持。
入门指南
狐狸洞使用一组处理程序系统和路由模块来处理请求和响应。
以下是一个 Hello World 服务器的入门示例。
use foxhole::{action::Html, connection::Http1, resolve::Get, App, sys, Scope};
fn get(_get: Get) -> Html {
Html(String::from("<h1> Foxhole! </h1>"))
}
fn main() {
let scope = Scope::new(sys![get]);
println!("Running on '127.0.0.1:8080'");
#[cfg(test)]
App::builder(scope)
.run::<Http1>("127.0.0.1:8080");
}
让我们将其分解为其组件。
路由
作用域树将按照其部分逐步遍历 URL,首先从根开始。它将尝试按顺序运行它经过的每个节点的所有系统。一旦收到响应,它将停止遍历 URL 并立即响应。
假设我们有树 Scope::new(sys![auth]).route("page", sys![get_page])
和请求 /page
在这个例子中,路由器首先会在树的根处调用auth
。如果auth
返回响应,比如用户未被授权并且我们希望尽早响应,那么我们就在这里停止并响应401
。否则,我们将继续到下一个节点get_page
如果到树的末尾都没有返回响应,服务器将自动返回404
。这将在未来可配置。
参数/守卫
函数参数可以在foxhole
中作为获取器和守卫。
在上面的例子中,Get
作为守卫确保系统只在GET
请求上运行。
任何实现了Resolve
特质的类型都可以用作参数。
foxhole
将尝试提供最常用的守卫和获取器,但目前实现得很少。
示例
use foxhole::{http::Method, PathIter, RequestState, resolve::{Resolve, ResolveGuard}};
pub struct Get;
impl<'a> Resolve<'a> for Get {
type Output = Self;
fn resolve(ctx: &'a RequestState, _path_iter: &mut PathIter) -> ResolveGuard<Self::Output> {
if ctx.request.method() == Method::GET {
ResolveGuard::Value(Get)
} else {
ResolveGuard::None
}
}
}
返回类型
系统必须返回一个实现Action
的值。
另外请注意存在IntoResponse
,它可以替代实现,用于总是返回响应的类型。
如果一个类型从Action
返回None
,则不会发送响应,并且路由将继续到更远的节点。这可能会成为对WebSocket支持的扩展枚举。
示例
use foxhole::{http::Version, IntoResponse, Response};
pub struct Html(pub String);
impl IntoResponse for Html {
fn response(self) -> Response {
let bytes = self.0.into_bytes();
http::Response::builder()
.version(Version::HTTP_11)
.status(200)
.header("Content-Type", "text/html; charset=utf-8")
.header("Content-Length", format!("{}", bytes.len()))
.body(bytes)
.unwrap()
}
}
贡献
如果您对功能或改进有建议,请随时提交问题或拉取请求!
许可证
MIT许可证(LICENSE或https://opensource.org/licenses/MIT)
依赖项
~8–15MB
~275K SLoC