gpt4 book ai didi

rust - 有没有办法在 Warp 中作为过滤器的一部分进行验证?

转载 作者:行者123 更新时间:2023-12-03 11:24:19 29 4
gpt4 key购买 nike

我定义了一个路由和一个端点函数。我还注入(inject)了一些依赖项。

pub fn route1() -> BoxedFilter<(String, ParamType)> {
warp::get()
.and(warp::path::param())
.and(warp::filters::query::query())
.and(warp::path::end())
.boxed()
}

pub async fn handler1(
query: String,
param: ParamType,
dependency: DependencyType,
) -> Result<impl warp::Reply, warp::Rejection> {
}

let api = api::routes::route1()
.and(warp::any().map(move || dependency))
.and_then(api::hanlders::hander1);

这一切似乎都很好。

但是,我希望能够在几个端点前面有一些东西来检查查询参数中的有效键。内部 handler1我可以补充:

if !param.key_valid {
return Ok(warp::reply::with_status(
warp::reply::json(&""),
StatusCode::BAD_REQUEST,
));
}

我不想将它单独添加到每个处理程序中。

看来我应该可以通过 filter ,但我无法弄清楚。我试过使用 .map()但随后返回多个项目将其转换为一个元组,我必须更改我的下游函数签名。理想情况下,我想找到一种方法来添加验证或其他过滤器,这些过滤器可以在没有任何下游值知道它们的情况下拒绝请求。

最佳答案

warp 的 rejection example 有效地证明了这一点。 :

Rejections represent cases where a filter should not continue processing the request, but a different filter could process it.



Extract a denominator from a "div-by" header, or reject with DivideByZero.



你需要
  • 使用 Filter::and_then 采用现有过滤器(在本例中为 query())并执行验证。如果验证失败,则返回自定义拒绝。
  • 使用 Filter::recover 以适本地处理自定义拒绝和任何其他可能的错误。

  • 适用于您的情况:
    use serde::Deserialize;
    use std::{convert::Infallible, net::IpAddr};
    use warp::{filters::BoxedFilter, http::StatusCode, reject::Reject, Filter, Rejection, Reply};

    fn route1() -> BoxedFilter<(String, ParamType)> {
    warp::get()
    .and(warp::path::param())
    .and(validated_query())
    .and(warp::path::end())
    .boxed()
    }

    #[derive(Debug)]
    struct Invalid;
    impl Reject for Invalid {}

    fn validated_query() -> impl Filter<Extract = (ParamType,), Error = Rejection> + Copy {
    warp::filters::query::query().and_then(|param: ParamType| async move {
    if param.valid {
    Ok(param)
    } else {
    Err(warp::reject::custom(Invalid))
    }
    })
    }

    async fn report_invalid(r: Rejection) -> Result<impl Reply, Infallible> {
    let reply = warp::reply::reply();

    if let Some(Invalid) = r.find() {
    Ok(warp::reply::with_status(reply, StatusCode::BAD_REQUEST))
    } else {
    // Do better error handling here
    Ok(warp::reply::with_status(
    reply,
    StatusCode::INTERNAL_SERVER_ERROR,
    ))
    }
    }

    async fn handler1(
    _query: String,
    _param: ParamType,
    _dependency: DependencyType,
    ) -> Result<impl warp::Reply, warp::Rejection> {
    Ok(warp::reply::reply())
    }

    struct DependencyType;

    #[derive(Deserialize)]
    struct ParamType {
    valid: bool,
    }

    #[tokio::main]
    async fn main() {
    let api = route1()
    .and(warp::any().map(move || DependencyType))
    .and_then(handler1)
    .recover(report_invalid);

    let ip: IpAddr = "127.0.0.1".parse().unwrap();
    let port = 8888;
    warp::serve(api).run((ip, port)).await;
    }

    并删除了不相关行的 curl 输出:

    % curl -v '127.0.0.1:8888/dummy/?valid=false'
    < HTTP/1.1 400 Bad Request

    % curl -v '127.0.0.1:8888/dummy/?valid=true'
    < HTTP/1.1 200 OK

    cargo .toml
    [dependencies]
    warp = "0.2.2"
    serde = { version = "1.0.104", features = ["derive"] }
    tokio = { version = "0.2.13", features = ["full"] }

    关于rust - 有没有办法在 Warp 中作为过滤器的一部分进行验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60554783/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com