9 个版本

0.0.9 2024 年 2 月 5 日
0.0.8 2023 年 4 月 2 日
0.0.6 2022 年 11 月 25 日

#338HTTP 服务器

MIT/Apache

45KB
602

Hyper 中间件

hyper-middleware crate Released API docs hyper-middleware crate license

Hyper 0.14.x 提供的紧凑型 HTTP 中间件和处理器系统。
注意: 此软件包仍在积极开发中。

特性

  • Iron 框架 启发的紧凑型中间件和处理器系统。
  • 简单且方便访问 远程地址Hyper Service
  • anyhow 提供的方便的 ErrorResult 类型。
  • 通过 async-trait 支持 Async
  • 宏,用于简化 HTTP 响应错误或错误转换。

示例

examples/server.rs

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