无法将 HTTP URL 作为 Rocket 中的查询参数处理
Cannot handle a HTTP URL as a query parameter in Rocket
我正在使用 Rocket 创建一个基本的 Web api 来练习和提高我的 Rust 编程技能。
这里我卡住了。
#[post("/make/<link>")]
fn shorten_link(link: String) -> String {
// Some other code
}
问题是当我 post 让我们说 http://localhost:8000/make/https://youtube.com/
我被重定向到 Rocket 404 页面但是当我做类似 http://localhost:8000/make/hello
的事情时一切正常。我不明白我在这里做错了什么,所以任何帮助将不胜感激,谢谢。
问题是 url https://youtube.com/
中的 /
被误解了。具体来说,它们被解释为路径的新部分。例如,如果我请求 /seg1/seg2/seg3
,我不希望用 #[get("/seg1/<arg>")]
注释的处理程序匹配该路径,因为它的末尾有一个额外的段。同样,https://youtube.com/
中的 /
被解释为新的路径段,因此不会影响您的处理程序。
我想到的第一个解决方案是像这样重写处理程序:
#[post("/make/<link..>")]
fn shorten_link(link: PathBuf) -> String {
let link = link.to_str().unwrap(); // Don't actually unwrap
// Other code
}
我认为这行得通,因为它需要一大堆路径段,并将其变成一个字符串,但这没有用,因为 Rocket 抱怨说你不能用 :
.
所以我只是尝试了 URL-格式化 https://youtube.com/
,它在没有对处理程序进行任何修改的情况下工作。 URL-formatting 是您使用对 HTTP 不安全或具有不同含义的符号(在我们的例子中,/
和 :
),并用特殊符号替换它们没问题的代码。例如,https://youtube.com/
的 URL 编码版本是 https%3A%2F%2Fyoutube.com%2F
。最后一个请求是 POST 请求 /make/https%3A%2F%2Fyoutube.com%2F
:
client.post(format!(
"/make/{}",
urlencoding::encode("https://youtube.com/"),
));
您可以使用 urlencoding
crate 为您编码 URLS。
编辑:
我的完整代码如下所示(这只是一个简单的测试):
#![feature(decl_macro)]
use rocket::{local::Client, post, routes};
#[post("/make/<link>")]
fn shorten_link(link: String) -> String {
link
}
fn main() {
let rocket = rocket::ignite().mount("/", routes![shorten_link]);
let client = Client::new(rocket).expect("valid rocket instance");
let req = client.post(format!(
"/make/{}",
urlencoding::encode("https://youtube.com/"),
));
let mut resp = req.dispatch();
println!("{}", resp.body_string().unwrap());
}
我正在使用 Rocket 创建一个基本的 Web api 来练习和提高我的 Rust 编程技能。
这里我卡住了。
#[post("/make/<link>")]
fn shorten_link(link: String) -> String {
// Some other code
}
问题是当我 post 让我们说 http://localhost:8000/make/https://youtube.com/
我被重定向到 Rocket 404 页面但是当我做类似 http://localhost:8000/make/hello
的事情时一切正常。我不明白我在这里做错了什么,所以任何帮助将不胜感激,谢谢。
问题是 url https://youtube.com/
中的 /
被误解了。具体来说,它们被解释为路径的新部分。例如,如果我请求 /seg1/seg2/seg3
,我不希望用 #[get("/seg1/<arg>")]
注释的处理程序匹配该路径,因为它的末尾有一个额外的段。同样,https://youtube.com/
中的 /
被解释为新的路径段,因此不会影响您的处理程序。
我想到的第一个解决方案是像这样重写处理程序:
#[post("/make/<link..>")]
fn shorten_link(link: PathBuf) -> String {
let link = link.to_str().unwrap(); // Don't actually unwrap
// Other code
}
我认为这行得通,因为它需要一大堆路径段,并将其变成一个字符串,但这没有用,因为 Rocket 抱怨说你不能用 :
.
所以我只是尝试了 URL-格式化 https://youtube.com/
,它在没有对处理程序进行任何修改的情况下工作。 URL-formatting 是您使用对 HTTP 不安全或具有不同含义的符号(在我们的例子中,/
和 :
),并用特殊符号替换它们没问题的代码。例如,https://youtube.com/
的 URL 编码版本是 https%3A%2F%2Fyoutube.com%2F
。最后一个请求是 POST 请求 /make/https%3A%2F%2Fyoutube.com%2F
:
client.post(format!(
"/make/{}",
urlencoding::encode("https://youtube.com/"),
));
您可以使用 urlencoding
crate 为您编码 URLS。
编辑: 我的完整代码如下所示(这只是一个简单的测试):
#![feature(decl_macro)]
use rocket::{local::Client, post, routes};
#[post("/make/<link>")]
fn shorten_link(link: String) -> String {
link
}
fn main() {
let rocket = rocket::ignite().mount("/", routes![shorten_link]);
let client = Client::new(rocket).expect("valid rocket instance");
let req = client.post(format!(
"/make/{}",
urlencoding::encode("https://youtube.com/"),
));
let mut resp = req.dispatch();
println!("{}", resp.body_string().unwrap());
}