Request an image and send it over Rocket #2849
-
I havent gotten this to work. My current attempt: #[get("/<bbox>")]
async fn map(state: State<MyState>, bbox: &str) -> Response {
let url = MAP_URL.to_owned() + bbox;
let resp = state.client.get(url).send().await.unwrap();
let bytes = resp.bytes().await.unwrap();
Response::build()
.sized_body(bytes.len(), Cursor::new(bytes))
.header(ContentType::PNG)
.finalize()
} but I get the error: error[E0277]: the trait bound `rocket::Response<'_>: Responder<'_, '_>` is not satisfied
--> src/main.rs:16:52
|
15 | #[get("/<bbox>")]
| ----------------- in this procedural macro expansion
16 | async fn map(state: State<MyState>, bbox: &str) -> Response {
| ^^^^^^^^ the trait `Responder<'_, '_>` is not implemented for `rocket::Response<'_>`
|
= help: the following other types implement trait `Responder<'r, 'o>`:
<&'o [u8] as Responder<'r, 'o>>
<&'o str as Responder<'r, 'o>>
<() as Responder<'r, 'static>>
<(ContentType, R) as Responder<'r, 'o>>
<(Status, R) as Responder<'r, 'o>>
<Accepted<R> as Responder<'r, 'o>>
<Arc<[u8]> as Responder<'r, 'static>>
<Arc<str> as Responder<'r, 'static>>
and 37 others
note: required by a bound in `route::handler::<impl Outcome<rocket::Response<'o>, Status, (rocket::Data<'o>, Status)>>::from`
--> C:\Users\Me\.cargo\registry\src\index.crates.io-6f17d22bba15001f\rocket-0.5.1\src\route\handler.rs:188:20
|
188 | pub fn from<R: Responder<'r, 'o>>(req: &'r Request<'_>, responder: R) -> Outcome<'r> {
| ^^^^^^^^^^^^^^^^^ required by this bound in `route::handler::<impl Outcome<Response<'o>, Status, (Data<'o>, Status)>>::from`
= note: this error originates in the attribute macro `get` (in Nightly builds, run with -Z macro-backtrace for more info)
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
let url = MAP_URL.to_owned() + bbox;
let resp = state.client.get(url).send().await.unwrap(); This is a security vulnerability. You're letting the client make a request to wherever they want. -> Response You cannot return a #[get("/<bbox>")]
async fn map(state: State<MyState>, bbox: PathBuf) -> Option<(ContentType, Vec<u8>)> {
let resp = state.client.get(MAP_URL + bbox).send().ok()?;
let bytes = resp.bytes().await.ok()?; // FIXME: What if the response is too large?
Some((ContentType::PNG, bytes))
} You just need to figure out what Finally, you can encode the image as a type as well with a custom responder: #[derive(Responder)]
#[response(content_type = "png")]
struct Image(Vec<u8>);
#[get("/<bbox>")]
async fn map(state: State<MyState>, bbox: PathBuf) -> Option<Image> {
// ...
Some(Image(bytes))
} |
Beta Was this translation helpful? Give feedback.
This is a security vulnerability. You're letting the client make a request to wherever they want.
-> Response
You cannot return a
Response
because allowing this to happen results in code that isn't reusable and riddled with details that don't matter. Rocket wants to protect you from that. Your entire route can be written correctly, idiomatically, and securely: