rust - 火箭.rs : Optional PathBuf has no matching routes

标签 rust rust-rocket

我正在创建一个投资组合网站,一些项目有静态 HTML 演示,我想根据 URL 中的 ID 提供这些演示。路线如下所示:

#[get("/demo/<id>/<pathbuf..>")]
fn site_demo(id: usize, pathbuf: Option<PathBuf>) -> Option<NamedFile> {
    // set path according to id
    let demo = format!{"static/projects/{:03}/demo/", id};
    // if `pathbuf` is not provided, set file to `index.html`
    let pathbuf = pathbuf.unwrap_or(PathBuf::from("index.html"));

    let path = Path::new(&demo).join(pathbuf);
    NamedFile::open(path).ok()
}

当我在浏览器中键入 localhost:5050/demo/003/index.html 时,将加载演示(以及演示文件夹中的所有其他内容)。但是,一旦我只键入 localhost:5050/demo/003/ 我就会收到此错误(末尾没有 / 的结果相同):

GET /demo/003/ text/html:
    => Error: No matching routes for GET /demo/003/ text/html.
    => Warning: Responding with 404 Not Found catcher.
    => Response succeeded.

我希望路由匹配,因为 PathBuf 是可选的并且设置为 index.html。对我来说有意义...

我是哪里出错了还是应该打开一个问题?

最佳答案

多段路径不能为空。

另一种方法是使用 2 条路线:

  • 一个用于多个段 /demo/<id>/<pathbuf..>
  • 一个用于空段/demo/<id>重定向到 /demo/<id>/index.html

使用 rust nightly 和 rocket 0.4 的样本:

#![feature(proc_macro_hygiene, decl_macro)]  
#[macro_use] extern crate rocket;

use std::path::{Path,PathBuf};
use rocket::response::{Redirect,NamedFile};

#[get("/demo/<id>/<pathbuf..>")]
fn site_demo(id: usize, pathbuf: PathBuf) -> Option<NamedFile> {
    let demo = format!{"static/projects/{:03}/demo/", id};
    NamedFile::open(Path::new(&demo).join(pathbuf)).ok()
}

#[get("/demo/<pathbuf..>", rank=2)]
fn redirect(pathbuf: PathBuf) -> Redirect {
    Redirect::to(format!{"/demo/{}/index.html", pathbuf.display()})
}

fn main() {
    rocket::ignite().mount("/", routes![site_demo,redirect]).launch();
}

使用 rust stable 和 rocket 0.5 的样本:

#[macro_use] extern crate rocket;

use std::path::{Path,PathBuf};
use rocket::response::{Redirect,NamedFile};

#[get("/demo/<id>/<pathbuf..>")]
async fn site_demo(id: usize, pathbuf: PathBuf) -> Option<NamedFile> {
    let demo = format!{"static/projects/{:03}/demo/", id};
    NamedFile::open(Path::new(&demo).join(pathbuf)).await.ok()
}

#[get("/demo/<pathbuf..>", rank=2)]
fn redirect(pathbuf: PathBuf) -> Redirect {
    Redirect::to(format!{"/demo/{}/index.html", pathbuf.display()})
}

#[launch]
fn rocket() -> rocket::Rocket {
    rocket::ignite().mount("/", routes![site_demo,redirect])
}

像这样localhost:5050/demo/003/将重定向到 localhost:5050/demo/003/index.html然后 localhost:5050/demo/003/index.html将加载 static/projects/003/demo/index.html

关于rust - 火箭.rs : Optional PathBuf has no matching routes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57437310/

相关文章:

error-handling - 为什么在扩展失败类型的结果时得到 "the method exists but the following trait bounds were not satisfied"?

rust - 最小 future 回调示例中出现 "Expected lifetime parameter"错误?

rust - 我可以使用自己的序列化结构在 Rocket 中渲染模板吗?

rust - 如何从字符串创建响应?(Rust-Rocket)

rust - 火箭有像Flask的蓝图一样的东西吗?

rust - 如何修复 cargo 错误 "failed to find branch ` master`”?

rust - 有没有办法从 `f64::from(0.23_f32)` 得到 0.23_f64?

rust - 写入 BufWriter 的字节实际上并未写入

rust - 使用 Rocket 日志时在此范围内找不到宏 `log`

rust - 可以在没有#[derive(Serialize)] 的情况下在枚举上实现/派生 Serialize 吗?