9 个版本
0.0.9 | 2024 年 2 月 5 日 |
---|---|
0.0.8 | 2023 年 4 月 2 日 |
0.0.6 | 2022 年 11 月 25 日 |
#338 在 HTTP 服务器
45KB
602 行
Hyper 中间件
为 Hyper
0.14.x
提供的紧凑型 HTTP 中间件和处理器系统。
注意: 此软件包仍在积极开发中。
特性
- 受 Iron 框架 启发的紧凑型中间件和处理器系统。
- 简单且方便访问 远程地址 的 Hyper Service。
- 由 anyhow 提供的方便的
Error
和Result
类型。 - 通过 async-trait 支持
Async
。 - 宏,用于简化 HTTP 响应错误或错误转换。
示例
use hyper::{header, Server, StatusCode};
use hyper_middleware::{
async_trait, AfterMiddleware, BeforeMiddleware, Body, Error, Handler, Middlewares, Request,
Response, Result, Service,
};
use std::{net::SocketAddr, path::PathBuf};
struct Config {
pub root: PathBuf,
}
struct Application {
opts: Config,
}
#[async_trait]
impl Handler for Application {
async fn handle(&self, req: &mut Request) -> Result<Response> {
// Access the Hyper incoming Request
println!("Application::handle() - URI Path: {}", req.uri().path());
// Access the custom app options
println!(
"Application::handle() - Config Root: {}",
self.opts.root.display()
);
// Access the Remote Address
let remote_addr = req.extensions().get::<SocketAddr>().unwrap();
println!("Application::handle() - Remote Addr: {}", remote_addr);
// Create a Hyper Response and send it back to the middlewares chain
Ok(Response::new(Body::from("¡Hola!")))
}
}
struct FirstMiddleware {}
#[async_trait]
impl BeforeMiddleware for FirstMiddleware {
async fn before(&self, req: &mut Request) -> Result {
println!("FirstMiddleware::before()");
// Access the Hyper incoming Request
println!("FirstMiddleware::before() - URI Path: {}", req.uri().path());
Ok(())
}
async fn catch(&self, _: &mut Request, err: Error) -> Result {
Err(err)
}
}
struct SecondMiddleware {}
#[async_trait]
impl AfterMiddleware for SecondMiddleware {
async fn after(&self, _: &mut Request, mut res: Response) -> Result<Response> {
println!("SecondMiddleware::after()");
// Mutate the Hyper Response at convenience
// and send it back to other middlewares on the chain
res.headers_mut().insert(
header::CONTENT_TYPE,
"text/html; charset=utf-8".parse().unwrap(),
);
Ok(res)
}
async fn catch(&self, _: &mut Request, err: Error) -> Result<Response> {
Ok(Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from(err.to_string()))
.unwrap())
}
}
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result {
// 0. Define some app options (example only)
let opts = Config {
root: std::env::current_dir().unwrap(),
};
// 1. Create a custom middleware chain and plug in some custom middlewares
let mut middlewares = Middlewares::new(Application { opts });
middlewares.link_before(FirstMiddleware {});
middlewares.link_after(SecondMiddleware {});
// 2. Create a Hyper service and set the current handler with its middlewares
let service = Service::new(middlewares);
// 3. Finally just run server using the service already created
let addr = ([127, 0, 0, 1], 8787).into();
let server = Server::bind(&addr).serve(service);
println!("Listening on http://{}", addr);
server.await?;
Ok(())
}
要运行示例,只需输入
cargo run --example server
贡献
除非您明确表示,否则任何有意提交以包含在您当前工作中的贡献,根据 Apache-2.0 许可证定义,均应按以下方式双重许可,不附加任何额外条款或条件。
请随意发送一些 Pull request 或提交一个 issue。
许可证
本作品主要在 MIT 许可证和 Apache 许可证(版本 2.0)的条款下分发。
© 2022-至今 Jose Quintana
依赖关系
~5–14MB
~162K SLoC