gpt4 book ai didi

rust - 使用Warp的and_then时未实现 future 特征

转载 作者:行者123 更新时间:2023-12-03 11:31:07 26 4
gpt4 key购买 nike

我正在尝试将HTTPS强制添加到我在GKE上基于Warp的Web应用程序中。

GKE平台基本上无关紧要;最重要的细节是负载平衡器终止了SSL/TLS连接,因此在X-Forwarded-Proto header 中提供了“真实”方案。 Warp解析的文字方案将始终为HTTP

逻辑如下:

  • 如果方案是HTTPS,则正常处理请求。
  • 如果方案为HTTP,则发送301重定向到等效的HTTPS URL。
  • 如果方案不正确,请发送421(错误请求)错误。
  • 如果缺少X-Forwarded-Proto header (或者发生了其他任何现实不可能的情况),则发送400(错误请求)错误。

  • 在此示例中,错误响应没有正文内容,并且所有HTTPS请求均应使用文本 Hello, world!进行响应。

    问题:

    error[E0277]: the trait bound `std::result::Result<(), warp::reject::Rejection>: core::future::future::Future` is not satisfied
    --> src/main.rs:23:10
    |
    23 | .and_then(|scheme_header: Option<String>, host: String, path: FullPath| {
    | ^^^^^^^^ the trait `core::future::future::Future` is not implemented for `std::result::Result<(), warp::reject::Rejection>`
    |
    = note: required because of the requirements on the impl of `futures_core::future::TryFuture` for `std::result::Result<(), warp::reject::Rejection>`

    error[E0599]: no method named `and` found for type `warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure@src/main.rs:23:19: 43:10]>` in the current scope
    --> src/main.rs:44:10
    |
    44 | .and(filter)
    | ^^^ method not found in `warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure@src/main.rs:23:19: 43:10]>`
    |
    = note: the method `and` exists but the following trait bounds were not satisfied:
    `&mut warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure@src/main.rs:23:19: 43:10]> : warp::filter::Filter`
    `&warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure@src/main.rs:23:19: 43:10]> : warp::filter::Filter`
    `warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure@src/main.rs:23:19: 43:10]> : warp::filter::Filter`

    显然,我在这里缺少明显的东西,因此我希望有人可以向正确的方向插入我!

    use futures::{FutureExt, StreamExt};
    use warp::{Filter, Rejection};
    use warp::filters::path::{FullPath};
    use warp::http::{StatusCode, Uri};
    use warp::http::uri::{Parts, Scheme};
    use warp::reply::Reply;

    enum SchemeError {
    InsecureScheme(Uri),
    UnknownScheme,
    MissingScheme,
    }

    impl warp::reject::Reject for SchemeError {}

    async fn requires_https(filter: impl Filter<Extract = (Scheme,), Error = Rejection> + Copy) -> impl Filter<Extract = (), Error = Rejection> + Copy {
    warp::header::optional("X-Forwarded-Proto")
    .and(warp::header("Host"))
    .and(warp::path::full())
    .and_then(|scheme_header: Option<String>, host: String, path: FullPath| {
    if let Some(scheme) = scheme_header {
    match scheme.to_ascii_lowercase().as_str() {
    "https" => Ok(()),
    "http" => {
    let mut uri_parts = Parts::default();
    uri_parts.scheme = Some(Scheme::HTTPS);
    uri_parts.authority = Some(host.parse().unwrap());
    uri_parts.path_and_query = Some(path.as_str().parse().unwrap());
    let uri_parts = uri_parts;

    let new_uri = Uri::from_parts(uri_parts).unwrap();
    println!("Redirecting to secure URL: {}", new_uri);
    Err(warp::reject::custom(SchemeError::InsecureScheme(new_uri)))
    },
    _ => Err(warp::reject::custom(SchemeError::UnknownScheme)),
    }
    } else {
    Err(warp::reject::custom(SchemeError::MissingScheme))
    }
    })
    .and(filter)
    .recover(|err: Rejection| {
    if let Some(scheme_error) = err.find::<SchemeError>() {
    match scheme_error {
    SchemeError::InsecureScheme(new_uri) => Ok(warp::redirect(new_uri)),
    SchemeError::UnknownScheme => Ok(StatusCode::MISDIRECTED_REQUEST),
    SchemeError::MissingScheme => Ok(StatusCode::BAD_REQUEST),
    }
    } else {
    Err(err)
    }
    })
    }

    #[tokio::main]
    async fn main() {
    let routes = requires_https(warp::any().map(|| "Hello, world!"));

    warp::serve(routes)
    .run(([0, 0, 0, 0], 8080))
    .await;
    }

    最佳答案

    我是 rust 新手,但遇到类似的编译器错误

    我的问题是在使用warp 0.2的同时查看warp 0.1文档
    https://docs.rs/warp/0.2.0/warp/trait.Filter.html#example-3

    我需要将async move放在and_then的关闭管道之后

    如果不是那样,可能类似于
    understanding error: trait `futures::future::Future` is not implemented for `()`

    其中std::result::Result<(), warp::reject::Rejection>表示您要返回的单位类型为左结果,将来可能尚未实现。

    关于rust - 使用Warp的and_then时未实现 future 特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60365276/

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