如何修改actix-web中间件中的请求数据? [复制]

2024-05-14

是否有推荐的方法来修改 actix-web 上收到的请求?我正在寻找将数据添加到请求对象并使其可供下游中间件和处理程序处理的方法。

The 中间件文档 https://actix.rs/docs/middleware/ says:

“Actix-web 的中间件系统允许我们为请求/响应处理添加额外的行为。中间件可以挂钩传入的请求流程,使我们能够修改请求以及停止请求处理以尽早返回响应。”

该页面没有有关如何修改请求的示例。

让我们看下面的代码(从上面的文档中获得),以某种方式向请求添加数据的代码是什么?

use std::pin::Pin;
use std::task::{Context, Poll};

use actix_service::{Service, Transform};
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error};
use futures::future::{ok, Ready};
use futures::Future;

// There are two steps in middleware processing.
// 1. Middleware initialization, middleware factory gets called with
//    next service in chain as parameter.
// 2. Middleware's call method gets called with normal request.
pub struct SayHi;

// Middleware factory is `Transform` trait from actix-service crate
// `S` - type of the next service
// `B` - type of response's body
impl<S, B> Transform<S> for SayHi
where
    S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Request = ServiceRequest;
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = SayHiMiddleware<S>;
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ok(SayHiMiddleware { service })
    }
}

pub struct SayHiMiddleware<S> {
    service: S,
}

impl<S, B> Service for SayHiMiddleware<S>
where
    S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Request = ServiceRequest;
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.service.poll_ready(cx)
    }

    fn call(&mut self, req: ServiceRequest) -> Self::Future {
        println!("Hi from start. You requested: {}", req.path());

        let fut = self.service.call(req);

        Box::pin(async move {
            let res = fut.await?;

            println!("Hi from response");
            Ok(res)
        })
    }
}

我也只是在研究如何做到这一点,令人失望的是他们在文档中谈论了它但没有显示任何示例。

我发现您可以按如下方式编辑标题或扩展名,我不知道如何编辑它。

Headers https://docs.rs/actix-web/3.3.2/actix_web/dev/struct.ServiceRequest.html#method.headers_mut

  • 从服务请求中获取标头,let headers = req.headers_mut()
  • 采取标题映射 https://docs.rs/actix-web/3.3.2/actix_web/http/struct.HeaderMap.html您可以从那里插入、删除、清除等
  • 插入示例:headers.insert(HeaderName::from_lowercase(b"content-length").unwrap(), HeaderValue::from_static("hello"));

扩展 https://docs.rs/actix-web/3.3.2/actix_web/struct.HttpRequest.html#method.extensions_mut

  • 获取请求的扩展名let extensions = req.extensions_mut()
  • 添加到扩展程序extensions.insert("foo".to_string());
  • 一班轮:req.extensions_mut().insert("foo".to_string());
  • 稍后获取该扩展名:req.extensions().get::<String>()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何修改actix-web中间件中的请求数据? [复制] 的相关文章

随机推荐