httpbin-rs 0.1.0

使用 Rust 实现 httpbin
# actix-web 中间件

在 actix-web 中,中间件是一个实现了 `Service` 和 `Transform` trait 的结构体,它可以拦截请求和响应,对其进行处理。

actix-web 自提供了一些中间件,如 `日志 Logger`、`用户会话 user sessions`、`压缩 Compress` 等。

## 日志中间件 (Logging)

在项目中使用日志中间件,可以记录请求的信息,如请求方法、路径、响应状态码等。

> Note:需要额外添加对 `env_logger` 的依赖。

```bash
cargo add env_logger
```

示例代码如下:

```rust
use actix_web::middleware::Logger;
use env_logger::Env;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{App, HttpServer};

    env_logger::init_from_env(Env::default().default_filter_or("info"));

    HttpServer::new(|| {
        App::new()
            .wrap(Logger::default())
            .wrap(Logger::new("%a %{User-Agent}i"))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
```

## 默认响应头中间件 (DefaultHeaders)

在项目中使用默认响应头中间件,可以为所有响应添加默认的响应头。

示例代码如下:

```rust
use actix_web::{http::Method, middleware, web, App, HttpResponse, HttpServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2")))
            .service(
                web::resource("/test")
                    .route(web::get().to(HttpResponse::Ok))
                    .route(web::method(Method::HEAD).to(HttpResponse::MethodNotAllowed)),
            )
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
```

## 用户会话中间件 (Session)

在项目中使用用户会话中间件,可以对用户的会话数据进行存储。默认实现了基于 Cookie 的会话存储(存储限制为 4000 字节)。

> Note:需要额外添加对 `actix-session` 的依赖。

```bash
cargo add actix-session --features=cookie-session
```

示例代码如下:

```rust
use actix_session::{Session, SessionMiddleware, storage::CookieSessionStore};
use actix_web::{web, App, Error, HttpResponse, HttpServer, cookie::Key};

async fn index(session: Session) -> Result<HttpResponse, Error> {
    // access session data
    if let Some(count) = session.get::<i32>("counter")? {
        session.insert("counter", count + 1)?;
    } else {
        session.insert("counter", 1)?;
    }

    Ok(HttpResponse::Ok().body(format!(
        "Count is {:?}!",
        session.get::<i32>("counter")?.unwrap()
    )))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(
                // create cookie based session middleware
                SessionMiddleware::builder(CookieSessionStore::default(), Key::from(&[0; 64]))
                    .cookie_secure(false)
                    .build()
            )
            .service(web::resource("/").to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
```

## 错误处理中间件 (ErrorHandlers)

在项目中使用错误处理中间件,可以对请求处理过程中的错误进行处理。

示例代码如下:

```rust
use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};
use actix_web::{
    dev,
    http::{header, StatusCode},
    web, App, HttpResponse, HttpServer, Result,
};

fn add_error_header<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
    res.response_mut().headers_mut().insert(
        header::CONTENT_TYPE,
        header::HeaderValue::from_static("Error"),
    );

    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(
                ErrorHandlers::new()
                    .handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_header),
            )
            .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
```

## 自定义中间件

参考官方文档:[中间件](https://actix.rs/docs/middleware/)