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

青色鲁克

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

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()但是返回多个项目会将其移动到元组,并且我必须更改下游函数签名。理想情况下,我想找到一种添加验证或其他过滤器的方法,这些过滤器可以在没有任何下游值知道它们的情况下拒绝请求。

Shepmaster

通过warp的拒绝示例可以有效地证明这一点

拒绝表示过滤器不应继续处理请求,但其他过滤器可以处理请求的情况。

从“ div-by”标题中提取一个分母,或用DivideByZero拒绝。

你需要

  1. 使用Filter::and_then采取现有的过滤器(在这种情况下query()),并进行验证。如果验证失败,则返回自定义拒绝。
  2. 使用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

货代

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有没有一种方法可以根据字符串是否作为较长字符串的一部分进行过滤?

有没有办法在fortran中读取文件的一部分?

有没有办法隔离字符串的一部分?

有没有办法在MongoDB中返回文档中数组的一部分?

有没有办法在mdraid5设置中仅重建磁盘的一部分?

有没有办法在侧边栏中添加主导航的一部分?

有没有办法只更改 QTextEdit 中的一部分文本?

有没有办法在颤动中仅更改图标颜色的一部分?

有没有一种方法可以对列的一部分进行分组?

有没有办法存储我的存储库的一部分以进行部署并能够进行git pull

有没有办法为所有操作为 CancellationToken 创建过滤器?

有没有办法将 Cells.Address 作为范围(“A1:Cells.Address”)的一部分用于函数的输入?

有没有办法只读取输入文件的一行的一部分?

有没有办法突出显示发生错误的行的一部分

有没有办法在vscode上隐藏我的python代码的一部分?

有没有办法将 javascript 变量用作 PHP SQL 页面的一部分?

有没有办法在c#中注释掉字符串的一部分?

序列化类的一部分时,有没有办法保留XML属性?

有没有办法隐藏从Wagtail管理页面树创建的URL的一部分?

有没有办法在<p>内用<img src>替换一部分文本?

有没有办法使用 jQuery 操作 HTML 复选框的一部分值?

有没有办法只能解析字符串的一部分?

有没有办法使用另一列中的行作为过滤器来填充列中的特定缺失行

有没有办法在 MongoDB 中创建一个具有多个值的过滤器?

有没有办法将变量标签的一部分分配为 R 中的变量名称

有没有办法在C ++正则表达式中重用模式的一部分?

有没有办法在 python 中使用 selenium 来抓取地址栏中的页面 url(或其中的一部分)?

有没有办法从另一个 JS 文件中读取 JS 代码作为 JS 文件的一部分?(该应用程序使用 NodeJS)

有没有办法使用在同一$项目$过滤器和$总和?